diff --git a/.cursor/rules/backend_development.mdc b/.cursor/rules/backend_development.mdc deleted file mode 100644 index 3ed0261f95..0000000000 --- a/.cursor/rules/backend_development.mdc +++ /dev/null @@ -1,268 +0,0 @@ ---- -description: "Guidelines for backend development in Langflow, focusing on Python components, FastAPI services, and backend testing." -globs: - - "src/backend/**/*.py" - - "tests/**/*.py" - - "Makefile" - - "pyproject.toml" - - "uv.lock" -alwaysApply: false ---- - - -# Backend Development Guidelines - -## Purpose -Guidelines for backend development in Langflow, focusing on Python components, FastAPI services, and backend testing. - ---- - -## 1. Backend Environment Setup - -### Prerequisites -- **Python Package Manager:** `uv` (>=0.4) for dependency management -- **Database:** SQLite for development, PostgreSQL for production -- **Development Tools:** `make` for build coordination - -### Backend Service -```bash -make backend # Start FastAPI backend on port 7860 -``` -- Auto-reloads on file changes -- Health check: http://localhost:7860/health -- Backend components: `src/backend/base/langflow/` - ---- - -## 2. Component Development - -### Component Structure -``` -src/backend/base/langflow/components/ -├── agents/ # Agent components -├── data/ # Data processing components -├── embeddings/ # Embedding components -├── input_output/ # Input/output components -├── models/ # Language model components -├── processing/ # Text processing components -├── prompts/ # Prompt components -├── tools/ # Tool components -└── vectorstores/ # Vector store components -``` - -### Adding New Components -1. **Location:** Add to appropriate subdirectory under `src/backend/base/langflow/components/` -2. **Import:** Update `__init__.py` with alphabetical imports: - ```python - from .my_component import MyComponent - - __all__ = [ - "ExistingComponent", - "MyComponent", # Add alphabetically - ] - ``` -3. **Auto-restart:** Backend auto-restarts on save -4. **Browser refresh:** Refresh browser to see component changes - -### Component Testing -- **Unit Tests:** `src/backend/tests/unit/components/` -- **Test Structure:** Mirror component directory structure -- **Test Base Classes:** Use `ComponentTestBaseWithClient` or `ComponentTestBaseWithoutClient` -- **Version Testing:** Provide `file_names_mapping` for backward compatibility - -### Development Tips -- **Fast iteration:** Edit component in UI first, then save to source -- **Component updates:** Old components show "Updates Available" after backend restart -- **Testing:** Create comprehensive unit tests for all new components - ---- - -## 3. Backend Code Quality - -### Formatting (CRITICAL) -```bash -make format_backend # Format Python code -``` -**Important:** Run `make format_backend` _early and often_ (ideally before running linting or committing changes). It auto-corrects the majority of style issues, preventing lengthy manual fixes when lint errors surface later. - -### Linting -```bash -make lint # Run linting checks -``` - -### Testing -```bash -make unit_tests # Run backend unit tests -``` - -### Pre-commit Workflow -1. **Run `make format_backend`** (FIRST - saves time on lint fixes) -2. Run `make lint` -3. Run `make unit_tests` -4. Commit changes - ---- - -## 4. FastAPI Development - -### API Structure -``` -src/backend/base/langflow/api/ -├── v1/ # API version 1 -│ ├── chat.py # Chat endpoints -│ ├── flows.py # Flow management -│ ├── users.py # User management -│ └── ... -└── v2/ # API version 2 (future) -``` - -### Testing APIs -- Use `client` fixture from `conftest.py` -- Test with `logged_in_headers` for authenticated endpoints -- Example: - ```python - async def test_flows_endpoint(client, logged_in_headers): - response = await client.post( - "api/v1/flows/", - json=flow_data, - headers=logged_in_headers - ) - assert response.status_code == 201 - ``` - ---- - -## 5. Database Development - -### Models Location -``` -src/backend/base/langflow/services/database/models/ -├── api_key/ # API key models -├── flow/ # Flow models -├── folder/ # Folder models -├── user/ # User models -└── ... -``` - -### Database Testing -- Use in-memory SQLite for tests -- Database tests may fail in batch runs - run individually if needed: - ```bash - uv run pytest src/backend/tests/unit/test_database.py - ``` - ---- - -## 6. Async Development Patterns - -### Component Async Methods -```python -async def run(self) -> MessageType: - """Main component execution method.""" - # Use await for async operations - result = await self.async_operation() - return result - -async def message_response(self) -> Message: - """Return a Message object for chat components.""" - return Message( - text=self.input_value, - sender=self.sender, - session_id=self.session_id, - ) -``` - -### Background Tasks -```python -import asyncio - -async def process_in_background(self): - """Process items without blocking.""" - # Use asyncio.create_task for background work - task = asyncio.create_task(self.heavy_operation()) - - # Ensure proper cleanup - try: - result = await task - return result - except asyncio.CancelledError: - # Handle cancellation gracefully - await self.cleanup() - raise -``` - -### Queue Operations -```python -async def queue_processing(self): - """Non-blocking queue operations.""" - queue = asyncio.Queue() - - # Non-blocking put - queue.put_nowait(data) - - # Timeout-controlled get - try: - result = await asyncio.wait_for(queue.get(), timeout=5.0) - return result - except asyncio.TimeoutError: - # Handle timeout appropriately - raise ComponentError("Processing timeout") -``` - ---- - -## 7. Component Integration Testing - -### Flow Testing -```python -from tests.unit.build_utils import create_flow, build_flow, get_build_events - -async def test_component_in_flow(client, json_flow, logged_in_headers): - """Test component within a complete flow.""" - flow_id = await create_flow(client, json_flow, logged_in_headers) - build_response = await build_flow(client, flow_id, logged_in_headers) - - # Validate flow execution - job_id = build_response["job_id"] - events_response = await get_build_events(client, job_id, logged_in_headers) - assert events_response.status_code == 200 -``` - -### External API Testing -```python -@pytest.mark.api_key_required -@pytest.mark.no_blockbuster -async def test_with_real_api(self): - """Test component with external service.""" - api_key = os.getenv("OPENAI_API_KEY") - component = MyComponent(api_key=api_key, model="gpt-4o") - - response = await component.run() - assert response is not None -``` - ---- - -## 8. Known Backend Issues - -### Testing Quirks -- `test_database.py` may fail in batch runs but pass individually -- Use `@pytest.mark.no_blockbuster` to skip blockbuster plugin when needed -- Context variables may not propagate correctly in `asyncio.to_thread` - test both patterns - -### File Changes -- Starter project files auto-format after `langflow run` -- These formatting changes can be committed or ignored - ---- - -## Backend Development Checklist -- [ ] Component added to appropriate subdirectory -- [ ] `__init__.py` updated with alphabetical imports -- [ ] Code formatted with `make format_backend` (FIRST) -- [ ] Linting passed with `make lint` -- [ ] Unit tests created and passing with `make unit_tests` -- [ ] Component tested in UI with backend restart + browser refresh -- [ ] Version mapping provided for backward compatibility -- [ ] Async patterns implemented correctly with proper cleanup -- [ ] External API calls use appropriate pytest markers diff --git a/.cursor/rules/components/basic_component.mdc b/.cursor/rules/components/basic_component.mdc deleted file mode 100644 index f2cb445de1..0000000000 --- a/.cursor/rules/components/basic_component.mdc +++ /dev/null @@ -1,82 +0,0 @@ ---- -description: "Guide for creating a basic Langflow component, including requirements gathering, component structure, and implementation best practices." -globs: - - "src/backend/**/components/**/*.py" - - "src/backend/base/langflow/components/**/*.py" -alwaysApply: false ---- - - -# Rule: How to Create a Basic Langflow Component - -## Purpose -Guide for Creating a Langflow Component - ---- - -### 1. Gather Requirements - -Ask the user for: -- **Component Name:** What should the component be called? -- **Description:** What does the component do? -- **Inputs:** What are the required inputs? (e.g., text, dropdown, boolean, etc.) -- **Outputs:** What should the component output? (e.g., a message, a value, etc.) -- **Category:** Which component category should this component be stored under in `langflow/src/backend/base/langflow/components` - -### 2. Define the Component - -- Inherit from `Component`. -- Set `display_name`, `description`, `icon`. -- Define the `inputs` and `outputs` as lists of input/output field objects (e.g., `DropdownInput`, `MessageTextInput`, `Output`). -- Implement the main logic as a method (e.g., `get_current_date`, `true_response`, etc.). - -### 3. Example: Conditional If-Else Component - -```python -class ConditionalRouterComponent(Component): - display_name = "If-Else" - description = "Routes an input message to a corresponding output based on text comparison." - icon = "split" - name = "ConditionalRouter" - inputs = [ - # Define your inputs here - ] - outputs = [ - # Define your outputs here - ] - # Implement your logic methods here -``` - -### 4. Example: Current Date Component - -```python -class CurrentDateComponent(Component): - display_name = "Current Date" - description = "Returns the current date and time in the selected timezone." - icon = "clock" - name = "CurrentDate" - inputs = [ - # Define your inputs here - ] - outputs = [ - # Define your outputs here - ] - # Implement your logic methods here -``` - -### 5. Best Practices - -- Use clear and descriptive names for inputs and outputs. -- Provide helpful `info` for each input to guide users. -- Handle errors gracefully and provide meaningful error messages. -- Use appropriate icons to visually represent the component's function. -- Use a Lucide icon or if you want a custom icon follow the icon rules (`./cursor/rules/icons.mdc`) - ---- - -## Checklist for Creating a Component -- [ ] Ask the user for component name, description, inputs, and outputs. -- [ ] Define the component class with the required fields. -- [ ] Implement the main logic. -- [ ] Add helpful info and error handling. -- [ ] Test the component. diff --git a/.cursor/rules/frontend_development.mdc b/.cursor/rules/frontend_development.mdc deleted file mode 100644 index 42b3dac7e7..0000000000 --- a/.cursor/rules/frontend_development.mdc +++ /dev/null @@ -1,374 +0,0 @@ ---- -description: "Guidelines for frontend development in Langflow, focusing on React/TypeScript UI components, build processes, and frontend testing." -globs: - - "src/frontend/**/*.{ts,tsx,js,jsx}" - - "src/frontend/**/*.{css,scss,json}" - - "src/frontend/package*.json" - - "src/frontend/vite.config.*" - - "src/frontend/tailwind.config.*" - - "src/frontend/tsconfig.json" -alwaysApply: false ---- - -## 1. Frontend Environment Setup - -### Prerequisites -- **Node.js:** v22.12 LTS for JavaScript runtime -- **Package Manager:** npm (v10.9) for dependency management -- **Development Tools:** Vite for build tooling - -### Frontend Service -```bash -make frontend # Start Vite dev server on port 3000 -``` -- Hot-reload enabled for UI changes -- Access at: http://localhost:3000/ -- Frontend source: `src/frontend/` - ---- - -## 2. Frontend Structure - -### Directory Layout -``` -src/frontend/src/ -├── components/ # Reusable UI components -├── pages/ # Page-level components -├── icons/ # Component icons and lazy loading -├── stores/ # State management (Zustand) -├── types/ # TypeScript type definitions -├── utils/ # Utility functions -├── hooks/ # Custom React hooks -├── services/ # API service functions -└── assets/ # Static assets -``` - -### Key Technologies -- **React 18** with TypeScript -- **Vite** for build tooling and dev server -- **Tailwind CSS** for styling -- **Zustand** for state management -- **React Flow** for flow graph visualization -- **Lucide React** for icons - ---- - -## 3. Frontend Code Quality - -### Formatting -```bash -make format_frontend # Format TypeScript/JavaScript code -``` - -### Linting -```bash -make lint # Run ESLint and TypeScript checks -``` - -### Testing -```bash -make tests_frontend # Run frontend tests (requires additional setup) -``` - -### Pre-commit Workflow -1. Run `make format_frontend` -2. Run `make lint` -3. Test changes in browser -4. Commit changes - ---- - -## 4. State Management - -### Zustand Stores -```typescript -// stores/myStore.ts -import { create } from 'zustand'; - -interface MyState { - value: string; - setValue: (value: string) => void; -} - -export const useMyStore = create((set) => ({ - value: '', - setValue: (value) => set({ value }), -})); -``` - -### Using Stores in Components -```typescript -// components/MyComponent.tsx -import { useMyStore } from '@/stores/myStore'; - -export function MyComponent() { - const { value, setValue } = useMyStore(); - - return ( - setValue(e.target.value)} - /> - ); -} -``` - ---- - -## 5. API Integration - -### Service Functions -```typescript -// services/api.ts -import { api } from '@/controllers/API'; - -export async function createFlow(flowData: FlowData) { - const response = await api.post('/flows/', flowData); - return response.data; -} - -export async function getFlows() { - const response = await api.get('/flows/'); - return response.data; -} -``` - -### Error Handling -```typescript -// hooks/useApi.ts -import { useState, useCallback } from 'react'; - -export function useApi(apiFunction: (...args: any[]) => Promise) { - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - - const execute = useCallback(async (...args: any[]) => { - try { - setLoading(true); - setError(null); - const result = await apiFunction(...args); - return result; - } catch (err) { - setError(err instanceof Error ? err.message : 'Unknown error'); - throw err; - } finally { - setLoading(false); - } - }, [apiFunction]); - - return { execute, loading, error }; -} -``` - ---- - -## 6. React Flow Integration - -### Flow Graph Components -```typescript -// components/FlowGraph.tsx -import ReactFlow, { - Node, - Edge, - Controls, - Background -} from 'reactflow'; - -interface FlowGraphProps { - nodes: Node[]; - edges: Edge[]; - onNodesChange: (changes: NodeChange[]) => void; - onEdgesChange: (changes: EdgeChange[]) => void; -} - -export function FlowGraph({ - nodes, - edges, - onNodesChange, - onEdgesChange -}: FlowGraphProps) { - return ( -
- - - - -
- ); -} -``` - -### Custom Node Types -```typescript -// components/nodes/ComponentNode.tsx -import { memo } from 'react'; -import { Handle, Position } from 'reactflow'; - -interface ComponentNodeProps { - data: { - label: string; - icon?: string; - }; -} - -export const ComponentNode = memo(({ data }: ComponentNodeProps) => { - return ( -
- - -
- {data.icon && ( - - )} - {data.label} -
- - -
- ); -}); -``` - ---- - -## 7. Styling with Tailwind - -### Component Styling -```typescript -// components/Button.tsx -import { cn } from '@/utils/cn'; - -interface ButtonProps { - variant?: 'primary' | 'secondary'; - size?: 'sm' | 'md' | 'lg'; - children: React.ReactNode; - onClick?: () => void; -} - -export function Button({ - variant = 'primary', - size = 'md', - children, - onClick -}: ButtonProps) { - return ( - - ); -} -``` - -### Dark Mode Support -```typescript -// hooks/useDarkMode.ts -import { useDarkStore } from '@/stores/darkStore'; - -export function useDarkMode() { - const { dark, setDark } = useDarkStore(); - - const toggle = () => setDark(!dark); - - return { isDark: dark, toggle }; -} -``` - ---- - -## 8. Frontend Testing - -### Component Testing -```typescript -// __tests__/Button.test.tsx -import { render, screen, fireEvent } from '@testing-library/react'; -import { Button } from '@/components/Button'; - -describe('Button', () => { - it('renders with correct text', () => { - render(); - expect(screen.getByText('Click me')).toBeInTheDocument(); - }); - - it('calls onClick when clicked', () => { - const handleClick = jest.fn(); - render(); - - fireEvent.click(screen.getByText('Click me')); - expect(handleClick).toHaveBeenCalledTimes(1); - }); -}); -``` - -### Integration Testing -```typescript -// __tests__/FlowEditor.test.tsx -import { render, screen } from '@testing-library/react'; -import { FlowEditor } from '@/pages/FlowEditor'; - -describe('FlowEditor', () => { - it('loads flow data correctly', async () => { - render(); - - // Wait for flow to load - await screen.findByText('Flow loaded'); - - expect(screen.getByTestId('flow-canvas')).toBeInTheDocument(); - }); -}); -``` - ---- - -## 9. Build and Deployment - -### Development Build -```bash -make build_frontend # Build frontend static files -``` - -### Production Build -```bash -cd src/frontend -npm run build # Creates dist/ directory -``` - -### Build Integration -- Frontend builds to `src/frontend/dist/` -- Backend serves static files from this directory in production -- `make init` includes frontend build step ---- - -## Frontend Development Checklist -- [ ] Frontend service running with `make frontend` -- [ ] Changes hot-reload correctly in browser -- [ ] State management uses Zustand stores -- [ ] API calls use proper error handling -- [ ] Components styled with Tailwind CSS -- [ ] Dark mode support implemented where needed -- [ ] Code formatted with `make format_frontend` -- [ ] Linting passed with `make lint` -- [ ] Changes tested in both light and dark mode - -- [ ] Components styled with Tailwind CSS -- [ ] Dark mode support implemented where needed -- [ ] Code formatted with `make format_frontend` -- [ ] Changes tested in both light and dark mode - diff --git a/.cursor/rules/icons.mdc b/.cursor/rules/icons.mdc deleted file mode 100644 index 9d30d9ad68..0000000000 --- a/.cursor/rules/icons.mdc +++ /dev/null @@ -1,137 +0,0 @@ ---- -description: "Rules for creating and implementing component icons in Langflow, covering both backend Python component icon attributes and frontend React icon implementation." -globs: - - "src/frontend/src/icons/**/*" - - "src/frontend/src/icons/lazyIconImports.ts" - - "src/backend/**/*component*.py" - - "src/backend/**/components/**/*.py" -alwaysApply: false ---- - -# Component Icon Rules - -## Purpose - -To ensure consistent, clear, and functional icon usage for components, covering both backend (Python) and frontend (React/TypeScript) steps. - ---- - -## 1. Backend (Python) — Setting the Icon Name - -- **Where:** In your component class (e.g., in `src/backend/base/langflow/components/vectorstores/astradb.py`) -- **How:** - Set the `icon` attribute to a string matching the icon you want to use. - ```python - icon = "AstraDB" - ``` -- **Tip:** - The string must match the frontend icon mapping exactly (case-sensitive). - ---- - -## 2. Frontend (React/TypeScript) — Adding the Icon - -### a. Create the Icon Component - -- **Where:** - In a new directory for your icon, e.g., `src/frontend/src/icons/AstraDB/`. -- **How:** - - - Add your SVG as a React component, e.g., `AstraSVG` in `AstraDB.jsx`. - ```jsx - const AstraSVG = (props) => ( - - - - ); - ``` - - Create an `index.tsx` that exports your icon using `forwardRef`: - - ```tsx - import React, { forwardRef } from "react"; - import AstraSVG from "./AstraDB"; - - export const AstraDBIcon = forwardRef< - SVGSVGElement, - React.PropsWithChildren<{}> - >((props, ref) => { - return ; - }); - ``` - -#### Supporting Light and Dark Mode Icons - -- **How:** - - In your SVG component (e.g., `AstraDB.jsx`), use the `isDark` prop to switch colors: - ```jsx - const AstraSVG = (props) => ( - - - - ); - ``` - - The `isDark` prop is passed from the icon wrapper (see above) and should be used to toggle between light and dark color schemes. - - You can use a utility like `stringToBool` to ensure the prop is interpreted correctly. - -### b. Add to Lazy Icon Imports - -- **Where:** - In `src/frontend/src/icons/lazyIconImports.ts` -- **How:** - Add an entry to the `lazyIconsMapping` object: - ```ts - AstraDB: () => - import("@/icons/AstraDB").then((mod) => ({ default: mod.AstraDBIcon })), - ``` -- **Tip:** - The key (`AstraDB`) must match the string used in the backend. - ---- - -## 3. Best Practices - -- **Naming:** - Use clear, recognizable names (e.g., `"AstraDB"`, `"Postgres"`, `"OpenAI"`). -- **Consistency:** - Always use the same icon name for the same service across backend and frontend. -- **Missing Icon:** - If no icon exists, use a [lucide icon](https://lucide.dev/icons) -- **Light/Dark Mode:** - Always support both light and dark mode for custom icons by using the `isDark` prop in your SVG. - ---- - -## 4. Checklist for Adding a New Icon - -- [ ] Decide on a clear, descriptive icon name (e.g., `AstraDB`). -- [ ] In your Python component, set `icon = "YourIconName"`. -- [ ] Create a new icon directory in `src/frontend/src/icons/YourIconName/`. -- [ ] Add your SVG as a React component (e.g., `YourIconNameIcon.jsx`). -- [ ] Create an `index.tsx` that exports your icon using `forwardRef` and passes the `isDark` prop. -- [ ] Add your icon to `lazyIconsMapping` in `src/frontend/src/icons/lazyIconImports.ts` with the exact same name. -- [ ] Verify the icon appears correctly in the UI in both light and dark mode. -- [ ] If no suitable icon exists, use a generic icon and request a new one if needed. - ---- - -**Example for AstraDB:** - -- Backend: - ```python - icon = "AstraDB" - ``` -- Frontend: - - `src/icons/AstraDB/AstraDB.jsx` (SVG as React component, uses `isDark` prop) - - `src/icons/AstraDB/index.tsx` (exports `AstraDBIcon` and passes `isDark`) - - Add to `lazyIconImports.ts`: - ```ts - AstraDB: () => - import("@/icons/AstraDB").then((mod) => ({ default: mod.AstraDBIcon })), - ``` - ---- diff --git a/.cursor/rules/testing.mdc b/.cursor/rules/testing.mdc deleted file mode 100644 index 1bd0af1cf7..0000000000 --- a/.cursor/rules/testing.mdc +++ /dev/null @@ -1,561 +0,0 @@ ---- -description: "Guidelines for testing Langflow components and backend code, with emphasis on async patterns and robust, well-documented testing practices." -globs: - - "src/backend/tests/**/*.py" - - "src/frontend/**/*.test.{ts,tsx,js,jsx}" - - "src/frontend/**/*.spec.{ts,tsx,js,jsx}" - - "tests/**/*.py" - - "conftest.py" - - "pytest.ini" -alwaysApply: false ---- - -# Testing Guidelines for Langflow - -## Purpose -Guidelines for testing Langflow components and backend code, with emphasis on async patterns and robust, well-documented testing practices. - ---- - -## 1. Testing Structure - -### Backend Tests Location -- **Unit Tests:** `src/backend/tests/` -- **Component Tests:** `src/backend/tests/unit/components/` (organized by component subdirectory) -- **Integration Tests:** Available via `make integration_tests` (requires additional setup) - -### Test File Naming -- Use same filename as component with appropriate test prefix/suffix -- Example: `my_component.py` → `test_my_component.py` - ---- - -## 2. Built-in Fixtures & Base Classes - -### `client` Fixture (FastAPI Test Client) -- Defined in `src/backend/tests/conftest.py` -- Provides an **async** `httpx.AsyncClient` connected to the full application via `ASGITransport` + `LifespanManager`. -- Use it for API tests: - ```python - async def test_login_endpoint(client): - response = await client.post("api/v1/login", data={"username": "foo", "password": "bar"}) - assert response.status_code == 200 - ``` -- Automatically configured with an **in-memory SQLite database** and mocked environment variables. No additional setup needed in individual tests. -- Skip client creation by marking the test with `@pytest.mark.noclient`. - -### `ComponentTestBase` Family -Located in `src/backend/tests/base.py`. - -| Base Class | Creates `client`? | Typical Use | Notes | -|------------|------------------|-------------|-------| -| `ComponentTestBase` | No | Core logic for component version testing | Requires you to provide fixtures described below. | -| `ComponentTestBaseWithClient` | Yes (`@pytest.mark.usefixtures("client")`) | Components that need API access during `run()` | Inherit when the component interacts with backend services. | -| `ComponentTestBaseWithoutClient` | No | Pure-logic components with no API calls | Lightweight alternative. | - -Required fixtures for subclasses: -1. `component_class` → the component **class** under test. -2. `default_kwargs` → dict of kwargs to instantiate the component (can be empty). -3. `file_names_mapping` → list of `VersionComponentMapping` dicts mapping historical **Langflow versions** to module/file names. - -Example skeleton: -```python -from tests.base import ComponentTestBaseWithClient, VersionComponentMapping, DID_NOT_EXIST -from langflow.components.my_namespace import MyComponent - -class TestMyComponent(ComponentTestBaseWithClient): - @pytest.fixture - def component_class(self): - return MyComponent - - @pytest.fixture - def default_kwargs(self): - return {"foo": "bar"} - - @pytest.fixture - def file_names_mapping(self): - return [ - VersionComponentMapping(version="1.1.1", module="my_module", file_name="my_component.py"), - # Older versions can be mapped or DID_NOT_EXIST - VersionComponentMapping(version="1.0.19", module="my_module", file_name=DID_NOT_EXIST), - ] -``` - -`ComponentTestBase` automatically provides: -- `test_latest_version` → Instantiates component via `component_class` and asserts `run()` doesn't return `None`. -- `test_all_versions_have_a_file_name_defined` → Ensures mapping completeness vs `SUPPORTED_VERSIONS` constant (`src/backend/tests/constants.py`). -- `test_component_versions` (parametrised) → Builds component from source for each supported version and asserts successful execution. - -When adding a new component test, **inherit from the correct base class and provide the three fixtures**. This greatly reduces boilerplate and enforces version compatibility. - ---- - -## 3. Component Testing Requirements - -### Minimum Testing Requirements -- **Unit Tests:** Create comprehensive unit tests for all new components -- **Manual Test Documentation:** If unit tests are incomplete, create a Markdown file with manual testing steps - - Location: Same directory as unit tests - - Filename: Same as component but with `.md` extension - - Content: Detailed manual testing steps and expected outcomes - -### Testing Best Practices -- Test both sync and async code paths -- Mock external dependencies appropriately -- Test error handling and edge cases -- Validate input/output behavior -- Test component initialization and configuration - ---- - -## 4. Async Testing Patterns - -### Async Component Testing -```python -import pytest -import asyncio - -@pytest.mark.asyncio -async def test_async_component(): - # Test async component methods - result = await component.async_method() - assert result is not None -``` - -### Testing Background Tasks -```python -@pytest.mark.asyncio -async def test_background_task_completion(): - # Ensure background tasks complete properly - task = asyncio.create_task(component.background_operation()) - result = await asyncio.wait_for(task, timeout=5.0) - assert result.success -``` - -### Testing Queue Operations -```python -@pytest.mark.asyncio -async def test_queue_operations(): - # Test queue put/get operations without blocking - queue = asyncio.Queue() - - # Non-blocking put - queue.put_nowait(test_data) - - # Verify queue processing - result = await asyncio.wait_for(queue.get(), timeout=1.0) - assert result == test_data -``` - ---- - -## 5. Special Testing Considerations - -### Blockbuster Plugin -- Use `no_blockbuster` pytest marker to skip blockbuster plugin in tests -- Example: `@pytest.mark.no_blockbuster` - -### Database Tests -- `test_database.py` may fail in batch runs but pass individually -- Run problematic tests sequentially: `uv run pytest src/backend/tests/unit/test_database.py` -- Consider this behavior when writing database-related tests - -### Context Variables in Async Tests -- Be aware of ContextVar propagation in async tests -- Test both direct event loop execution and `asyncio.to_thread` scenarios -- Ensure proper context isolation between test cases - ---- - -## 6. Test Execution - -### Running Tests -```bash -make unit_tests # Run all backend unit tests -make integration_tests # Run integration tests (requires additional setup) -make coverage # Run tests with coverage (requires additional setup) -make tests_frontend # Run frontend tests (requires additional setup) -``` - -### Individual Test Execution -```bash -# Run specific test file -uv run pytest src/backend/tests/unit/test_specific_component.py - -# Run specific test method -uv run pytest src/backend/tests/unit/test_component.py::test_specific_method - -# Run with verbose output -uv run pytest -v src/backend/tests/unit/ -``` - ---- - -## 7. Robust Testing Patterns - -### Error Handling Tests -```python -def test_component_error_handling(): - """Test that component handles errors gracefully.""" - with pytest.raises(ExpectedError): - component.method_that_should_fail(invalid_input) - - # Test error message quality - try: - component.risky_operation() - except ComponentError as e: - assert "helpful error message" in str(e) -``` - -### Resource Cleanup Tests -```python -@pytest.fixture -async def component_with_cleanup(): - """Fixture ensuring proper resource cleanup.""" - component = MyComponent() - await component.initialize() - try: - yield component - finally: - await component.cleanup() -``` - -### Timeout and Performance Tests -```python -@pytest.mark.asyncio -async def test_operation_timeout(): - """Test that operations respect timeout constraints.""" - start_time = time.time() - - with pytest.raises(asyncio.TimeoutError): - await asyncio.wait_for( - component.long_running_operation(), - timeout=1.0 - ) - - elapsed = time.time() - start_time - assert elapsed < 1.5 # Allow some tolerance -``` - ---- - -## 8. Documentation in Tests - -### Test Documentation Standards -- Each test should have a clear docstring explaining its purpose -- Complex test setups should be commented -- Mock usage should be documented -- Expected behaviors should be explicitly stated - -### Example Well-Documented Test -```python -async def test_component_background_processing(): - """ - Test that component processes items in background without blocking. - - This test verifies: - 1. Items are added to processing queue immediately - 2. Background processing completes successfully - 3. No deadlocks occur during shutdown - 4. All tasks are properly cleaned up - """ - # Setup component with background processing - component = BackgroundComponent() - await component.start() - - try: - # Add items for processing - for i in range(10): - await component.add_item(f"item_{i}") - - # Verify items are queued (non-blocking) - assert component.queue_size() == 10 - - # Wait for processing to complete - await component.wait_for_completion(timeout=5.0) - - # Verify all items processed - assert component.processed_count() == 10 - - finally: - # Ensure clean shutdown - await component.stop() - assert component.is_stopped() -``` - ---- - -## Testing Checklist -- [ ] Unit tests created for all new components -- [ ] Async patterns tested appropriately -- [ ] Error handling and edge cases covered -- [ ] Manual testing documentation created (if unit tests incomplete) -- [ ] Background tasks and queues tested for proper cleanup -- [ ] Database tests considered for sequential execution if needed -- [ ] Appropriate pytest markers used (`no_blockbuster`, etc.) -- [ ] Tests are well-documented with clear docstrings -- [ ] Resource cleanup properly handled in fixtures -- [ ] Timeout and performance constraints validated - ---- - -## 9. Langflow-Specific Testing Patterns - -### Message Testing -Test Langflow's `Message` objects and chat functionality: - -```python -from langflow.schema.message import Message -from langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER - -async def test_message_response(self, component_class, default_kwargs): - """Test Message object creation and properties.""" - component = component_class(**default_kwargs) - message = await component.message_response() - - assert isinstance(message, Message) - assert message.text == default_kwargs["input_value"] - assert message.sender == default_kwargs["sender"] - assert message.sender_name == default_kwargs["sender_name"] - assert message.session_id == default_kwargs["session_id"] - assert message.files == default_kwargs["files"] - # Test message properties structure - assert message.properties.model_dump() == { - "background_color": default_kwargs["background_color"], - "text_color": default_kwargs["text_color"], - "icon": default_kwargs["chat_icon"], - # ... other expected properties - } -``` - -### Flow Testing with JSON Data -Use predefined JSON flows and utility functions: - -```python -from tests.unit.build_utils import create_flow, build_flow, get_build_events, consume_and_assert_stream - -async def test_flow_execution(client, json_memory_chatbot_no_llm, logged_in_headers): - """Test flow creation, building, and execution.""" - # Create flow from JSON data - flow_id = await create_flow(client, json_memory_chatbot_no_llm, logged_in_headers) - - # Start the build process - build_response = await build_flow(client, flow_id, logged_in_headers) - job_id = build_response["job_id"] - - # Get and validate event stream - events_response = await get_build_events(client, job_id, logged_in_headers) - assert events_response.status_code == codes.OK - - # Process events and validate structure - await consume_and_assert_stream(events_response, job_id) -``` - -### Component Testing with Real Services -Test components that need external APIs with proper markers: - -```python -@pytest.mark.api_key_required -@pytest.mark.no_blockbuster -async def test_component_with_external_api(self): - """Test component with external API integration.""" - api_key = os.getenv("OPENAI_API_KEY") - - component = MyAPIComponent( - api_key=api_key, - model_name="gpt-4o", - input_value="test input", - session_id=str(uuid4()), - ) - - response = await component.message_response() - assert response.data.get("text") is not None -``` - -### Mocking Language Models -Use `MockLanguageModel` for testing without external APIs: - -```python -from tests.unit.mock_language_model import MockLanguageModel - -@pytest.fixture -def default_kwargs(self): - return { - "agent_llm": MockLanguageModel(), - "input_value": "test message", - "session_id": str(uuid4()), - # ... other component-specific kwargs - } -``` - -### File Handling in Tests -Use `anyio` and `aiofiles` for async file operations: - -```python -import aiofiles -import anyio - -async def test_file_operations(self, component_class, tmp_path): - """Test component file handling.""" - # Create temporary test file - test_file = anyio.Path(tmp_path) / "test.txt" - await test_file.write_text("Test content", encoding="utf-8") - - # Test with file input - component = component_class(files=[str(test_file)]) - result = await component.run() - - # Verify file was processed - assert len(result.files) == 1 - assert await test_file.exists() -``` - -### API Endpoint Testing -Test Langflow's REST API endpoints: - -```python -async def test_flows_endpoint(client, logged_in_headers): - """Test flow creation via API.""" - flow_data = { - "name": "Test Flow", - "description": "Test description", - "data": {"nodes": [], "edges": []} - } - - response = await client.post( - "api/v1/flows/", - json=flow_data, - headers=logged_in_headers - ) - assert response.status_code == codes.CREATED - - flow = response.json() - assert flow["name"] == "Test Flow" - assert "id" in flow -``` - -### Build Config Testing -Test component configuration updates: - -```python -async def test_build_config_updates(self, component_class, default_kwargs): - """Test dynamic build configuration updates.""" - component = await self.component_setup(component_class, default_kwargs) - frontend_node = component.to_frontend_node() - build_config = frontend_node["data"]["node"]["template"] - - # Test configuration update - component.set(llm_provider="OpenAI") - updated_config = await component.update_build_config( - build_config, "OpenAI", "llm_provider" - ) - - assert updated_config["llm_provider"]["value"] == "OpenAI" - assert "gpt-4o" in updated_config["model_name"]["options"] -``` - -### Testing Event Streams -Test real-time event streaming endpoints: - -```python -async def consume_and_validate_events(response, expected_job_id): - """Consume NDJSON event stream and validate structure.""" - count = 0 - first_event_seen = False - end_event_seen = False - - async for line in response.aiter_lines(): - if not line: - continue - - parsed = json.loads(line) - - # Validate job_id in events - if "job_id" in parsed: - assert parsed["job_id"] == expected_job_id - - # First event should be vertices_sorted - if not first_event_seen: - assert parsed["event"] == "vertices_sorted" - first_event_seen = True - - # Track end event - elif parsed["event"] == "end": - end_event_seen = True - - count += 1 - - assert first_event_seen and end_event_seen - return count -``` - -### Testing Component Versioning -Test backward compatibility across Langflow versions: - -```python -@pytest.fixture -def file_names_mapping(self): - """Map component files across Langflow versions.""" - return [ - VersionComponentMapping( - version="1.1.1", - module="inputs", - file_name="chat" - ), - VersionComponentMapping( - version="1.1.0", - module="inputs", - file_name="chat" - ), - VersionComponentMapping( - version="1.0.19", - module="inputs", - file_name="ChatInput" - ), - ] -``` - -### Webhook Testing -Test webhook endpoints with proper payload handling: - -```python -async def test_webhook_endpoint(client, added_webhook_test): - """Test webhook flow execution.""" - endpoint_name = added_webhook_test["endpoint_name"] - endpoint = f"api/v1/webhook/{endpoint_name}" - - payload = {"path": "/tmp/test_file.txt"} - - response = await client.post(endpoint, json=payload) - assert response.status_code == 202 - - # Verify webhook processed the payload - # ... additional validation logic -``` - -### Monkeypatch for Testing Errors -Test error handling by mocking internal functions: - -```python -async def test_cancellation_error(client, flow_id, logged_in_headers, monkeypatch): - """Test error handling during flow cancellation.""" - import langflow.api.v1.chat - - async def mock_cancel_with_error(*args, **kwargs): - raise RuntimeError("Cancellation failed") - - monkeypatch.setattr( - langflow.api.v1.chat, - "cancel_flow_build", - mock_cancel_with_error - ) - - response = await client.post( - f"api/v1/build/{job_id}/cancel", - headers=logged_in_headers - ) - assert response.status_code == codes.INTERNAL_SERVER_ERROR - assert "Cancellation failed" in response.json()["detail"] -``` - - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 683c91dd96..c7f346e624 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,8 +117,11 @@ jobs: TODAY=$(date -u +"%Y-%m-%d") echo "Today's date: $TODAY" - # Query PyPI API for the langflow package - HTTP_STATUS=$(curl -s -o response.json -w "%{http_code}" https://pypi.org/pypi/langflow-nightly/json) + # Query PyPI for the canonical langflow project. The nightly now publishes as a `.devN` + # pre-release of `langflow` (not a separate `langflow-nightly` distribution), so inspect + # the most recent dev release rather than `.info.version` (which is the latest stable). + # See src/bundles/NIGHTLY.md. + HTTP_STATUS=$(curl -s -o response.json -w "%{http_code}" https://pypi.org/pypi/langflow/json) # Check HTTP status code first if [ "$HTTP_STATUS" -ne 200 ]; then @@ -136,16 +139,16 @@ jobs: exit 0 fi - # Extract the latest version - LATEST_VERSION=$(jq -r '.info.version // empty' response.json) + # Extract the most recent nightly (.devN pre-release), highest by version sort + LATEST_VERSION=$(jq -r '.releases | keys[]' response.json | grep -E '\.dev[0-9]+$' | sort -V | tail -n1) if [ -z "$LATEST_VERSION" ]; then - echo "Could not extract latest version" + echo "Could not find a nightly (.devN) release" echo "success=false" >> $GITHUB_OUTPUT exit 0 fi - # Extract the release date of the latest version + # Extract the release date of that nightly version RELEASE_DATE=$(jq -r --arg ver "$LATEST_VERSION" '.releases[$ver][0].upload_time_iso_8601 // empty' response.json | cut -d'T' -f1) if [ -z "$RELEASE_DATE" ]; then diff --git a/.github/workflows/db-migration-validation.yml b/.github/workflows/db-migration-validation.yml index f638785519..9a3c905c4c 100644 --- a/.github/workflows/db-migration-validation.yml +++ b/.github/workflows/db-migration-validation.yml @@ -161,12 +161,12 @@ jobs: NIGHTLY_TAG="${{ inputs.nightly_tag || 'langflowai/langflow-nightly:latest' }}" echo "Upgrading to nightly version: $NIGHTLY_TAG" - # Remove stable distributions before installing nightly. - # langflow and langflow-nightly share langflow-base which writes to the - # same site-packages/langflow/ namespace. If stable stays installed, - # python -m langflow still boots the stable version and no real - # nightly migration is exercised (false-positive test). - echo "Removing stable langflow to avoid namespace collision with nightly..." + # Remove the stable install first. The nightly now publishes as a `.devN` pre-release of + # the canonical `langflow` (same distribution as stable, different version), so a clean + # uninstall avoids stale files and guarantees the dev version is what boots — otherwise + # `python -m langflow` could keep running the stable version and no real nightly migration + # is exercised (false-positive test). + echo "Removing stable langflow to force a clean install of the nightly dev version..." uv pip uninstall -y langflow langflow-base || true # Extract version from Docker tag (format: langflowai/langflow-nightly:v1.10.0.dev20260522) @@ -178,21 +178,30 @@ jobs: VERSION="${VERSION#v}" echo "Version for PyPI: $VERSION" + # Scope pre-release resolution to the langflow stack only. uv accepts a + # pre-release for a package when its own requirement carries a pre-release + # marker, but NOT via transitive pins (langflow -> langflow-base -> lfx -> + # langflow-sdk are exact ==devN pins on nightlies), so each lockstep package + # must be requested directly. A global --prerelease=allow is NOT safe here: + # it lets unrelated dependencies resolve to alphas (pydantic 2.14.0a1 broke + # langchain-core imports on the first canonical-prerelease nightly). + # langflow-sdk has its own version line, so an explicit .dev0 floor marks it + # pre-release-eligible while the lfx pin selects the exact version. if [[ "$VERSION" == "latest" ]]; then - # Install latest nightly from PyPI - uv pip install --upgrade 'langflow-nightly[postgresql]' + # Install latest nightly (canonical pre-release) from PyPI + uv pip install --upgrade 'langflow[postgresql]>=0.0.0.dev0' 'langflow-base>=0.0.0.dev0' 'lfx>=0.0.0.dev0' 'langflow-sdk>=0.0.0.dev0' else # Install specific version - uv pip install --upgrade "langflow-nightly[postgresql]==$VERSION" + uv pip install --upgrade "langflow[postgresql]==$VERSION" "langflow-base==$VERSION" "lfx==$VERSION" 'langflow-sdk>=0.0.0.dev0' fi else # Direct version string (strip 'v' prefix if present) VERSION="${NIGHTLY_TAG#v}" - uv pip install --upgrade "langflow-nightly[postgresql]==$VERSION" + uv pip install --upgrade "langflow[postgresql]==$VERSION" "langflow-base==$VERSION" "lfx==$VERSION" 'langflow-sdk>=0.0.0.dev0' fi # Verify upgrade - python -c 'from importlib.metadata import version; print("Upgraded to Langflow Nightly version:", version("langflow-nightly"))' + python -c 'from importlib.metadata import version; print("Upgraded to Langflow Nightly version:", version("langflow"))' - name: Run migration and verify startup working-directory: migration-test diff --git a/.github/workflows/docker-nightly-build.yml b/.github/workflows/docker-nightly-build.yml index 7411e5a6b6..1ac15fde5a 100644 --- a/.github/workflows/docker-nightly-build.yml +++ b/.github/workflows/docker-nightly-build.yml @@ -72,7 +72,11 @@ jobs: id: version run: | echo "Extracting base version from pyproject.toml" - version=$(uv tree 2>/dev/null | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//' | head -n 1) + # Anchor to the langflow-base workspace-root line (same pattern as the + # langflow extraction below): the unanchored grep used to match a + # dependency line whose version sat in field 3, but uv tree now lists + # the langflow-base root line first, which has no third field. + version=$(uv tree 2>/dev/null | grep -E '^langflow-base[[:space:]]' | cut -d' ' -f2 | sed 's/^v//' | head -n 1) # Verify nightly tag format @@ -351,7 +355,7 @@ jobs: id: version run: | if [[ "${{ inputs.release_type }}" == "nightly-base" ]]; then - version=$(uv tree 2>/dev/null | grep 'langflow-base' | awk '{print $3}' | sed 's/^v//' | head -n 1) + version=$(uv tree 2>/dev/null | grep -E '^langflow-base[[:space:]]' | cut -d' ' -f2 | sed 's/^v//' | head -n 1) else version=$(uv tree 2>/dev/null | grep -E '^langflow(-nightly)?[[:space:]]' | cut -d' ' -f2 | sed 's/^v//') fi diff --git a/.github/workflows/nightly_build.yml b/.github/workflows/nightly_build.yml index c9b02982cb..def8504263 100644 --- a/.github/workflows/nightly_build.yml +++ b/.github/workflows/nightly_build.yml @@ -172,13 +172,9 @@ jobs: cd src/lfx && uv lock && cd ../.. git add pyproject.toml src/backend/base/pyproject.toml src/lfx/pyproject.toml src/sdk/pyproject.toml uv.lock - # update_lfx_version.py re-pins each bundle's `lfx` dep to - # lfx-nightly==, so any modified bundle pyprojects need to - # ride the same commit/tag as the rest of the version bumps. - if compgen -G "src/bundles/*/pyproject.toml" > /dev/null; then - git add src/bundles/*/pyproject.toml - fi - git commit -m "Update version and project name" + # The nightly keeps canonical package names and the stable `lfx-*` bundles + # are not modified (see src/bundles/NIGHTLY.md), so no bundle pyprojects ride this commit. + git commit -m "Update version for nightly" echo "Tagging main with $RELEASE_TAG" if ! git tag -a $RELEASE_TAG -m "Langflow nightly $RELEASE_TAG"; then diff --git a/.github/workflows/python_test.yml b/.github/workflows/python_test.yml index 40d3a6cf95..1975763ab7 100644 --- a/.github/workflows/python_test.yml +++ b/.github/workflows/python_test.yml @@ -93,7 +93,7 @@ jobs: - name: Run unit tests uses: nick-fields/retry@v3 with: - timeout_minutes: 40 + timeout_minutes: 50 max_attempts: 2 command: make unit_tests args="-x -vv --splits ${{ matrix.splitCount }} --group ${{ matrix.group }} --reruns 5 --cov --cov-config=src/backend/.coveragerc --cov-report=xml --cov-report=html" diff --git a/.github/workflows/release-lfx.yml b/.github/workflows/release-lfx.yml index fd7c11b8bf..5ce6220f08 100644 --- a/.github/workflows/release-lfx.yml +++ b/.github/workflows/release-lfx.yml @@ -276,7 +276,7 @@ jobs: create-release: name: Create GitHub Release - needs: [release-lfx, build-docker] + needs: [validate-version, release-lfx, build-docker] if: always() && github.event.inputs.create_github_release == 'true' && needs.release-lfx.result == 'success' runs-on: ubuntu-latest steps: @@ -337,6 +337,9 @@ jobs: uses: softprops/action-gh-release@v2 with: tag_name: lfx-v${{ github.event.inputs.version }} + # Pin the minted tag to the commit this release was built from; + # without it GitHub creates the tag at the default-branch HEAD. + target_commitish: ${{ github.sha }} name: LFX ${{ github.event.inputs.version }} body_path: release_notes.md draft: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41c9e13e24..ade6471a4c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1216,6 +1216,20 @@ jobs: with: name: dist-main path: dist + # The release must attach to the dispatched v-prefixed tag. Passing the + # bare version as `tag` made GitHub mint a new lightweight tag at the + # default-branch HEAD — the wrong commit, still carrying the previous + # version (main only adopts the new version via the post-release + # back-merge). Pre-releases keep their computed tag (e.g. 1.10.0rc1), + # but `commit` pins any newly minted tag to the release commit. + - name: Resolve release commit + id: release_commit + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + sha=$(gh api "repos/${{ github.repository }}/commits/${{ inputs.release_tag }}" --jq '.sha') + echo "Release tag '${{ inputs.release_tag }}' resolves to commit $sha" + echo "sha=$sha" >> "$GITHUB_OUTPUT" - name: Create Release uses: ncipollo/release-action@v1 with: @@ -1224,6 +1238,8 @@ jobs: draft: false generateReleaseNotes: true prerelease: ${{ inputs.pre_release }} - tag: ${{ needs.determine-main-version.outputs.version }} + tag: ${{ inputs.pre_release && needs.determine-main-version.outputs.version || inputs.release_tag }} + name: ${{ needs.determine-main-version.outputs.version }} + commit: ${{ steps.release_commit.outputs.sha }} allowUpdates: true updateOnlyUnreleased: false diff --git a/.github/workflows/release_nightly.yml b/.github/workflows/release_nightly.yml index 7321b6c5e5..ed18ecd461 100644 --- a/.github/workflows/release_nightly.yml +++ b/.github/workflows/release_nightly.yml @@ -81,8 +81,8 @@ jobs: run: | name=$(grep '^name = "' src/sdk/pyproject.toml | head -n 1 | sed 's/.*"\(.*\)".*/\1/') version=$(grep '^version = "' src/sdk/pyproject.toml | head -n 1 | sed 's/.*"\(.*\)".*/\1/') - if [ "$name" != "langflow-sdk-nightly" ]; then - echo "Name $name does not match langflow-sdk-nightly. Exiting the workflow." + if [ "$name" != "langflow-sdk" ]; then + echo "Name $name does not match langflow-sdk. Exiting the workflow." exit 1 fi if [ "v$version" != "${{ inputs.nightly_tag_sdk }}" ]; then @@ -94,10 +94,11 @@ jobs: id: verify run: | cd src/lfx - name=$(uv tree | grep 'lfx' | head -n 1 | awk '{print $1}') - version=$(uv tree | grep 'lfx' | head -n 1 | awk '{print $2}') - if [ "$name" != "lfx-nightly" ]; then - echo "Name $name does not match lfx-nightly. Exiting the workflow." + # Root the tree at lfx; a bare `grep lfx` matches bundles like `lfx-ibm` first. + name=$(uv tree --package lfx | head -n 1 | awk '{print $1}') + version=$(uv tree --package lfx | head -n 1 | awk '{print $2}') + if [ "$name" != "lfx" ]; then + echo "Name $name does not match lfx. Exiting the workflow." exit 1 fi if [ "$version" != "${{ inputs.nightly_tag_lfx }}" ]; then @@ -188,12 +189,14 @@ jobs: - name: Verify Nightly Name and Version id: verify run: | - name=$(uv tree | grep 'langflow-base' | awk '{print $2}' | head -n 1) - version=$(uv tree | grep 'langflow-base' | awk '{print $3}' | head -n 1) - # Strip extras from package name (e.g., "langflow-base-nightly[complete]" -> "langflow-base-nightly") + # Root the tree at langflow-base; it prints as a top-level `langflow-base v` line, + # so a bare `grep langflow-base` would read the version into $name and leave $version empty. + name=$(uv tree --package langflow-base | head -n 1 | awk '{print $1}') + version=$(uv tree --package langflow-base | head -n 1 | awk '{print $2}') + # Strip extras from package name (e.g., "langflow-base[complete]" -> "langflow-base") name_without_extras=$(echo $name | sed 's/\[.*\]//') - if [ "$name_without_extras" != "langflow-base-nightly" ]; then - echo "Name $name_without_extras does not match langflow-base-nightly. Exiting the workflow." + if [ "$name_without_extras" != "langflow-base" ]; then + echo "Name $name_without_extras does not match langflow-base. Exiting the workflow." echo "skipped=true" >> $GITHUB_OUTPUT exit 1 fi @@ -297,10 +300,10 @@ jobs: - name: Verify Nightly Name and Version id: verify run: | - name=$(uv tree | grep -E '^langflow(-nightly)?[[:space:]]' | awk '{print $1}') - version=$(uv tree | grep -E '^langflow(-nightly)?[[:space:]]' | awk '{print $2}') - if [ "$name" != "langflow-nightly" ]; then - echo "Name $name does not match langflow-nightly. Exiting the workflow." + name=$(uv tree | grep -E '^langflow[[:space:]]' | awk '{print $1}') + version=$(uv tree | grep -E '^langflow[[:space:]]' | awk '{print $2}') + if [ "$name" != "langflow" ]; then + echo "Name $name does not match langflow. Exiting the workflow." exit 1 fi if [ "$version" != "${{ inputs.nightly_tag_release }}" ]; then @@ -337,9 +340,9 @@ jobs: - name: Prepare Langflow Main artifact run: | shopt -s nullglob - MAIN_WHEELS=(dist/langflow_nightly-*.whl) + MAIN_WHEELS=(dist/langflow-*.whl) if [ ${#MAIN_WHEELS[@]} -ne 1 ]; then - echo "Expected exactly one langflow-nightly wheel in dist/, found ${#MAIN_WHEELS[@]}" + echo "Expected exactly one langflow wheel in dist/, found ${#MAIN_WHEELS[@]}" ls -la dist/ exit 1 fi @@ -347,23 +350,9 @@ jobs: mkdir -p main-dist cp "${MAIN_WHEELS[0]}" main-dist/ - - name: Build bundle wheels for cross-platform test - run: | - shopt -s nullglob - bundles=(src/bundles/*/pyproject.toml) - if [ ${#bundles[@]} -eq 0 ]; then - echo "No bundles found under src/bundles/*/" - exit 1 - fi - rm -rf bundles-dist - mkdir -p bundles-dist - BUNDLES_DIST="$PWD/bundles-dist" - for bundle_pyproject in "${bundles[@]}"; do - bundle_dir=$(dirname "$bundle_pyproject") - echo "Building wheel for $bundle_dir" - (cd "$bundle_dir" && uv build --wheel --out-dir "$BUNDLES_DIST") - done - ls -la bundles-dist/ + # Bundles are NOT rebuilt/republished for nightly. The stable `lfx-*` bundles on + # PyPI work as-is against the canonical `lfx` pre-release (see src/bundles/NIGHTLY.md). The + # cross-platform test self-builds the bundles from src/bundles for install coverage. # PyPI publishing moved to after cross-platform testing @@ -373,12 +362,6 @@ jobs: name: dist-nightly-main path: main-dist - - name: Upload bundles artifact - uses: actions/upload-artifact@v6 - with: - name: dist-nightly-bundles - path: bundles-dist - test-cross-platform: name: Test Cross-Platform Installation needs: [build-nightly-lfx, build-nightly-base, build-nightly-main] @@ -388,7 +371,6 @@ jobs: main-artifact-name: "dist-nightly-main" lfx-artifact-name: "dist-nightly-lfx" sdk-artifact-name: "dist-nightly-sdk" - bundles-artifact-name: "dist-nightly-bundles" publish-nightly-lfx: name: Publish LFX Nightly to PyPI @@ -475,60 +457,10 @@ jobs: run: | make publish base=true - publish-nightly-bundles: - name: Publish Langflow Bundles Nightly to PyPI - # langflow-nightly pins each `lfx--nightly==` exactly, so the - # bundles must be on PyPI before main is published (publish-nightly-main - # gates on this job). They depend on `lfx-nightly`, so gate on the lfx - # publish too (or skip it when lfx isn't being rebuilt). - needs: [build-nightly-main, test-cross-platform, publish-nightly-lfx] - if: ${{ always() && needs.build-nightly-main.result == 'success' && needs.test-cross-platform.result == 'success' && (needs.publish-nightly-lfx.result == 'success' || inputs.build_lfx == false) }} - runs-on: ubuntu-latest - steps: - - name: Download bundles artifact - uses: actions/download-artifact@v7 - with: - name: dist-nightly-bundles - path: bundles-dist - - name: Setup Environment - uses: astral-sh/setup-uv@v6 - with: - enable-cache: false - python-version: "3.13" - - name: Publish bundles to PyPI - env: - POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_API_TOKEN }} - UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }} - run: | - shopt -s nullglob - wheels=(bundles-dist/*.whl) - if [ ${#wheels[@]} -eq 0 ]; then - echo "No bundle wheels to publish." - exit 1 - fi - failed=0 - for wheel in "${wheels[@]}"; do - echo "Publishing $wheel" - # Capture stderr so a re-run without a version bump is a no-op for - # an already-published bundle instead of failing the whole job. - if ! err=$(uv publish "$wheel" 2>&1); then - echo "$err" - if echo "$err" | grep -qiE 'already exists|file already exists|HTTP 400|duplicate'; then - echo "Skipping $wheel: already published." - else - echo "Publish failed for $wheel" - failed=1 - fi - fi - done - if [ "$failed" = "1" ]; then - exit 1 - fi - publish-nightly-main: name: Publish Langflow Main Nightly to PyPI - needs: [build-nightly-main, test-cross-platform, publish-nightly-base, publish-nightly-bundles] - if: ${{ always() && needs.build-nightly-main.result == 'success' && needs.test-cross-platform.result == 'success' && needs.publish-nightly-base.result == 'success' && needs.publish-nightly-bundles.result == 'success' }} + needs: [build-nightly-main, test-cross-platform, publish-nightly-base] + if: ${{ always() && needs.build-nightly-main.result == 'success' && needs.test-cross-platform.result == 'success' && needs.publish-nightly-base.result == 'success' }} runs-on: ubuntu-latest steps: - name: Checkout code diff --git a/.secrets.baseline b/.secrets.baseline index 46eaaf3efe..8c0c458bf5 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -133,7 +133,7 @@ "filename": ".github/workflows/nightly_build.yml", "hashed_secret": "3e26d6750975d678acb8fa35a0f69237881576b0", "is_verified": false, - "line_number": 304, + "line_number": 308, "is_secret": false } ], @@ -153,7 +153,7 @@ "filename": ".github/workflows/release_nightly.yml", "hashed_secret": "3e26d6750975d678acb8fa35a0f69237881576b0", "is_verified": false, - "line_number": 565, + "line_number": 497, "is_secret": false } ], @@ -2352,29 +2352,6 @@ "line_number": 774 } ], - "src/backend/base/langflow/initial_setup/starter_projects/Pok\u00e9dex Agent.json": [ - { - "type": "Hex High Entropy String", - "filename": "src/backend/base/langflow/initial_setup/starter_projects/Pok\u00e9dex Agent.json", - "hashed_secret": "54ed260e3bc31bc77ee06754dff850981d39a66c", - "is_verified": false, - "line_number": 115 - }, - { - "type": "Hex High Entropy String", - "filename": "src/backend/base/langflow/initial_setup/starter_projects/Pok\u00e9dex Agent.json", - "hashed_secret": "d6e6d7b4b115cd3b9d172623199f8c403055fecc", - "is_verified": false, - "line_number": 394 - }, - { - "type": "Hex High Entropy String", - "filename": "src/backend/base/langflow/initial_setup/starter_projects/Pok\u00e9dex Agent.json", - "hashed_secret": "ecdbe30d19e36761df3620b37270f23c8e3eaa4c", - "is_verified": false, - "line_number": 774 - } - ], "src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json": [ { "type": "Hex High Entropy String", @@ -2860,7 +2837,7 @@ "filename": "src/backend/tests/conftest.py", "hashed_secret": "8bb6118f8fd6935ad0876a3be34a717d32708ffd", "is_verified": false, - "line_number": 490, + "line_number": 515, "is_secret": false }, { @@ -2868,7 +2845,7 @@ "filename": "src/backend/tests/conftest.py", "hashed_secret": "61fbb5a12cd7b1f1fe1624120089efc0cd299e43", "is_verified": false, - "line_number": 700, + "line_number": 725, "is_secret": false } ], @@ -9310,5 +9287,5 @@ } ] }, - "generated_at": "2026-06-05T18:07:39Z" + "generated_at": "2026-06-10T08:36:23Z" } diff --git a/docs/agents/ANTI-PATTERNS.md b/docs/agents/ANTI-PATTERNS.md new file mode 100644 index 0000000000..98c9f84111 --- /dev/null +++ b/docs/agents/ANTI-PATTERNS.md @@ -0,0 +1,79 @@ +# Anti-Patterns and Scar Tissue + +These are battle scars. Every rule here cites a real recurring failure: a commit, a revert, or an explicit project lesson. Read this file when you're about to "just" change something — most of the don't/do rules below started as a one-line "small fix" that broke production. + +## Don't / Do (with why) + +1. **Don't add or rename a field on a component without regenerating starter projects AND the component index.** + *Why:* commits `1a9f4548c`, `5987421bd`, `bbe1dad7c`, `69d29a4c6`, `67af71450`, `4f9beebc0` are all `fix:` commits cleaning up the same "I added a field and shipped" mistake. CI (`9dad1965c`) now syncs the index on label addition — that's a backstop, not a substitute. + +2. **Don't rename a component class, display name, or module path.** If unavoidable, add the new component alongside the old one, set `legacy = True` + `replacement = ["."]` on the old class, and update every supported version's `file_names_mapping` in tests. + *Why:* class names key saved flows. There is no class-rename map in `setup.py` — the `type_migrations` map there only handles output type strings (`Data` → `JSON`, `DataFrame` → `Table`). See `2a7c56e84` (`IngestionDescriberComponent` → `FileDescriptionGeneratorComponent`) and `f5a0d52197` (starter project rename) for the cleanup churn. See [CONTRACTS.md](./CONTRACTS.md) for the full list. + +3. **Don't mock at a different boundary than production calls.** If production uses `subprocess.Popen`, mock `Popen` — not `run`. + *Why:* `a747135d1`, `bc433c375` — mocked tests passed; production failed. **Better: don't mock at all** — project policy is "Avoid mocking in tests." Use real integrations or `MockLanguageModel` for pure-logic LLM paths. + +4. **Don't write a Graph test by poking internals.** + *Why:* the canonical pattern is build → connect via `.set()` → call `async_start` → iterate results → validate. Tests that bypass this don't exercise the graph the way users do. + +5. **Don't add a retry, broaden an except, or widen a type to make a symptom go away.** + *Why:* "It is not a fix if you didn't have evidence of the change fixing something." See revert chain `9cdbf1b23`, `35aad2f2e`, `e3b90b7351` — fixes that masked rather than solved, then had to be reverted. + +6. **Don't bump a dependency speculatively.** Confirm the conflict reproduces locally and the new version actually resolves it. + *Why:* `cf659f0d0`, `ef6a303406`, `38d142a72`, `9029c4b61` — repeated dep-conflict cleanup. + +7. **Don't invent model IDs, MCP tool names, or API surface.** Read the registry, the batch dispatcher, and `models.py` first. + *Why:* `9f1402ed9` (`remove fictional gpt-5.3 ids`), `cecc4a6c2` (`expose layout tool as layout_flow to match batch dispatch`). + +8. **Don't use raw `langflow run` / `python` when a `uv` command exists.** Always `uv run`. For lfx tests specifically: `uv sync` inside `src/lfx` (not `src/lfx/src/lfx`) to avoid pulling in langflow. + *Why:* lfx must be testable without langflow installed; mixing them masks dependency leaks. + +9. **Don't add a database migration without running `make alembic-upgrade` end to end** and `uv run pytest src/backend/tests/unit/test_database.py` sequentially. + *Why:* `d8b9cc38f`, `c30150a2d`, `6585fe661`. `test_database.py` may pass in batch and fail individually — agents have stopped running it. + +10. **Don't claim a race condition is fixed without an integration test that reproduced it.** Agent double-execution and queue leaks keep coming back. + *Why:* `8a993ac90`, `42e84d0fd`, `749865b31`, `f30b291f8`. + +11. **Don't add `tool_mode=True` to outputs that confuse agents** (e.g., dataframe surfaces). + *Why:* `cbc54108` (`remove tool_mode=True for as_dataframe`), `35aad2f2e` (revert of the original disable). Output tool exposure is a user contract — don't toggle it back and forth. + +12. **Don't widen the scope of a PR.** Closely related follow-ups belong in the existing open PR, not a new stacked PR. + +13. **Don't ship without running the tests locally.** Typing the test command in the chat is not running it. + +14. **Don't make incremental "wip" commits.** One coherent commit per logical change, after everything is done and tested. + +15. **Don't push or open PRs without explicit user confirmation.** Pushing during active CI iteration on an already-open PR is fine; opening a new PR or pushing new branches is not. + +## Things that look like a fix but aren't + +- Adding `try/except Exception: pass` around a flaky call. +- Adding a `time.sleep` to dodge a race instead of awaiting a condition. +- Bumping a dependency version "just in case." +- Marking a failing test `@pytest.mark.skip` without a linked issue. +- Switching `# type: ignore` instead of fixing the type. +- Reverting symptoms (a UI flag, a tool flag) instead of finding the root. +- "Fixing" a test by changing its assertion to match wrong output. + +## Before claiming done + +- [ ] `make format_backend` and `make lint` clean. +- [ ] Tests for the changed surface ran and passed locally — not just typed out. +- [ ] If a component field/output changed: starter projects regenerated and `component_index.json` rebuilt. +- [ ] If a class/module renamed: old class kept with `legacy=True` + `replacement=[...]`; `file_names_mapping` updated for every supported version. +- [ ] No incremental "wip" commits. One coherent commit per logical change. +- [ ] No "Generated with Claude Code" / `Co-Authored-By: Claude` trailers. +- [ ] No `--no-verify` unless explicitly authorized. +- [ ] PR not pushed and PR not opened until the user explicitly asks. +- [ ] PR description has no test-plan checklist, no Jira links/IDs. + +## Where to look for context — don't invent it + +- **Starter projects:** `src/backend/base/langflow/initial_setup/starter_projects/`. Any field/output change must regenerate these. +- **Component index:** `src/lfx/src/lfx/_assets/component_index.json` (rebuilt via the index sync workflow added in `9dad1965c`). +- **Output type migrations:** `src/backend/base/langflow/initial_setup/setup.py` `type_migrations` map — handles renames of *output type strings* (e.g., `Data` → `JSON`). It does NOT remap component class names; for class renames use `legacy=True` + `replacement=[...]`. +- **Version mapping for component tests:** `src/backend/tests/constants.py::SUPPORTED_VERSIONS` and each test's `file_names_mapping`. +- **Release notes / changelog:** `docs/docs/Support/release-notes/` — check before claiming behavior is "new"; many features predate the current task. +- **MCP tool catalog:** dispatched via the batch tool — names must match (`cecc4a6c2` is the canonical "I guessed the tool name" failure). +- **Models / providers:** real model IDs come from the provider's listing endpoint or our adapter, never from training-data memory (`9f1402ed9`). +- **Migrations:** `src/backend/base/langflow/alembic/versions/` — always read the latest two before adding a new one. diff --git a/docs/agents/ARCHITECTURE.md b/docs/agents/ARCHITECTURE.md new file mode 100644 index 0000000000..3c02fb60a4 --- /dev/null +++ b/docs/agents/ARCHITECTURE.md @@ -0,0 +1,81 @@ +# Architecture Boundaries + +Langflow is three Python packages and one frontend, layered with one-way dependencies. Most "off-narrative" code is a boundary violation. Read this before adding a new file. + +## Package dependency graph (one-way only) + +``` +frontend (TS) ──HTTP──▶ langflow (api routers, integrations, distribution) + │ + ▼ may import + langflow-base (services, graph, db, alembic) + │ + ▼ may import + lfx (executor core, base primitives, components) + │ + ▼ may import + langchain-core, pydantic, third-party SDKs +``` + +### Dependency rules + +- **`lfx` MUST NOT import `langflow.*` or `langflow-base.*`.** If lfx code needs a service (auth, db, flow lookup), define an interface inside `lfx` and inject the implementation from `langflow`. The repo currently has ~13 upward `from langflow.*` imports inside `src/lfx/src/lfx/components/...` (auth, db, helpers) — these are **known violations**. Do not add more; prefer fixing them. +- **`langflow-base` MAY import `lfx`.** It MUST NOT import vendor-specific component modules from `langflow.components.`. +- **`frontend` talks to `langflow` only via HTTP/WebSocket.** No shared filesystem state. + +## "Where does this code go?" decision tree + +Walk top-down. Stop at the first match. + +1. Is it framework-agnostic flow execution, base component classes, or `Component` primitives? + → `src/lfx/src/lfx/` (`base/` for shared primitives, `components/` for built-ins shipped with lfx). +2. Is it a FastAPI route, auth, db model, alembic migration, or a lifecycle-managed singleton? + → `src/backend/base/langflow/` (`api/`, `services/X/`, `alembic/versions/`). +3. Is it a vendor integration (OpenAI, Pinecone, Notion, …) — a `Component` subclass that wraps a third-party SDK? + → `src/lfx/src/lfx/components//` and update its `__init__.py` alphabetically. Never rename the class. +4. Is it UI, state, or icons? + → `src/frontend/src/`. If it consumes a new API field, also update `src/frontend/src/types/`. +5. Is it CLI behavior for `lfx run` / `lfx serve`? + → `src/lfx/src/lfx/cli/`. +6. Is it a SQLAlchemy/SQLModel model change? + → `services/database/models/` AND `make alembic-revision message="..."` AND apply with `make alembic-upgrade`. +7. Is it a flow JSON schema change? + → STOP. Existing saved flows must keep loading. Add a version mapping; do not mutate the existing shape. See [CONTRACTS.md](./CONTRACTS.md). +8. Is it shared by both `lfx` and `langflow-base`? + → `src/lfx/src/lfx/base/`, never `langflow/base/`. + +## Dependency direction — bad/good examples + +- **Bad:** `from langflow.services.deps import session_scope` inside `src/lfx/...`. + **Good:** Define `lfx.interfaces.SessionProvider`, accept it as a constructor arg; `langflow` wires the concrete `session_scope` at startup. +- **Bad:** `from langflow.components.openai import ...` inside `langflow-base` core (`api/`, `services/`, `graph/`). + **Good:** Components are loaded dynamically via the component registry; core code references `Component` only. +- **Bad:** A new `MyHelperService` that's just functions. + **Good:** Utility functions go in `langflow/helpers/` or `lfx/utils/`. A service inherits from `services/base.Service` and is registered via `services/factory.py`. + +## API change protocol + +- **`api/v1/`** is the live, stable surface (~25 routers). Existing v1 endpoints MUST stay backwards-compatible: only additive fields, never rename or remove. +- **`api/v2/`** is the **active redesign surface** (`files`, `mcp`, `registration`, `workflow`) — both are mounted at runtime in `api/router.py`. v2 is **not** "future"; the old cursor rule was wrong. +- Add a new endpoint to v2 only if it (a) replaces a v1 endpoint with a breaking shape change, or (b) belongs to one of the four v2 domains. Otherwise extend v1 additively. +- A breaking change to a v1 endpoint is forbidden. Add a v2 sibling and leave v1 in place. + +## Cross-cutting change protocol + +A change that touches a request/response shape MUST update three places in the same PR: + +1. The pydantic model in `langflow/api/v{1,2}/schemas.py` (or the route's local schema). +2. The TypeScript type in `src/frontend/src/types/` consumed by the affected page/store. There is no OpenAPI generator — the types are hand-maintained, so the frontend silently breaks at runtime if you skip this. +3. If the field is persisted: a new alembic revision (`make alembic-revision message=...`) AND a flow-JSON version mapping if the shape lives inside saved flows. + +If you cannot do all three in one PR, do not start. + +## Service vs utility vs component + +- **Service** (`services//`): lifecycle-managed singleton, inherits `services.base.Service`, registered through `services/factory.py`, accessed via `services/deps.py`. Use when the thing has state, startup/shutdown, or shared connections (db, cache, queue). +- **Utility** (`helpers/`, `utils/`, or `lfx/utils/`): pure or near-pure functions. Use when there is no shared state and no lifecycle. +- **Component** (`src/lfx/src/lfx/components//`): user-visible node in the graph, subclass of `Component`, with `display_name`, `inputs`, `outputs`. Use only when the user must wire it on the canvas. Do not add a Component to expose internal plumbing. + +## `lfx/base/` vs `langflow/base/` + +Both exist. Both have `agents/`, `data/`, `models/`, `prompts/`. New shared primitives go in **`src/lfx/src/lfx/base/`**. The `langflow/base/` tree is legacy; do not add to it. diff --git a/docs/agents/COMPONENTS.md b/docs/agents/COMPONENTS.md new file mode 100644 index 0000000000..729c681535 --- /dev/null +++ b/docs/agents/COMPONENTS.md @@ -0,0 +1,138 @@ +# Component Development + +Components are the unit of work in Langflow. They render as nodes on the canvas, persist into flow JSON, and become tools for Agents. Get the contract right and the rest of the system follows; get it wrong and you orphan every saved flow that referenced your component. + +Components live in **`src/lfx/src/lfx/components//`**. The mirror tree under `src/backend/base/langflow/components/` is legacy stubs — do not add files there. + +## Before you add a component (decision checklist) + +Stop and check, in order. If any answer is "yes," do not create a new component. + +1. **Does one already exist?** Search: + ```bash + rg -l 'display_name = ".*.*"' src/lfx/src/lfx/components/ + ``` + and check the category folder. The Calculator regret (two of them, see `tools/calculator.py` `legacy = True, replacement = ["helpers.CalculatorComponent"]`) is what happens when this step is skipped. +2. **Is this a thin wrapper around an existing tool/SDK that an Agent could call directly via `tool_mode=True`?** If yes, add `tool_mode=True` to the relevant input on the existing component instead of building a new one. +3. **Does it belong in a vendor bundle** (e.g., `openai/`, `anthropic/`, `datastax/`) rather than in generic `tools/` or `helpers/`? Vendor logic goes in vendor folders so bundles can ship/version independently. +4. **Is this an lfx-runtime concern** (graph execution, schema, IO primitives) or a **Langflow-app concern** (auth, DB, tracing)? Components are lfx; never import `langflow.services.*` from a component. +5. **Does an existing base class cover this category?** Use it: + - LLMs → `LCModelComponent` (see `openai/openai_chat_model.py`) + - Tools → `LCToolComponent` (see `tools/calculator.py`) + - Vector stores → `LCVectorStoreComponent` + `@check_cached_vector_store` (see `vectorstores/local_db.py`) + - Chat IO → `ChatComponent` (see `input_output/chat.py`) + +## Scope rules (one component, one job) + +- One job per component. If the description has " and " in it, split it. +- **Inputs budget:** aim for ≤8 visible inputs; push the rest behind `advanced=True`. If you need a mode switch (Ingest/Retrieve etc.), use `TabInput` + `update_build_config` to hide irrelevant fields — see `vectorstores/local_db.py`. +- **Outputs:** one primary `Output(method=...)` is the default. Add more only if downstream nodes genuinely need different shapes (Message vs DataFrame vs Data). Don't add an output you don't use. +- Mark inputs an Agent should be able to fill with `tool_mode=True` (e.g., `local_db.py`) — this is how a component becomes an agent tool. + +## Breaking-change list (locked once shipped) + +Saved flows reference components by string identifiers. Once a component is merged, the following are **frozen** — change them and existing user flows break silently: + +- The **class name** (already in our rules). +- The **`name = "..."` class attribute**. **This is the flow-JSON identifier**, not the class name. See `openai_chat_model.py`, `chat.py`. +- Each input **`name=...`**. Renaming `input_value` → `prompt` orphans every edge pointing at it. +- Each output **`name=...`** and its declared return type. Downstream nodes match on both. +- **Default values** and default behavior of existing inputs (a flow saved with the default re-loads with the new default). + +To remove or rework a component, **do not edit it in place**. Add the replacement under the right category, then on the old one set: + +```python +legacy = True +replacement = ["."] +``` + +(see `tools/calculator.py`, `flow_controls/sub_flow.py`). The UI shows "Updates Available" and migrates users; the old class stays importable. + +See [CONTRACTS.md](./CONTRACTS.md) for the full user-facing surface this protects. + +## Conventions agents miss + +These appear all over the codebase but rarely in old docs. + +- **`name`** (class attr): flow-JSON identifier. Always set it explicitly; do not rely on `__class__.__name__`. Example: `chat.py` `name = "ChatInput"`. +- **`legacy = True` + `replacement = [...]`**: deprecation pair. Always together. Example: `tools/calculator.py`. +- **`tool_mode=True`** on an input: exposes the component as an Agent tool with that input as the tool argument. Example: `vectorstores/local_db.py`. +- **`real_time_refresh=True` + `update_build_config(self, build_config, value, name)`**: dynamic form. Use for mode switches and dependent-field hide/show. Examples: `openai/openai_chat_model.py`, `vectorstores/local_db.py`. +- **`metadata = {"keywords": [...]}`**: extra search terms for the component picker. Example: `data_source/sql_executor.py`. +- **`minimized = True`**: render collapsed by default. Example: `input_output/chat.py`. +- **`documentation = "https://docs.langflow.org/..."`**: deep-link from the node UI. Example: `input_output/chat.py`. + +## Placement rules + +- **Vendor-specific code** → vendor folder (`openai/`, `anthropic/`, `datastax/`, `cohere/`, …). Not `tools/`, not `models/`. +- **Generic, vendor-agnostic helpers** → `helpers/`, `processing/`, `logic/`, `flow_controls/`. +- **IO primitives** → `input_output/`. +- Add the import to the category `__init__.py` in **alphabetical order**. +- **Do not invent a new top-level category.** If you think you need one, that is a signal to discuss with the team first — categories are visible in the UI sidebar and are part of the product surface. + +## Icons + +Every component needs an icon. Use a Lucide icon when one fits; create a custom SVG only for vendor logos. + +### Lucide icon (default) + +```python +icon = "calculator" # any Lucide icon name, lowercase +``` + +See https://lucide.dev/icons for the catalog. + +### Custom vendor icon + +For brand logos you need a frontend SVG component. The Python `icon` string and the frontend mapping key must match **exactly** (case-sensitive). + +1. **Python:** set `icon = "AstraDB"` on the component. +2. **Frontend SVG component** at `src/frontend/src/icons/AstraDB/AstraDB.jsx`: + ```jsx + const AstraSVG = (props) => ( + + + + ); + ``` +3. **Wrapper** at `src/frontend/src/icons/AstraDB/index.tsx`: + ```tsx + import React, { forwardRef } from "react"; + import AstraSVG from "./AstraDB"; + + export const AstraDBIcon = forwardRef>( + (props, ref) => + ); + ``` +4. **Lazy import** in `src/frontend/src/icons/lazyIconImports.ts`: + ```ts + AstraDB: () => + import("@/icons/AstraDB").then((mod) => ({ default: mod.AstraDBIcon })), + ``` +5. Verify in the UI in **both light and dark mode**. + +### Icon checklist + +- [ ] Python `icon = "..."` set. +- [ ] If custom: SVG component with `isDark` prop, wrapper with `forwardRef`, entry in `lazyIconImports.ts`. +- [ ] Light and dark mode both verified. + +## Component testing + +See [TESTING.md](./TESTING.md) for the full testing contract. Quick reference: + +- Inherit from `ComponentTestBaseWithClient` (needs API) or `ComponentTestBaseWithoutClient` (pure logic). +- Provide three fixtures: `component_class`, `default_kwargs`, `file_names_mapping`. +- Use `MockLanguageModel` for pure-logic LLM paths; use `@pytest.mark.api_key_required` for real-API tests. +- For graph behavior, use the Graph test pattern: build, `.set()`, `async_start`, validate. Do not poke graph internals. + +## Canonical examples + +When in doubt, read these files before starting: + +- LLM with dynamic provider switching: `src/lfx/src/lfx/components/openai/openai_chat_model.py` +- Tool with `tool_mode` and legacy/replacement: `src/lfx/src/lfx/components/tools/calculator.py` +- Vector store with cache + tab inputs: `src/lfx/src/lfx/components/vectorstores/local_db.py` +- Chat input with `minimized`: `src/lfx/src/lfx/components/input_output/chat.py` +- Component with searchable metadata: `src/lfx/src/lfx/components/data_source/sql_executor.py` +- Legacy + replacement pattern: `src/lfx/src/lfx/components/flow_controls/sub_flow.py` diff --git a/docs/agents/CONTRACTS.md b/docs/agents/CONTRACTS.md new file mode 100644 index 0000000000..f29bfd3439 --- /dev/null +++ b/docs/agents/CONTRACTS.md @@ -0,0 +1,57 @@ +# User-Facing Contracts + +These are the surfaces users depend on. Breaking them silently is the most common way an agent ships work that "doesn't connect to the story." Read this before changing anything below. + +## The contract surface + +| # | Contract | Source of truth | Rule | +|---|----------|-----------------|------| +| 1 | Component class `name` attribute | `class XComponent: name = "X"` | NEVER rename. Used to match nodes in saved flow JSON. | +| 2 | Component class identifier (Python class name) | `class XComponent` | NEVER rename. Combined with `name` for resolution. | +| 3 | Component file path + module | `src/lfx/src/lfx/components//.py` | Renames are breaking. The supported workflow is to add the new component alongside the old one and set `legacy = True` + `replacement = ["."]` on the old class. Update every component's `file_names_mapping` in tests for past `SUPPORTED_VERSIONS` (`src/backend/tests/constants.py`). Regenerate starter projects and rebuild the component index. | +| 4 | Input `name=` and `Output(name=...)` on every component | The component file itself | NEVER rename or remove. Saved flows reference these as keys. Adding new optional inputs is safe; removing or renaming breaks every saved flow that used them. | +| 5 | Output order and `Output.types` | Component `outputs = [...]` list | Reordering changes default selection in old flows. Tightening a type is a breaking change; widening is safe. | +| 6 | Default values for inputs | `default=` / `value=` in input spec | Changing a default silently changes behavior for users who relied on the default. Treat as a breaking change unless the old default was a bug. | +| 7 | Flow JSON schema | `src/backend/base/langflow/initial_setup/starter_projects/*.json` (canonical examples) | Top-level `data.nodes[*].data.node` shape and `data.edges` shape are public. New fields must be optional with defaults. | +| 8 | Public REST API | `docs/docs/API-Reference/api-flows-run.mdx`, `api-build.mdx`, `api-files.mdx`, `api-projects.mdx`, `api-logs.mdx`, `api-monitor.mdx`, `api-users.mdx`. Endpoints with `include_in_schema=False` are internal. | Documented endpoints are stable. `POST /api/v1/run/{flow_id_or_name}` and `POST /api/v1/webhook/{flow_id_or_name}` are user contracts — payload shape and status codes are frozen. | +| 9 | MCP tool exposure | `src/backend/base/langflow/api/v1/mcp.py`, `mcp_projects.py`. Tool-mode toggled by `Output.tool_mode` / outputs named `component_as_tool`. | Removing `tool_mode=True` from an existing component output, or changing its name, breaks every Agent flow using it as a tool. | +| 10 | `Message` / `Data` / `DataFrame` schema | `src/lfx/src/lfx/schema/message.py` (`text`, `sender`, `sender_name`, `session_id`, `flow_id`, `timestamp`, `properties`, `content_blocks`, `category`, `files`, `error`, `edit`, `duration`, `session_metadata`) | Inter-component wire format. Add fields with defaults only. Renaming or retyping any listed field breaks every running flow. | +| 11 | Environment variables | `LANGFLOW_*` (server) defined in `src/backend/base/langflow/services/settings/base.py` and `feature_flags.py`. `LFX_*` (executor) defined in `src/lfx/src/lfx/services/settings/base.py`, except a few read directly via `os.getenv` (e.g., `LFX_DEV` in `src/lfx/src/lfx/interface/components.py`). | Public deployment contract. Renaming requires deprecation cycle reading both names. | +| 12 | Database schema | `src/backend/base/langflow/services/database/models/` + `alembic/versions/`. | NEVER edit a model without `make alembic-revision`. Never edit a past migration. Custom-component Python source is stored in user DBs — refactoring an import path used by `from langflow.X import Y` breaks loading those rows. | +| 13 | Starter project JSON | `src/backend/base/langflow/initial_setup/starter_projects/*.json` | Each references real components by `name`/`type`. Renaming a component, removing an input, or changing an output type breaks loading. After ANY component change, re-load the affected starter project. | +| 14 | Webhook payload shape | `POST /api/v1/webhook/{flow_id_or_name}` | External systems POST here. Response status (202 Accepted) and the `dict` body shape are frozen. | +| 15 | Component index | `src/lfx/src/lfx/_assets/component_index.json` | Generated artifact consumed by the frontend. Any field/output addition requires regeneration; CI enforces this on label add. | + +## Before-you-change matrix + +| If you are about to... | Check / update | +|---|---| +| Rename a component file | Add the new file alongside; set `legacy = True` + `replacement = [...]` on the old class; update every test's `file_names_mapping`; grep `starter_projects/*.json` for the old type | +| Rename an input `name=` | Don't. Add a new input alongside and deprecate the old via `legacy=True` on the component if necessary; grep `starter_projects/*.json` for the old name | +| Add or rename an output | Regenerate starter projects; rebuild component index | +| Change a default value | Treat as breaking. Grep starter projects + tests for reliance | +| Remove `tool_mode=True` from an output | Search agent flows / starter projects using it as a tool; this is a user-visible regression | +| Add a `Message` field | Must be `Optional` with default; never reorder existing | +| Add a REST endpoint | If user-facing, add to `docs/docs/API-Reference/`; if internal, set `include_in_schema=False` | +| Modify a DB model | `make alembic-revision message="..."`; never edit past revisions | +| Change a `LANGFLOW_*` / `LFX_*` env var | Read old name as fallback for at least one minor version; document in release notes | +| Change a request/response schema | Update pydantic schema + `src/frontend/src/types/` + alembic if persisted, all in one PR | + +## Breaking changes that look harmless + +These all look like cleanup. They are user-visible regressions. + +- **Renaming `input_value` → `text`** on a component: 100% of saved flows referencing that input lose their wiring. +- **Reordering `outputs = [a, b]` to `[b, a]`**: old flows with the default selection now route from the wrong output. +- **Tightening `Output(types=["Message", "Data"])` → `["Message"]`**: edges that resolved as `Data` go invalid on load. +- **Changing a `default="gpt-4o-mini"` to `default="gpt-5"`**: silently re-bills users. +- **Moving `langflow/components/foo/bar.py` → `langflow/components/foo2/bar.py`**: custom components stored in user DBs that `from langflow.components.foo.bar import ...` fail on next load. `file_names_mapping` test passes because it only validates listed historical versions, not user code. +- **Dropping `tool_mode=True` from a vector store's `as_dataframe`**: every Agent that called it as a tool now sees the tool disappear. +- **Adding a required field to `Message`**: every queued message in a running deployment fails to deserialize on next read. +- **Renaming a starter project file**: deep links from docs and tutorials 404. + +## Why this matters + +Langflow flows are **persisted user artifacts** running in production. The system that loads them is forgiving by design: it tolerates new fields, falls back on missing ones, applies type migrations on load. That tolerance is paid for by every contract in the table above. Break one and the system can no longer route around it — the flow stops working. + +Treat this file as a checklist. If your change touches any row, the corresponding rule applies; no exceptions without an explicit deprecation plan. diff --git a/docs/agents/PHILOSOPHY.md b/docs/agents/PHILOSOPHY.md new file mode 100644 index 0000000000..b06b1b9166 --- /dev/null +++ b/docs/agents/PHILOSOPHY.md @@ -0,0 +1,33 @@ +# Project Philosophy + +Read this file before scoping any non-trivial work. Most off-narrative work comes from skipping it. + +Langflow is a **visual flow builder first**. Every change should make sense to someone whose only interface is dragging nodes onto a canvas. Use these principles to scope work; if a proposed change fails one of them, stop and reconsider. + +## Tenets + +1. **Flows are user artifacts, not implementation details.** Flow JSON lives in users' databases and runs in production. Backwards compatibility for components is non-negotiable: never rename a class name, `name` attribute, input name, or output name; never remove an input or output; never tighten an output type; never remove methods from base classes like `LCModelComponent`. To change a component, add the new one alongside, set `legacy=True` + `replacement=[...]` on the old, and update `file_names_mapping` in tests so saved flows still load. See [CONTRACTS.md](./CONTRACTS.md) for the full surface. + +2. **Every backend feature must land on the canvas.** If a capability cannot be expressed as a component (or a property of one) that a non-Python user can wire up, it is an SDK feature and belongs in `lfx`, not `langflow-base`. Backend changes that have no visual surface are almost always off-narrative. + +3. **Components are the unit of work, not endpoints or services.** Before adding a route, store, or service, ask: which component does this serve? If the answer is "none yet," the route is premature. New REST endpoints without a component or UI consumer are off-narrative. + +4. **`lfx` is the runtime, `langflow-base` is the platform, `langflow` is the distribution.** Components and the graph engine live in `lfx` (`src/lfx/src/lfx/components/`). API, auth, persistence, and multi-user concerns live in `langflow-base`. The `langflow` package is the integration that ships everything together. New code goes in the lowest layer that can host it. Boundaries are enforced one-way: `langflow` → `langflow-base` → `lfx`. See [ARCHITECTURE.md](./ARCHITECTURE.md). + +5. **Don't add a config flag for something a builder-user would set on a node.** If a setting affects flow behavior, it's a component input. If it affects deployment, it's an env var. Hidden global flags that change component semantics break the visible-data-flow contract. + +6. **Visible data flow beats clever magic.** Implicit context, hidden globals, and side-channel state make flows unreadable on the canvas. Pass data through inputs and outputs. If you find yourself reaching for a global, you're probably building something that doesn't belong in a node. + +7. **Composition over capability.** Prefer adding small, single-purpose components users can wire together over one large component with many modes. The `If-Else` / `Current Date` style (one job, clear name, obvious icon) is the target shape. + +8. **Every component needs `display_name`, `description`, `icon`, and a sensible category.** A component that doesn't render legibly in the sidebar shouldn't ship. The icon is part of the API, not decoration — pick a Lucide icon that matches the verb. + +9. **The Playground is the test harness builder-users see.** A component is "done" when it works end-to-end in a flow on the canvas, not when its unit test passes. Use the Graph test pattern (build, `.set()`, `async_start`, validate) before claiming a feature works. + +10. **Two audiences, one product: visual builders and Python devs.** When their needs conflict, the visual builder wins for `langflow-base` features and the Python dev wins for `lfx` SDK features. Don't compromise the canvas to make the SDK prettier, and don't compromise the SDK to make the canvas easier. + +11. **It is not a fix if you didn't have evidence of the change fixing something.** Adding error handling, retries, type widening, or skipping a flaky test does not constitute a fix. Reproduce the failure, demonstrate the fix removes it, then ship. See [ANTI-PATTERNS.md](./ANTI-PATTERNS.md). + +## How to apply + +When scoping a task, walk through the tenets and name the ones the work serves. If a change fails tenet 1, 2, or 3, stop and surface the conflict before writing code. If you can't tell which tenet a change serves, it's probably off-narrative — ask. diff --git a/docs/agents/TESTING.md b/docs/agents/TESTING.md new file mode 100644 index 0000000000..9f5a9c4eed --- /dev/null +++ b/docs/agents/TESTING.md @@ -0,0 +1,163 @@ +# Testing + +Conventions for backend tests. Frontend testing follows the standard Jest/Playwright patterns documented in `src/frontend/`. + +## Project policy: avoid mocking + +Prefer real integrations. The pattern of "mocked test passes, production fails" has cost us multiple release cycles — see [ANTI-PATTERNS.md](./ANTI-PATTERNS.md) for the relevant commit history. Use mocks only when: + +- The dependency is an LLM and the test exercises pure logic → use `MockLanguageModel` from `tests/unit/mock_language_model.py`. +- The dependency is genuinely unreliable and orthogonal to what's being tested. + +Otherwise: hit the real thing, mark the test with `@pytest.mark.api_key_required` if it needs credentials, and let CI gate it. + +## Built-in fixtures + +### `client` (FastAPI test client) + +Defined in `src/backend/tests/conftest.py`. Async `httpx.AsyncClient` connected to the full app via `ASGITransport` + `LifespanManager`. Auto-configured with in-memory SQLite and mocked env vars. Skip with `@pytest.mark.noclient`. + +```python +async def test_login_endpoint(client): + response = await client.post("api/v1/login", data={"username": "foo", "password": "bar"}) + assert response.status_code == 200 +``` + +For authenticated routes, also use the `logged_in_headers` fixture. + +## Component test base classes + +Located in `src/backend/tests/base.py`. + +| Base class | Creates `client`? | Use for | +|---|---|---| +| `ComponentTestBase` | No | Component version testing core logic | +| `ComponentTestBaseWithClient` | Yes | Components that hit backend services during `run()` | +| `ComponentTestBaseWithoutClient` | No | Pure-logic components | + +### Required fixtures + +Every subclass provides three fixtures: + +1. **`component_class`** — the component class under test. +2. **`default_kwargs`** — dict of kwargs to instantiate the component (can be empty). +3. **`file_names_mapping`** — list of `VersionComponentMapping` entries mapping each historical Langflow version (from `src/backend/tests/constants.py::SUPPORTED_VERSIONS`) to module/file names. Use `DID_NOT_EXIST` for versions before the component was added. + +```python +from tests.base import ComponentTestBaseWithClient, VersionComponentMapping, DID_NOT_EXIST +from langflow.components.my_namespace import MyComponent + +class TestMyComponent(ComponentTestBaseWithClient): + @pytest.fixture + def component_class(self): + return MyComponent + + @pytest.fixture + def default_kwargs(self): + return {"foo": "bar"} + + @pytest.fixture + def file_names_mapping(self): + return [ + VersionComponentMapping(version="1.1.1", module="my_module", file_name="my_component.py"), + VersionComponentMapping(version="1.0.19", module="my_module", file_name=DID_NOT_EXIST), + ] +``` + +The base class auto-provides: + +- `test_latest_version` — instantiates and asserts `run()` doesn't return `None`. +- `test_all_versions_have_a_file_name_defined` — ensures mapping completeness vs `SUPPORTED_VERSIONS`. +- `test_component_versions` (parameterized) — builds the component from source for each supported version and asserts execution. + +If you rename or move a component file, you **must** update `file_names_mapping` for every supported version, or saved flows on those versions will fail to load. See [CONTRACTS.md](./CONTRACTS.md) row 3. + +## Graph testing pattern + +The canonical pattern for tests that exercise the graph engine: + +1. Build the graph with connected components. +2. Connect them via `.set()` calls. +3. Call `async_start` and iterate over the results. +4. Validate the results. + +Don't poke graph internals. If a test needs to reach into private state, the test is wrong or the API is wrong — fix the right one. + +## Async patterns + +```python +@pytest.mark.asyncio +async def test_async_component(): + result = await component.async_method() + assert result is not None +``` + +**Awaiting conditions, not sleeping:** never use `time.sleep` or `asyncio.sleep` to mask a race. Wait on a condition (`asyncio.wait_for`, an event, a queue read with timeout). Sleep-based tests are flaky by construction. + +## Pytest markers + +- `@pytest.mark.api_key_required` — needs an external API key; CI skips when absent. +- `@pytest.mark.no_blockbuster` — skip blockbuster plugin. +- `@pytest.mark.noclient` — skip the `client` fixture. +- `@pytest.mark.asyncio` — async test (also `pytest-asyncio` auto-mode in some configs). + +## Database tests + +`test_database.py` may fail in batch and pass individually. If you touch DB models or migrations, run it sequentially as part of your verification: + +```bash +uv run pytest src/backend/tests/unit/test_database.py +``` + +Never edit a past alembic migration. Run `make alembic-upgrade` end-to-end before claiming a migration works. + +## API endpoint tests + +```python +async def test_flows_endpoint(client, logged_in_headers): + flow_data = {"name": "Test", "data": {"nodes": [], "edges": []}} + response = await client.post("api/v1/flows/", json=flow_data, headers=logged_in_headers) + assert response.status_code == 201 +``` + +For event-stream endpoints, consume the NDJSON stream and validate event order: + +```python +async for line in response.aiter_lines(): + if not line: + continue + parsed = json.loads(line) + # First event should be vertices_sorted; last should be end. +``` + +## Flow testing with starter JSON + +Use `tests/unit/build_utils.py` helpers: + +```python +from tests.unit.build_utils import create_flow, build_flow, get_build_events + +flow_id = await create_flow(client, json_flow, logged_in_headers) +build_response = await build_flow(client, flow_id, logged_in_headers) +events_response = await get_build_events(client, job_id, logged_in_headers) +``` + +## Running tests + +```bash +make unit_tests # All backend unit tests, parallel +make unit_tests async=false # Sequential +uv run pytest path/to/test.py # Single file +uv run pytest path/to/test.py::test_name # Single test + +# lfx tests specifically — must be run after `uv sync` inside src/lfx +cd src/lfx && uv sync && uv run pytest +``` + +## Verification checklist before claiming "tests pass" + +- [ ] You actually ran the command, not just composed it. +- [ ] You ran `test_database.py` sequentially if you touched DB code. +- [ ] You ran the specific test file for any component you changed. +- [ ] No skipped tests without a linked issue. +- [ ] No mocks added at the wrong boundary. diff --git a/scripts/ci/lfx_nightly_tag.py b/scripts/ci/lfx_nightly_tag.py index d54c6dda5b..ab0bfe538e 100644 --- a/scripts/ci/lfx_nightly_tag.py +++ b/scripts/ci/lfx_nightly_tag.py @@ -1,70 +1,75 @@ -"""Script to generate nightly tags for LFX package.""" +"""Generate the nightly tag for the canonical ``lfx`` package. + +The nightly publishes ``lfx==.devN`` to the canonical ``lfx`` PyPI project (not a separate +``lfx-nightly`` distribution), so the dev counter is computed against ``lfx``'s own release history. +```` is the in-development version from +``src/lfx/pyproject.toml`` (the latest ``release-*`` branch the nightly builds from) and ``N`` is +``max(existing same-base devN) + 1``. + +Only ``.devN`` releases whose ``base_version`` matches contribute; stable finals (e.g. ``1.10.0``) +are ignored. A 404 (no releases yet) yields ``dev0``; any other lookup failure is fatal (fail +closed) so a transient error cannot regenerate an already-published version. See +``src/bundles/NIGHTLY.md``. +""" + +from pathlib import Path import packaging.version import requests +import tomllib from packaging.version import Version PYPI_LFX_URL = "https://pypi.org/pypi/lfx/json" -PYPI_LFX_NIGHTLY_URL = "https://pypi.org/pypi/lfx-nightly/json" -def get_latest_published_version(*, is_nightly: bool) -> Version: - url = PYPI_LFX_NIGHTLY_URL if is_nightly else PYPI_LFX_URL - - res = requests.get(url, timeout=10) - if res.status_code == requests.codes.not_found: - msg = "Package not found on PyPI" - raise requests.RequestException(msg) - - try: - version_str = res.json()["info"]["version"] - except (KeyError, ValueError) as e: - msg = "Got unexpected response from PyPI" - raise requests.RequestException(msg) from e - return Version(version_str) - - -def create_lfx_tag(): - # Since LFX has never been released, we'll use the version from pyproject.toml as base - from pathlib import Path - - import tomllib - - # Read version from pyproject.toml +def _lfx_base_version() -> str: + """Return the base_version (e.g. "1.11.0") from src/lfx/pyproject.toml.""" lfx_pyproject_path = Path(__file__).parent.parent.parent / "src" / "lfx" / "pyproject.toml" pyproject_data = tomllib.loads(lfx_pyproject_path.read_text()) + return Version(pyproject_data["project"]["version"]).base_version - current_version_str = pyproject_data["project"]["version"] - current_version = Version(current_version_str) +def _dev_numbers(url: str, base_version: str) -> list[int]: + """Dev numbers of every release at ``url`` whose base_version matches ``base_version``. + + A 404 means the package has no releases yet and returns an empty list. Every other failure -- + a network error, a non-404 HTTP status, or a malformed 200 -- is fatal and raises, so the + nightly job aborts BEFORE mutating tags rather than regenerating an already-published version. + """ + res = requests.get(url, timeout=10) + if res.status_code == requests.codes.not_found: + return [] + res.raise_for_status() try: - current_nightly_version = get_latest_published_version(is_nightly=True) - nightly_base_version = current_nightly_version.base_version - except (requests.RequestException, KeyError, ValueError): - # If LFX nightly doesn't exist on PyPI yet, this is the first nightly - current_nightly_version = None - nightly_base_version = None + releases = res.json()["releases"] + except (ValueError, KeyError) as e: + msg = f"Unexpected response from {url!r}: missing 'releases' mapping" + raise RuntimeError(msg) from e - build_number = "0" - latest_base_version = current_version.base_version + dev_numbers: list[int] = [] + for version_str in releases: + try: + version = Version(version_str) + except packaging.version.InvalidVersion: + continue + if version.base_version == base_version and version.dev is not None: + dev_numbers.append(version.dev) + return dev_numbers - if current_nightly_version and latest_base_version == nightly_base_version: - # If the latest version is the same as the nightly version, increment the build number - build_number = str(current_nightly_version.dev + 1) - new_nightly_version = latest_base_version + ".dev" + build_number +def create_lfx_tag() -> str: + """Return the next ``lfx`` nightly tag (with a leading ``v``).""" + base_version = _lfx_base_version() + dev_numbers = _dev_numbers(PYPI_LFX_URL, base_version) + next_dev = max(dev_numbers) + 1 if dev_numbers else 0 - # Prepend "v" to the version, if DNE. - # This is an update to the nightly version format. - if not new_nightly_version.startswith("v"): - new_nightly_version = "v" + new_nightly_version + new_nightly_version = f"v{base_version}.dev{next_dev}" - # Verify if version is PEP440 compliant. + # Verify the version is PEP 440 compliant. packaging.version.Version(new_nightly_version) return new_nightly_version if __name__ == "__main__": - tag = create_lfx_tag() - print(tag) + print(create_lfx_tag()) diff --git a/scripts/ci/pypi_nightly_tag.py b/scripts/ci/pypi_nightly_tag.py index 0c8c206433..333fb68eba 100755 --- a/scripts/ci/pypi_nightly_tag.py +++ b/scripts/ci/pypi_nightly_tag.py @@ -1,8 +1,13 @@ #!/usr/bin/env python """Idea from https://github.com/streamlit/streamlit/blob/4841cf91f1c820a392441092390c4c04907f9944/scripts/pypi_nightly_create_tag.py. -`langflow-nightly` pins an EXACT dependency on `langflow-base-nightly[complete]==X.Y.Z.devN`. -For the latest published `langflow-nightly` to be installable, the base version it pins must +The nightly is published as canonical `.devN` pre-releases (e.g. `langflow==X.Y.Z.devN`), NOT +separate `*-nightly` distributions, so the dev counter is computed against the canonical +`langflow` / `langflow-base` PyPI histories (their `.devN` pre-releases; stable finals never +contribute). See `src/bundles/NIGHTLY.md`. + +`langflow` (the nightly pre-release) pins an EXACT dependency on `langflow-base[complete]==X.Y.Z.devN`. +For the latest published nightly `langflow` to be installable, the base version it pins must exist on PyPI. The two packages are therefore versioned in lockstep: they share a single dev number so that, in a single nightly run (publish order base -> main, gated), main's `devN` pin always references the base `devN` built and published in the same run. @@ -20,11 +25,13 @@ import packaging.version import requests from packaging.version import Version -PYPI_LANGFLOW_NIGHTLY_URL = "https://pypi.org/pypi/langflow-nightly/json" -PYPI_LANGFLOW_BASE_NIGHTLY_URL = "https://pypi.org/pypi/langflow-base-nightly/json" +# Count dev releases against the CANONICAL projects (not `*-nightly`), since the nightly is +# published as canonical `.devN` pre-releases of `langflow` / `langflow-base`. +PYPI_LANGFLOW_URL = "https://pypi.org/pypi/langflow/json" +PYPI_LANGFLOW_BASE_URL = "https://pypi.org/pypi/langflow-base/json" # main and base MUST share one dev number, so the shared number is derived from both packages. -PYPI_NIGHTLY_URLS = (PYPI_LANGFLOW_NIGHTLY_URL, PYPI_LANGFLOW_BASE_NIGHTLY_URL) +PYPI_CANONICAL_URLS = (PYPI_LANGFLOW_URL, PYPI_LANGFLOW_BASE_URL) ARGUMENT_NUMBER = 2 VALID_BUILD_TYPES = ("main", "base", "both") @@ -80,7 +87,7 @@ def _shared_nightly_version() -> str: """Compute the single dev number shared by langflow-nightly and langflow-base-nightly.""" base_version = _root_base_version() - dev_numbers = [dev for url in PYPI_NIGHTLY_URLS for dev in _all_dev_numbers(url, base_version)] + dev_numbers = [dev for url in PYPI_CANONICAL_URLS for dev in _all_dev_numbers(url, base_version)] # First-ever nightly for this base_version -> dev0. Otherwise max+1, so the result is # strictly ahead of BOTH packages' newest same-series dev release. diff --git a/scripts/ci/sdk_nightly_tag.py b/scripts/ci/sdk_nightly_tag.py index b3f0ae83f9..00f5a96c29 100644 --- a/scripts/ci/sdk_nightly_tag.py +++ b/scripts/ci/sdk_nightly_tag.py @@ -1,63 +1,69 @@ -"""Script to generate nightly tags for the SDK package.""" +"""Generate the nightly tag for the canonical ``langflow-sdk`` package. + +Mirrors ``lfx_nightly_tag.py`` but for the SDK -- the nightly publishes ``langflow-sdk==.devN`` +to the canonical ``langflow-sdk`` PyPI project, so the dev counter is computed against that +project's ``.devN`` history (stable finals never contribute). ```` comes from +``src/sdk/pyproject.toml``. See ``src/bundles/NIGHTLY.md``. +""" + +from pathlib import Path import packaging.version import requests +import tomllib from packaging.version import Version PYPI_SDK_URL = "https://pypi.org/pypi/langflow-sdk/json" -PYPI_SDK_NIGHTLY_URL = "https://pypi.org/pypi/langflow-sdk-nightly/json" -def get_latest_published_version(*, is_nightly: bool) -> Version: - url = PYPI_SDK_NIGHTLY_URL if is_nightly else PYPI_SDK_URL - - res = requests.get(url, timeout=10) - if res.status_code == requests.codes.not_found: - msg = "Package not found on PyPI" - raise requests.RequestException(msg) - - try: - version_str = res.json()["info"]["version"] - except (KeyError, ValueError) as e: - msg = "Got unexpected response from PyPI" - raise requests.RequestException(msg) from e - return Version(version_str) - - -def create_sdk_tag(): - from pathlib import Path - - import tomllib - +def _sdk_base_version() -> str: + """Return the base_version (e.g. "0.1.0") from src/sdk/pyproject.toml.""" sdk_pyproject_path = Path(__file__).parent.parent.parent / "src" / "sdk" / "pyproject.toml" pyproject_data = tomllib.loads(sdk_pyproject_path.read_text()) + return Version(pyproject_data["project"]["version"]).base_version - current_version_str = pyproject_data["project"]["version"] - current_version = Version(current_version_str) +def _dev_numbers(url: str, base_version: str) -> list[int]: + """Dev numbers of every release at ``url`` whose base_version matches ``base_version``. + + A 404 means the package has no releases yet and returns an empty list. Every other failure -- + a network error, a non-404 HTTP status, or a malformed 200 -- is fatal and raises, so the + nightly job aborts BEFORE mutating tags rather than regenerating an already-published version. + """ + res = requests.get(url, timeout=10) + if res.status_code == requests.codes.not_found: + return [] + res.raise_for_status() try: - current_nightly_version = get_latest_published_version(is_nightly=True) - nightly_base_version = current_nightly_version.base_version - except (requests.RequestException, KeyError, ValueError): - current_nightly_version = None - nightly_base_version = None + releases = res.json()["releases"] + except (ValueError, KeyError) as e: + msg = f"Unexpected response from {url!r}: missing 'releases' mapping" + raise RuntimeError(msg) from e - build_number = "0" - latest_base_version = current_version.base_version + dev_numbers: list[int] = [] + for version_str in releases: + try: + version = Version(version_str) + except packaging.version.InvalidVersion: + continue + if version.base_version == base_version and version.dev is not None: + dev_numbers.append(version.dev) + return dev_numbers - if current_nightly_version and latest_base_version == nightly_base_version: - build_number = str(current_nightly_version.dev + 1) - new_nightly_version = latest_base_version + ".dev" + build_number +def create_sdk_tag() -> str: + """Return the next ``langflow-sdk`` nightly tag (with a leading ``v``).""" + base_version = _sdk_base_version() + dev_numbers = _dev_numbers(PYPI_SDK_URL, base_version) + next_dev = max(dev_numbers) + 1 if dev_numbers else 0 - if not new_nightly_version.startswith("v"): - new_nightly_version = "v" + new_nightly_version + new_nightly_version = f"v{base_version}.dev{next_dev}" + # Verify the version is PEP 440 compliant. packaging.version.Version(new_nightly_version) return new_nightly_version if __name__ == "__main__": - tag = create_sdk_tag() - print(tag) + print(create_sdk_tag()) diff --git a/scripts/ci/sync_bundle_lfx_pin.py b/scripts/ci/sync_bundle_lfx_pin.py index 061a0902a4..f79d2a1790 100644 --- a/scripts/ci/sync_bundle_lfx_pin.py +++ b/scripts/ci/sync_bundle_lfx_pin.py @@ -8,11 +8,18 @@ guaranteed to resolve an lfx new enough to carry it. Before the LFX 0.5.x -> no upper bound, which silently permitted resolving against the now-dead 0.5.x line -- and neither pip nor uv flags the cross-line jump. -Pin form: ``lfx>=X.Y.0,<(X+1).0.0`` -- floored at the current minor line, -capped below the next lfx major. The cap is a coarse install-time guard -against an untested lfx major; fine-grained BUNDLE_API compatibility is still -enforced at load time by each ``extension.json``'s ``lfx.compat`` list against -the running lfx's ``BUNDLE_API_VERSION`` (see +Pin form: ``lfx>=X.Y.0.dev0,<(X+1).0.0`` -- floored at the very first +pre-release of the current minor line, capped below the next lfx major. The +``.dev0`` floor (not ``X.Y.0``) is load-bearing: nightlies off a release +branch are canonical ``X.Y.0.devN`` pre-releases, and PEP 440 sorts those +BELOW ``X.Y.0`` -- a plain ``>=X.Y.0`` floor makes the branch's own nightly +``lfx`` unresolvable against its own bundles (langflow-base pins +``lfx==X.Y.0.devN`` exactly, so the resolver cannot back off). ``X.Y.0.dev0`` +is the lowest version PEP 440 admits in the line, so every devN / rcN / final +satisfies it while older minor lines stay excluded. The cap is a coarse +install-time guard against an untested lfx major; fine-grained BUNDLE_API +compatibility is still enforced at load time by each ``extension.json``'s +``lfx.compat`` list against the running lfx's ``BUNDLE_API_VERSION`` (see ``src/lfx/src/lfx/extension/manifest.py``). Idempotent: re-running with the same version is a no-op (so it is safe to call @@ -53,8 +60,10 @@ _VERSION_RE = re.compile(r"^(\d+)\.(\d+)\.\d+") def lfx_floor_spec(version: str) -> str: """Return the bundle ``lfx`` dependency spec for a Langflow/LFX version. - ``"1.10.0"`` -> ``"lfx>=1.10.0,<2.0.0"`` (floor at the minor line start, - cap below the next lfx major). A leading ``v`` is tolerated. + ``"1.11.0"`` -> ``"lfx>=1.11.0.dev0,<2.0.0"`` (floor at the minor line's + first pre-release so the branch's own ``X.Y.0.devN`` nightlies resolve -- + see the module docstring; cap below the next lfx major). A leading ``v`` + is tolerated. NOTE: this floor format is duplicated in ``scripts/migrate/port_bundle.py`` (``_current_lfx_floor``) so each script stays standalone; keep them in step. @@ -64,7 +73,7 @@ def lfx_floor_spec(version: str) -> str: msg = f"Unparseable version {version!r}; expected X.Y.Z" raise ValueError(msg) major, minor = int(match.group(1)), int(match.group(2)) - return f"lfx>={major}.{minor}.0,<{major + 1}.0.0" + return f"lfx>={major}.{minor}.0.dev0,<{major + 1}.0.0" def rewrite_lfx_dep(content: str, floor_spec: str) -> str: diff --git a/scripts/ci/test_pypi_nightly_tag.py b/scripts/ci/test_pypi_nightly_tag.py index 093dfd980b..ff373ba330 100644 --- a/scripts/ci/test_pypi_nightly_tag.py +++ b/scripts/ci/test_pypi_nightly_tag.py @@ -20,8 +20,8 @@ import requests sys.path.insert(0, str(Path(__file__).parent)) import pypi_nightly_tag as nt -MAIN_URL = nt.PYPI_LANGFLOW_NIGHTLY_URL -BASE_URL = nt.PYPI_LANGFLOW_BASE_NIGHTLY_URL +MAIN_URL = nt.PYPI_LANGFLOW_URL +BASE_URL = nt.PYPI_LANGFLOW_BASE_URL class _FakeResponse: diff --git a/scripts/ci/update_lf_base_dependency.py b/scripts/ci/update_lf_base_dependency.py index 95670793a4..e51e140c20 100755 --- a/scripts/ci/update_lf_base_dependency.py +++ b/scripts/ci/update_lf_base_dependency.py @@ -16,9 +16,11 @@ def update_base_dep(pyproject_path: str, new_version: str) -> None: content = filepath.read_text(encoding="utf-8") # Updated pattern to handle PEP 440 version suffixes, extras (e.g., [complete]), - # both ~= and == version specifiers, and both langflow-base and langflow-base-nightly names + # ~=, ==, and >= version specifiers, and both langflow-base and langflow-base-nightly names # Captures extras in group 2 to preserve them in the replacement - pattern = re.compile(r'("langflow-base(?:-nightly)?((?:\[[^\]]+\])?)(?:~=|==)[\d.]+(?:\.(?:post|dev|a|b|rc)\d+)*")') + pattern = re.compile( + r'("langflow-base(?:-nightly)?((?:\[[^\]]+\])?)(?:~=|==|>=)[\d.]+(?:\.(?:post|dev|a|b|rc)\d+)*")' + ) # Check if the pattern is found match = pattern.search(content) @@ -28,7 +30,9 @@ def update_base_dep(pyproject_path: str, new_version: str) -> None: # Extract extras if present (e.g., "[complete]") extras = match.group(2) if match.group(2) else "" - replacement = f'"langflow-base-nightly{extras}=={new_version}"' + # Keep the canonical `langflow-base` name; the exact `==` pin enables pre-release + # resolution down the tree and keeps base in lockstep with the run. + replacement = f'"langflow-base{extras}=={new_version}"' # Replace the matched pattern with the new one content = pattern.sub(replacement, content) @@ -43,7 +47,9 @@ def update_lfx_dep_in_base(pyproject_path: str, lfx_version: str) -> None: # Updated pattern to handle PEP 440 version suffixes, both ~= and == version specifiers, # and both lfx and lfx-nightly names pattern = re.compile(r'("lfx(?:-nightly)?(?:~=|==)[\d.]+(?:\.(?:post|dev|a|b|rc)\d+)*")') - replacement = f'"lfx-nightly=={lfx_version}"' + # Pin base's lfx dep to the exact canonical dev version (single `lfx` distribution, no + # `lfx-nightly`), so there is no `lfx` vs `lfx-nightly` install collision with the bundles. + replacement = f'"lfx=={lfx_version}"' # Check if the pattern is found if not pattern.search(content): diff --git a/scripts/ci/update_lfx_version.py b/scripts/ci/update_lfx_version.py index 77dc90516c..1290b5f5e4 100644 --- a/scripts/ci/update_lfx_version.py +++ b/scripts/ci/update_lfx_version.py @@ -1,12 +1,19 @@ -"""Script to update LFX version for nightly builds.""" +"""Update the canonical ``lfx`` package (and its SDK dep) for nightly builds. + +The nightly publishes ``lfx`` and ``langflow-sdk`` under their CANONICAL names as ``.devN`` +pre-releases -- it does NOT rename them to ``lfx-nightly`` / ``langflow-sdk-nightly``, and it does +NOT give the ``src/bundles/*`` packages their own nightly track. The stable ``lfx-*`` bundles +(pinning ``lfx>=X.Y.0,<(X+1).0.0``) then resolve against the single canonical ``lfx`` distribution, +so there is no ``lfx`` vs ``lfx-nightly`` install collision. See ``src/bundles/NIGHTLY.md``. + +This script therefore only (a) sets ``lfx``'s version to the nightly ``.devN`` and (b) re-pins +lfx's ``langflow-sdk`` dependency to the exact canonical dev version. +""" import re import sys from pathlib import Path -import tomllib -from packaging.version import Version -from update_pyproject_name import update_pyproject_name from update_pyproject_version import update_pyproject_version # Add the current directory to the path so we can import the other scripts @@ -14,36 +21,20 @@ current_dir = Path(__file__).resolve().parent sys.path.append(str(current_dir)) BASE_DIR = Path(__file__).parent.parent.parent -ROOT_PYPROJECT = BASE_DIR / "pyproject.toml" - - -def update_lfx_workspace_dep(pyproject_path: str, new_project_name: str) -> None: - """Update the LFX workspace dependency in pyproject.toml.""" - filepath = BASE_DIR / pyproject_path - content = filepath.read_text(encoding="utf-8") - - if new_project_name == "lfx-nightly": - pattern = re.compile(r"lfx = \{ workspace = true \}") - replacement = "lfx-nightly = { workspace = true }" - else: - msg = f"Invalid LFX project name: {new_project_name}" - raise ValueError(msg) - - # Updates the dependency name for uv - if not pattern.search(content): - msg = f"lfx workspace dependency not found in {filepath}" - raise ValueError(msg) - content = pattern.sub(replacement, content) - filepath.write_text(content, encoding="utf-8") def update_sdk_dependency_in_lfx(pyproject_path: str, sdk_version: str) -> None: - """Update the SDK dependency in the LFX pyproject for nightly builds.""" + """Pin lfx's ``langflow-sdk`` dependency to the exact canonical dev version. + + An exact ``==`` pin keeps the SDK in lockstep with the lfx built in the same run and, + because it names a pre-release explicitly, enables pre-release resolution for ``langflow-sdk`` + down the dependency tree without requiring ``--pre``. + """ filepath = BASE_DIR / pyproject_path content = filepath.read_text(encoding="utf-8") pattern = re.compile(r'"langflow-sdk(?:-nightly)?(?:==|~=|>=)[\d.]+(?:\.(?:post|dev|a|b|rc)\d+)*"') - replacement = f'"langflow-sdk-nightly=={sdk_version}"' + replacement = f'"langflow-sdk=={sdk_version}"' if not pattern.search(content): msg = f"SDK dependency not found in {filepath}" @@ -53,158 +44,24 @@ def update_sdk_dependency_in_lfx(pyproject_path: str, sdk_version: str) -> None: filepath.write_text(content, encoding="utf-8") -# Match an `lfx` (or `lfx-nightly`) dependency specifier inside a quoted -# string. The lookahead enforces a version operator immediately after the -# name so we don't accidentally match sibling packages like `lfx-arxiv` or -# `lfx-duckduckgo`. -_BUNDLE_LFX_DEP_PATTERN = re.compile(r'"lfx(?:-nightly)?(?=[<>=!~])[^"]*"') - - -def update_lfx_dep_in_bundles(lfx_version: str) -> None: - """Pin every bundle's `lfx` dep to the renamed `lfx-nightly==`. - - Each `src/bundles/*/pyproject.toml` floors its `lfx` dep at `>=X.Y` - (no upper bound) against the published `lfx` package. During nightly builds the - workspace `lfx` package gets renamed to `lfx-nightly`, so those pins - no longer resolve against the workspace member — and PyPI may not yet - ship a matching `lfx` either. Rewrite each bundle's pin to - `lfx-nightly==` so `uv lock` resolves cleanly. - - No-op when no bundles exist (e.g. on a branch that hasn't picked up - the bundle extraction) or when a bundle has no `lfx` dep. - """ - bundles_dir = BASE_DIR / "src" / "bundles" - if not bundles_dir.is_dir(): - return - - replacement = f'"lfx-nightly=={lfx_version}"' - for bundle_pyproject in sorted(bundles_dir.glob("*/pyproject.toml")): - content = bundle_pyproject.read_text(encoding="utf-8") - if not _BUNDLE_LFX_DEP_PATTERN.search(content): - continue - new_content = _BUNDLE_LFX_DEP_PATTERN.sub(replacement, content) - if new_content == content: - continue - bundle_pyproject.write_text(new_content, encoding="utf-8") - print(f"Updated lfx dep in {bundle_pyproject.relative_to(BASE_DIR)} -> lfx-nightly=={lfx_version}") - - -def _bundle_nightly_version(bundle_base_version: str, lfx_version: str) -> str: - """Derive a bundle's nightly version: `.dev`. - - The dev build number `N` is shared with `lfx-nightly` (the same value the - nightly tagger already pins each bundle's `lfx` dep to), so a bundle's - nightly version moves in lockstep with the lfx it was built against while - keeping the bundle's own base version (e.g. `0.1.0`) truthful. - """ - lfx_parsed = Version(lfx_version) - if lfx_parsed.dev is None: - msg = f"Expected a .devN nightly lfx version, got {lfx_version!r}" - raise ValueError(msg) - base = Version(bundle_base_version).base_version - return f"{base}.dev{lfx_parsed.dev}" - - -def rename_bundles_for_nightly(lfx_version: str) -> None: - """Rename each `src/bundles/*` package to its `-nightly` distribution. - - The stable bundles publish as `lfx-` and pin `lfx>=X.Y`. During a - nightly build the workspace `lfx` becomes `lfx-nightly` (no stable `lfx` - matching the pin may exist on PyPI yet), so a `langflow-nightly` that still - depended on the stable `lfx-` would drag in `lfx>=X.Y` and fail to - resolve. Give the bundles their own nightly track instead, mirroring how - lfx/base/main are renamed. For every bundle this: - - * rewrites its `[project] name` `lfx-` -> `lfx--nightly` - * rewrites its `[project] version` `0.1.0` -> `0.1.0.dev` - * repoints the root `[tool.uv.sources]` workspace entry to the new name - * repoints the root `langflow` dependencies to `lfx--nightly==`, - including extras forms like `lfx-docling[local]>=...` in - `[project.optional-dependencies]` (the `[extra]` selector is preserved) - - The bundle's own `lfx` dep is repinned separately by - `update_lfx_dep_in_bundles`. No-op when no bundles are present, and - idempotent for bundles already carrying a `-nightly` name. - """ - bundles_dir = BASE_DIR / "src" / "bundles" - if not bundles_dir.is_dir(): - return - - root_content = ROOT_PYPROJECT.read_text(encoding="utf-8") - - for bundle_pyproject in sorted(bundles_dir.glob("*/pyproject.toml")): - data = tomllib.loads(bundle_pyproject.read_text(encoding="utf-8")) - old_name = data["project"]["name"] - if old_name.endswith("-nightly"): - continue - new_name = f"{old_name}-nightly" - new_version = _bundle_nightly_version(data["project"]["version"], lfx_version) - - rel_path = str(bundle_pyproject.relative_to(BASE_DIR)) - update_pyproject_name(rel_path, new_name) - update_pyproject_version(rel_path, new_version) - - # Repoint the workspace source: `lfx- = { workspace = true }`. - source_pattern = re.compile(rf"^{re.escape(old_name)}(\s*=\s*\{{ workspace = true \}})", re.MULTILINE) - if not source_pattern.search(root_content): - msg = f"Workspace source entry for {old_name} not found in {ROOT_PYPROJECT}" - raise ValueError(msg) - root_content = source_pattern.sub(rf"{new_name}\1", root_content) - - # Repoint the root dependencies to the exact nightly pin. This covers - # both the bare main dep `"lfx->=0.1.0"` and any extras form in - # `[project.optional-dependencies]` such as `"lfx-docling[local]>=0.1.0"`. - # The optional `[extra]` is captured and re-emitted so the selector - # survives the rewrite (-> `"lfx-docling-nightly[local]=="`); a - # missed extras ref would stay `lfx-` and leak to PyPI, where no - # `>=0.1.0` is published, breaking `uv lock`. The lookahead still - # requires a version operator right after the name+optional-extra so we - # match `lfx-arxiv>=...` / `lfx-docling[local]>=...` without also - # matching an already-renamed `lfx-arxiv-nightly`. - dep_pattern = re.compile(rf'"{re.escape(old_name)}(\[[^\]]+\])?(?=[<>=!~])[^"]*"') - if not dep_pattern.search(root_content): - msg = f"Root dependency on {old_name} not found in {ROOT_PYPROJECT}" - raise ValueError(msg) - root_content = dep_pattern.sub(rf'"{new_name}\g<1>=={new_version}"', root_content) - - print(f"Renamed bundle {old_name} -> {new_name}=={new_version}") - - ROOT_PYPROJECT.write_text(root_content, encoding="utf-8") - - def update_lfx_for_nightly(lfx_tag: str, sdk_tag: str): - """Update LFX package for nightly build. + """Update the canonical ``lfx`` package for a nightly build. Args: - lfx_tag: The nightly tag for LFX (e.g., "v0.1.0.dev0") - sdk_tag: The nightly tag for the SDK (e.g., "v0.1.0.dev0") + lfx_tag: The nightly tag for LFX (e.g., "v1.11.0.dev0"). + sdk_tag: The nightly tag for the SDK (e.g., "v0.1.0.dev0"). """ lfx_pyproject_path = "src/lfx/pyproject.toml" - # Update name to lfx-nightly - update_pyproject_name(lfx_pyproject_path, "lfx-nightly") - - # Update version (strip 'v' prefix if present) + # Set the version (strip 'v' prefix if present); the package keeps its canonical `lfx` name. version = lfx_tag.lstrip("v") update_pyproject_version(lfx_pyproject_path, version) - # Update workspace dependency in root pyproject.toml - update_lfx_workspace_dep("pyproject.toml", "lfx-nightly") - + # Re-pin lfx's SDK dependency to the exact canonical dev version. sdk_version = sdk_tag.lstrip("v") update_sdk_dependency_in_lfx(lfx_pyproject_path, sdk_version) - # Re-pin every bundle's lfx dep to the renamed workspace package so - # `uv lock` resolves cleanly. No-op when no bundles are present. - update_lfx_dep_in_bundles(version) - - # Give each bundle its own `-nightly` distribution and repoint the root - # `langflow` deps + workspace sources at it, so `langflow-nightly` pulls - # `lfx--nightly` (which pins `lfx-nightly`) instead of the stable - # `lfx-` (which pins an as-yet-unpublished stable `lfx`). - rename_bundles_for_nightly(version) - - print(f"Updated LFX package to lfx-nightly version {version}") + print(f"Updated lfx to nightly version {version}") def main(): diff --git a/scripts/ci/update_pyproject_combined.py b/scripts/ci/update_pyproject_combined.py index 997c2f9586..bc08e88e4d 100755 --- a/scripts/ci/update_pyproject_combined.py +++ b/scripts/ci/update_pyproject_combined.py @@ -4,8 +4,6 @@ import sys from pathlib import Path from update_lf_base_dependency import update_lfx_dep_in_base -from update_pyproject_name import update_pyproject_name -from update_pyproject_name import update_uv_dep as update_name_uv_dep from update_pyproject_version import update_pyproject_version from update_uv_dependency import update_uv_dep as update_version_uv_dep @@ -17,6 +15,10 @@ sys.path.append(str(current_dir)) def main(): """Universal update script that handles both base and main updates in a single run. + The packages keep their CANONICAL names (``langflow``, ``langflow-base``) -- they are NOT + renamed to ``*-nightly``. This script only sets the nightly ``.devN`` versions and re-pins the + inter-package dependencies to exact canonical dev versions. See ``src/bundles/NIGHTLY.md``. + Usage: update_pyproject_combined.py main """ @@ -36,26 +38,22 @@ def main(): base_tag = sys.argv[3] lfx_tag = sys.argv[4] - # Lockstep invariant: langflow-base-nightly's published version (set here from `base_tag`) - # and langflow-nightly's exact `==` pin on it (set below from the same `base_tag`) MUST come - # from the same value, so the latest langflow-nightly always pins a base version published in - # the same run. `pypi_nightly_tag.py` makes the main and base tags identical; keep both writes - # sourced from `base_tag` or the pin can reference a version that was never published. + # Lockstep invariant: langflow-base's published dev version (set here from `base_tag`) and + # langflow's exact `==` pin on it (set below from the same `base_tag`) MUST come from the same + # value, so the latest nightly `langflow` always pins a base version published in the same run. + # `pypi_nightly_tag.py` makes the main and base tags identical; keep both writes sourced from + # `base_tag` or the pin can reference a version that was never published. - # First handle base package updates - update_pyproject_name("src/backend/base/pyproject.toml", "langflow-base-nightly") - update_name_uv_dep("pyproject.toml", "langflow-base-nightly") + # First handle base package updates (canonical name kept). update_pyproject_version("src/backend/base/pyproject.toml", base_tag) - # Update LFX dependency in langflow-base + # Update LFX dependency in langflow-base (exact canonical dev pin). lfx_version = lfx_tag.lstrip("v") update_lfx_dep_in_base("src/backend/base/pyproject.toml", lfx_version) - # Then handle main package updates - update_pyproject_name("pyproject.toml", "langflow-nightly") - update_name_uv_dep("pyproject.toml", "langflow-nightly") + # Then handle main package updates (canonical name kept). update_pyproject_version("pyproject.toml", main_tag) - # Update dependency version (strip 'v' prefix if present) + # Update langflow-base dependency version (strip 'v' prefix if present). base_version = base_tag.lstrip("v") update_version_uv_dep(base_version) diff --git a/scripts/ci/update_sdk_version.py b/scripts/ci/update_sdk_version.py index 92a2d75ae6..920c9e084c 100644 --- a/scripts/ci/update_sdk_version.py +++ b/scripts/ci/update_sdk_version.py @@ -1,10 +1,13 @@ -"""Script to update SDK version for nightly builds.""" +"""Update the canonical ``langflow-sdk`` version for nightly builds. + +The SDK keeps its canonical ``langflow-sdk`` name -- it is NOT renamed to ``langflow-sdk-nightly`` -- +and is published as a ``.devN`` pre-release. This script only sets the nightly version. +See ``src/bundles/NIGHTLY.md``. +""" import sys from pathlib import Path -from update_pyproject_name import update_pyproject_name -from update_pyproject_name import update_uv_dep as update_workspace_dep from update_pyproject_version import update_pyproject_version # Add the current directory to the path so we can import the other scripts @@ -13,17 +16,13 @@ sys.path.append(str(current_dir)) def update_sdk_for_nightly(sdk_tag: str): - """Update SDK package for nightly build.""" + """Set the canonical ``langflow-sdk`` package version for a nightly build.""" sdk_pyproject_path = "src/sdk/pyproject.toml" - update_pyproject_name(sdk_pyproject_path, "langflow-sdk-nightly") - version = sdk_tag.lstrip("v") update_pyproject_version(sdk_pyproject_path, version) - update_workspace_dep("pyproject.toml", "langflow-sdk-nightly") - - print(f"Updated SDK package to langflow-sdk-nightly version {version}") + print(f"Updated langflow-sdk to nightly version {version}") def main(): diff --git a/scripts/ci/update_uv_dependency.py b/scripts/ci/update_uv_dependency.py index d0fb282510..93844bc80b 100755 --- a/scripts/ci/update_uv_dependency.py +++ b/scripts/ci/update_uv_dependency.py @@ -32,7 +32,8 @@ def update_uv_dep(base_version: str) -> None: # Extract extras if present (e.g., "[complete]") extras = match.group(3) if match.group(3) else "" - replacement = rf'\1"langflow-base-nightly{extras}=={base_version}"' + # Keep the canonical `langflow-base` name with an exact `==` pin. + replacement = rf'\1"langflow-base{extras}=={base_version}"' # Replace the matched pattern with the new one content = pattern.sub(replacement, content) diff --git a/scripts/migrate/port_bundle.py b/scripts/migrate/port_bundle.py index c164024dae..86f6c37f01 100755 --- a/scripts/migrate/port_bundle.py +++ b/scripts/migrate/port_bundle.py @@ -69,11 +69,13 @@ def _current_lfx_floor() -> str: """Return the ``lfx`` dependency floor for a freshly-ported bundle. Reads the workspace lfx version from ``src/lfx/pyproject.toml`` and pins - ``lfx>=X.Y.0,<(X+1).0.0`` -- floored at the current major.minor line, - capped below the next lfx major. Mirrors ``lfx_floor_spec`` in - ``scripts/ci/sync_bundle_lfx_pin.py`` (each script is kept standalone, so - keep the two in step); that script re-syncs every existing bundle on - ``make patch``. + ``lfx>=X.Y.0.dev0,<(X+1).0.0`` -- floored at the current major.minor + line's first pre-release (the branch's own canonical ``X.Y.0.devN`` + nightlies sort below a plain ``X.Y.0`` under PEP 440, so they must be + admitted by the floor), capped below the next lfx major. Mirrors + ``lfx_floor_spec`` in ``scripts/ci/sync_bundle_lfx_pin.py`` (each script + is kept standalone, so keep the two in step); that script re-syncs every + existing bundle on ``make patch``. """ lfx_pyproject = (REPO_ROOT / "src" / "lfx" / "pyproject.toml").read_text(encoding="utf-8") match = re.search(r'^version = "(\d+)\.(\d+)\.\d+', lfx_pyproject, re.MULTILINE) @@ -81,7 +83,7 @@ def _current_lfx_floor() -> str: msg = "Could not read lfx version from src/lfx/pyproject.toml" raise ValueError(msg) major, minor = int(match.group(1)), int(match.group(2)) - return f"lfx>={major}.{minor}.0,<{major + 1}.0.0" + return f"lfx>={major}.{minor}.0.dev0,<{major + 1}.0.0" # --------------------------------------------------------------------------- diff --git a/src/backend/base/langflow/main.py b/src/backend/base/langflow/main.py index 1d5190f4b9..388e41c3a5 100644 --- a/src/backend/base/langflow/main.py +++ b/src/backend/base/langflow/main.py @@ -479,7 +479,14 @@ def get_lifespan(*, fix_migration=False, version=None): await asyncio.sleep(refresh_interval_seconds) - models_dev_refresh_task = asyncio.create_task(refresh_models_dev_periodically()) + # LANGFLOW_MODELS_DEV_REFRESH=false disables the live models.dev + # fetch. Tests set this: the startup fetch otherwise fires from a + # background task during whatever test is running, hitting the + # network and tripping event-loop-block detectors (pyleak). + if os.getenv("LANGFLOW_MODELS_DEV_REFRESH", "true").lower() not in ("false", "0", "no"): + models_dev_refresh_task = asyncio.create_task(refresh_models_dev_periodically()) + else: + await logger.adebug("models.dev refresh disabled via LANGFLOW_MODELS_DEV_REFRESH") # v1 and project MCP server context managers from langflow.api.v1.mcp import start_streamable_http_manager diff --git a/src/backend/base/langflow/utils/version.py b/src/backend/base/langflow/utils/version.py index 336c6046ee..1a04b980db 100644 --- a/src/backend/base/langflow/utils/version.py +++ b/src/backend/base/langflow/utils/version.py @@ -38,10 +38,17 @@ def _get_version_info(): except (ImportError, metadata.PackageNotFoundError): pass else: + # The canonical `langflow` / `langflow-base` distribution matches first, and the + # nightly now publishes under that canonical name as a `.devN` pre-release. Derive the + # "Nightly" label from the `.dev` version marker (not the package name) so the startup + # banner and telemetry `package` field still identify nightlies correctly. + display = display_name + if "dev" in prerelease_version and "Nightly" not in display: + display = f"{display_name} Nightly" return { "version": prerelease_version, "main_version": version, - "package": display_name, + "package": display, } if __version__ is None: diff --git a/src/backend/tests/.test_durations b/src/backend/tests/.test_durations index 9af2919d56..ff76836e14 100644 --- a/src/backend/tests/.test_durations +++ b/src/backend/tests/.test_durations @@ -67,149 +67,3469 @@ "src/backend/tests/test_webhook.py::test_webhook_endpoint": 8.848518459000388, "src/backend/tests/test_webhook.py::test_webhook_flow_on_run_endpoint": 4.675444458000584, "src/backend/tests/test_webhook.py::test_webhook_with_random_payload": 5.161753501000476, - "src/backend/tests/unit/api/test_api_utils.py::test_get_outdated_components": 0.0008271670085377991, - "src/backend/tests/unit/api/test_api_utils.py::test_get_suggestion_message": 0.062292501010233536, - "src/backend/tests/unit/api/v1/test_api_key.py::test_create_api_key_route": 2.506952625029953, - "src/backend/tests/unit/api/v1/test_api_key.py::test_create_folder": 12.979961918026675, - "src/backend/tests/unit/api/v1/test_api_key.py::test_delete_api_key_route": 2.4513380830176175, - "src/backend/tests/unit/api/v1/test_api_key.py::test_save_store_api_key": 3.2220397089840844, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_combined_fields": 0.015468625002540648, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_logs": 0.014387874980457127, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_nested_structures": 0.008282333030365407, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_outputs": 0.016630333993816748, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_special_types": 0.6439955829991959, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_truncation": 0.03333358297822997, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_vertex_build_response_serialization": 0.03763025099760853, - "src/backend/tests/unit/api/v1/test_api_schemas.py::test_vertex_build_response_with_long_data": 0.008100416016532108, + "src/backend/tests/unit/agentic/api/test_assistant_api_report_repro.py::test_assist_rejects_unknown_flow_id_before_invoking_the_model": 15.069, + "src/backend/tests/unit/agentic/api/test_assistant_api_report_repro.py::test_check_config_providers_are_consistent_with_configured_providers": 16.84, + "src/backend/tests/unit/agentic/api/test_assistant_api_report_repro.py::test_execute_named_assistant_flow_is_graceful_not_500": 5.293, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_extract_component_code_should_reject_non_component": 0.008, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_extract_python_code_whitespace_only_block": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_find_component_code_false_positive_substring": 0.033, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_generic_pattern_ignores_language_tags": 0.048, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_nested_code_blocks_truncate_content": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_rstrip_should_not_corrupt_code_with_backticks": 0.012, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestBugsAndEdgeCases::test_should_return_none_for_empty_code_block": 0.009, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestCodeExtractionAndValidationIntegration::test_full_flow_with_invalid_code_returns_error": 0.043, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestCodeExtractionAndValidationIntegration::test_full_flow_with_text_heavy_response": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestCodeExtractionAndValidationIntegration::test_full_flow_with_unclosed_valid_response": 0.436, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestCodeExtractionAndValidationIntegration::test_full_flow_with_valid_response": 0.405, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestEdgeCases::test_case_insensitive_python_tag": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestEdgeCases::test_handles_mixed_line_endings": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestEdgeCases::test_handles_unicode_in_code": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestEdgeCases::test_handles_very_long_code": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestEdgeCases::test_handles_windows_line_endings": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_extract_from_closed_python_block": 0.04, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_extract_from_generic_code_block": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_extract_from_unclosed_python_block": 0.037, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_extract_with_text_before_code": 0.04, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_handles_code_with_special_characters": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_prefers_component_code_over_other_code": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_returns_none_for_empty_text": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_returns_none_for_no_code_blocks": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestExtractPythonCode::test_should_return_first_block_when_no_component_code": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindCodeBlocks::test_finds_closed_python_blocks": 0.043, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindCodeBlocks::test_finds_unclosed_blocks_as_fallback": 0.04, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindUnclosedCodeBlock::test_finds_unclosed_generic_block": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindUnclosedCodeBlock::test_finds_unclosed_python_block": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindUnclosedCodeBlock::test_handles_multiple_backticks_in_code": 0.043, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindUnclosedCodeBlock::test_returns_empty_for_closed_blocks": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestFindUnclosedCodeBlock::test_returns_empty_for_no_code_blocks": 0.045, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestValidateComponentCode::test_fails_for_empty_code": 0.041, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestValidateComponentCode::test_fails_for_incomplete_code": 0.042, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestValidateComponentCode::test_fails_for_non_component_code": 0.04, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestValidateComponentCode::test_fails_for_syntax_error": 0.038, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestValidateComponentCode::test_passes_static_validation_without_imports": 0.467, + "src/backend/tests/unit/agentic/api/test_code_extraction.py::TestValidateComponentCode::test_validates_valid_component": 0.039, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestAuditLogging::test_should_log_audit_event_when_file_read": 0.037, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestCrossUserDenial::test_should_return_404_when_target_in_other_user_namespace": 0.038, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestDownloadMode::test_should_force_octet_stream_when_download_true": 0.038, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestDownloadMode::test_should_sanitize_filename_in_content_disposition": 0.038, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestDownloadMode::test_should_set_content_disposition_attachment_when_download_true": 0.041, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestHappyPath::test_should_return_file_content_when_path_valid": 0.035, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestMissingFile::test_should_return_404_when_file_does_not_exist": 0.04, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_absolute_unix": 0.045, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_absolute_unix_backslash": 0.039, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_contains_dotdot[../../etc/passwd]": 0.039, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_contains_dotdot[../escape.md]": 0.042, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_contains_dotdot[subdir/../../../escape.md]": 0.044, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_contains_dotdot[subdir/..]": 0.041, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_empty": 0.044, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_null_byte": 0.046, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestPathTraversalRejection::test_should_reject_path_when_windows_drive_letter": 0.048, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestSizeAndBinaryGuards::test_should_return_413_when_file_exceeds_max_size": 0.041, + "src/backend/tests/unit/agentic/api/test_files_endpoint.py::TestSizeAndBinaryGuards::test_should_return_415_when_file_is_binary": 0.037, + "src/backend/tests/unit/agentic/api/test_files_endpoint_force_isolation.py::TestEndpointIsolatesUsersUnderAutoLogin::test_should_return_404_when_user_b_requests_user_a_file": 0.034, + "src/backend/tests/unit/agentic/api/test_files_endpoint_force_isolation.py::TestEndpointIsolatesUsersUnderAutoLogin::test_should_return_file_when_owner_requests_own_file": 0.036, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_case_insensitive": 0.068, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_extracts_flow_json_block": 0.041, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_extracts_from_mixed_content": 0.071, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_handles_pretty_printed_json": 0.074, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_returns_none_for_invalid_json": 0.067, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_returns_none_for_python_code_block": 0.041, + "src/backend/tests/unit/agentic/api/test_flow_extraction.py::TestExtractFlowJson::test_returns_none_when_no_flow_block": 0.075, + "src/backend/tests/unit/agentic/api/test_openapi_visibility.py::TestAgenticRoutersAppearInOpenApi::test_should_expose_assist_endpoint": 0.006, + "src/backend/tests/unit/agentic/api/test_openapi_visibility.py::TestAgenticRoutersAppearInOpenApi::test_should_expose_assist_stream_endpoint": 0.007, + "src/backend/tests/unit/agentic/api/test_openapi_visibility.py::TestAgenticRoutersAppearInOpenApi::test_should_expose_check_config_endpoint": 0.013, + "src/backend/tests/unit/agentic/api/test_openapi_visibility.py::TestAgenticRoutersAppearInOpenApi::test_should_expose_execute_endpoint": 0.012, + "src/backend/tests/unit/agentic/api/test_openapi_visibility.py::TestAgenticRoutersAppearInOpenApi::test_should_expose_files_endpoint": 0.011, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestAssistantRequest::test_should_accept_empty_string_for_optional_fields": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestAssistantRequest::test_should_create_with_all_fields": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestAssistantRequest::test_should_create_with_required_field_only": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestAssistantRequest::test_should_deserialize_from_dict": 0.051, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestAssistantRequest::test_should_raise_error_for_missing_flow_id": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestAssistantRequest::test_should_serialize_to_dict": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestSchemaIntegration::test_assistant_request_json_round_trip": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestSchemaIntegration::test_validation_result_json_round_trip": 0.042, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestStepType::test_should_define_all_expected_step_types": 0.049, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestStepType::test_step_types_should_be_strings": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestValidationResult::test_should_create_invalid_result_with_error": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestValidationResult::test_should_create_valid_result": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestValidationResult::test_should_create_with_required_field_only": 0.049, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestValidationResult::test_should_deserialize_from_dict": 0.041, + "src/backend/tests/unit/agentic/api/test_schemas.py::TestValidationResult::test_should_serialize_to_dict": 0.052, + "src/backend/tests/unit/agentic/api/test_sessions_reset_endpoint.py::TestResetSessionEndpointShape::test_should_accept_missing_session_id": 0.037, + "src/backend/tests/unit/agentic/api/test_sessions_reset_endpoint.py::TestResetSessionEndpointShape::test_should_return_zero_counts_when_nothing_to_clear": 0.038, + "src/backend/tests/unit/agentic/api/test_sessions_reset_endpoint.py::TestResetSessionEndpointWipesComponents::test_should_delete_conversation_buffer_for_session_id": 2.6, + "src/backend/tests/unit/agentic/api/test_sessions_reset_endpoint.py::TestResetSessionEndpointWipesComponents::test_should_delete_registered_components_for_calling_user": 0.032, + "src/backend/tests/unit/agentic/api/test_sessions_reset_endpoint.py::TestResetSessionEndpointWipesComponents::test_should_not_touch_other_sessions_conversation_buffer": 0.038, + "src/backend/tests/unit/agentic/api/test_sessions_reset_endpoint.py::TestResetSessionEndpointWipesComponents::test_should_not_touch_other_users_components": 0.035, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestNonStreamingValidation::test_non_streaming_max_retries_returns_error": 3.367, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestNonStreamingValidation::test_non_streaming_retries_on_failure": 0.058, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestNonStreamingValidation::test_non_streaming_valid_code_returns_validated": 0.95, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestRealWorldScenarios::test_code_extraction_from_exact_user_response": 0.046, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestRealWorldScenarios::test_cutoff_code_retry_gets_valid_code": 0.006, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestRealWorldScenarios::test_response_with_apology_and_cutoff_code": 0.912, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestRealWorldScenarios::test_response_with_apology_and_cutoff_code_with_retries": 0.036, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestResponseWithTextAndCode::test_complete_event_includes_component_code": 0.902, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestResponseWithTextAndCode::test_extracts_code_from_response_with_text_before": 0.007, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestResponseWithTextAndCode::test_extracts_code_from_unclosed_block_with_text": 0.007, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestResponseWithTextAndCode::test_validation_failure_includes_component_code": 0.903, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestSSEEventFormatting::testformat_complete_event_format": 1.78, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestSSEEventFormatting::testformat_error_event_format": 0.045, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestSSEEventFormatting::testformat_progress_event_format": 0.04, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestSSEEventFormatting::testformat_progress_event_validating_step": 0.055, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestStreamingValidationFlow::test_all_retries_fail_returns_validation_error": 1.587, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestStreamingValidationFlow::test_flow_execution_error_on_component_generation_retries_then_emits_complete_event": 2.145, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestStreamingValidationFlow::test_flow_execution_error_on_qa_intent_emits_error_event_without_retry": 0.955, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestStreamingValidationFlow::test_invalid_code_retries_until_success": 1.214, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestStreamingValidationFlow::test_no_code_in_response_returns_as_is": 0.042, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestStreamingValidationFlow::test_valid_code_first_try_returns_validated": 0.01, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestValidationRetryBehavior::test_retry_includes_previous_error_in_prompt": 3.318, + "src/backend/tests/unit/agentic/api/test_streaming_validation.py::TestValidationRetryTemplate::test_retry_template_contains_error": 0.959, + "src/backend/tests/unit/agentic/flows/test_agentic_model_config.py::TestBuildModelConfigUsesRegisteredClassNames::test_should_emit_a_resolvable_class_when_provider_is_google": 0.04, + "src/backend/tests/unit/agentic/flows/test_agentic_model_config.py::TestBuildModelConfigUsesRegisteredClassNames::test_should_keep_openai_and_anthropic_class_names[Anthropic-ChatAnthropic]": 0.044, + "src/backend/tests/unit/agentic/flows/test_agentic_model_config.py::TestBuildModelConfigUsesRegisteredClassNames::test_should_keep_openai_and_anthropic_class_names[OpenAI-ChatOpenAI]": 0.041, + "src/backend/tests/unit/agentic/flows/test_agentic_model_config.py::TestBuildModelConfigUsesRegisteredClassNames::test_should_use_registered_class_when_provider_is_google": 0.041, + "src/backend/tests/unit/agentic/flows/test_agentic_model_config.py::TestRegistryKnowsGroqAndAzure::test_should_resolve_groq_and_azure_without_unknown_class_error[AzureChatOpenAI]": 0.043, + "src/backend/tests/unit/agentic/flows/test_agentic_model_config.py::TestRegistryKnowsGroqAndAzure::test_should_resolve_groq_and_azure_without_unknown_class_error[ChatGroq]": 0.01, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_explains_description_is_the_tool_description": 0.04, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_explains_tool_mode_input_marker": 0.041, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_forbids_reserved_output_name": 0.036, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_includes_a_quick_checklist": 0.04, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_section_is_present": 0.039, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_shows_a_good_method_name_example": 0.039, + "src/backend/tests/unit/agentic/flows/test_component_generator_tool_prompt.py::TestAgentToolCompatibilitySection::test_warns_against_generic_method_names": 0.038, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_edit_file_through_toolkit_should_emit_file_written_event": 0.033, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_failed_write_should_not_emit_event": 0.026, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_read_file_should_not_emit_event": 0.022, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_toolkit_should_include_filesystem_tools": 0.044, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_toolkit_should_keep_existing_canvas_tools": 0.042, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_write_file_event_path_should_not_leak_base_dir": 0.039, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFilesystemToolsInToolkit::test_write_file_through_toolkit_should_emit_file_written_event": 0.803, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_explain_tools_input_only_takes_tool_outputs": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_forbid_orphan_components": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_have_chatbot_or_assistant_example_with_system_prompt": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_instruct_retry_on_failure": 0.042, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_instruct_search_before_building": 0.04, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_instruct_to_swap_model_via_configure_component": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_mention_build_flow_for_new_flows": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_mention_build_flow_tool": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_mention_describe_component_tool": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_mention_search_components_tool": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_require_a_model_on_any_agent_that_will_run": 0.042, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_require_system_prompt_for_persona_use_cases": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_resolve_target_component_by_role_not_name": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_run_in_same_turn_after_a_directly_applied_edit": 0.056, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_self_verify_run_reflects_the_edit": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_show_model_field_value_structure": 0.042, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_teach_the_edit_continuation_contract": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPrompt::test_should_warn_about_agents_built_in_model": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptBehaviorContract::test_should_forbid_asking_confirmation_for_already_requested_action": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptBehaviorContract::test_should_forbid_claiming_action_without_calling_the_tool": 0.04, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptBehaviorContract::test_should_instruct_reply_in_user_language": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptFilesystem::test_prompt_should_mention_sandbox": 1.615, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptFilesystem::test_prompt_should_mention_write_file": 0.051, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptLegacyComponents::test_should_warn_against_legacy_components": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptProposePlan::test_should_explain_user_continue_vs_dismiss_loop": 0.055, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptProposePlan::test_should_make_propose_plan_optional_not_mandatory": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptProposePlan::test_should_mention_propose_plan_tool": 0.056, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptUserComponents::test_should_forbid_refusing_to_use_user_components_in_a_flow": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestFlowBuilderPromptUserComponents::test_should_mention_user_generated_components_are_registered": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_different_providers_on_consecutive_calls": 0.035, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_flow_loader_reload_simulation": 0.006, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_load_graph_for_execution_twice": 0.028, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_load_graph_for_execution_with_replace_in_prompt": 0.019, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_second_call_should_not_crash": 0.132, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_should_accept_api_key_var": 0.077, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_should_accept_provider_and_model": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestGetGraph::test_should_create_graph_with_defaults": 0.096, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestIntentClassificationBuildFlow::test_build_rag_pipeline_classified_as_build_flow": 1.573, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestIntentClassificationBuildFlow::test_can_you_build_a_flow_classified_as_build_flow": 0.005, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestIntentClassificationBuildFlow::test_create_component_not_classified_as_build_flow": 0.006, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestIntentClassificationBuildFlow::test_simple_chat_flow_classified_as_build_flow": 1.282, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestProposePlanInToolkit::test_toolkit_should_include_propose_plan_tool": 0.026, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestRunFlowToolWiring::test_prompt_should_document_run_flow": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestRunFlowToolWiring::test_prompt_should_say_run_is_not_a_build_no_plan_gate": 0.132, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestRunFlowToolWiring::test_toolkit_should_include_run_flow_tool": 0.024, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestTranslationPromptBuildFlow::test_should_contain_build_flow_intent": 0.096, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestTranslationPromptBuildFlow::test_should_have_build_flow_examples": 0.041, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestTranslationPromptBuildFlow::test_should_have_simple_chat_flow_example": 0.144, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant.py::TestTranslationPromptBuildFlow::test_should_prefer_build_flow_when_ambiguous": 0.077, + "src/backend/tests/unit/agentic/flows/test_flow_builder_assistant_force_isolation.py::TestBuildToolkitBindsForceIsolation::test_should_bind_user_id_and_force_isolation_when_user_context_set": 0.031, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_build_config_for_anthropic": 0.039, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_build_config_for_azure_openai": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_build_config_for_google": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_build_config_for_groq": 0.044, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_build_config_for_openai": 0.042, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_default_to_openai_for_unknown_provider": 0.044, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestBuildModelConfig::test_should_include_context_length": 0.045, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_configure_chat_input": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_configure_chat_output": 0.038, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_create_graph_with_default_provider": 0.04, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_create_graph_with_start_and_end": 0.038, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_include_api_key_when_provided": 0.038, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_not_include_api_key_when_not_provided": 0.042, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_set_low_temperature": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_set_system_message": 0.038, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestGetGraph::test_should_use_provided_provider_and_model": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestTranslationPrompt::test_should_contain_examples": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestTranslationPrompt::test_should_contain_intent_classification_instructions": 0.042, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestTranslationPrompt::test_should_contain_translation_instructions": 0.044, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestTranslationPrompt::test_should_distinguish_how_to_from_create": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow.py::TestTranslationPrompt::test_should_specify_json_output_format": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestFileQuestionDisambiguationStillHolds::test_translation_prompt_should_include_disambiguation_rule_for_file_question": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestFollowUpSessionContextRouting::test_translation_prompt_should_reference_session_context_block": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestFollowUpSessionContextRouting::test_translation_prompt_should_route_contextual_followup_to_build_flow": 0.042, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestFollowUpSessionContextRouting::test_translation_prompt_should_translate_only_user_message_not_context": 0.038, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestManageFilesIntentDeclared::test_translation_prompt_should_include_manage_files_example_in_english": 0.04, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestManageFilesIntentDeclared::test_translation_prompt_should_include_manage_files_example_in_portuguese": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestManageFilesIntentDeclared::test_translation_prompt_should_list_manage_files_intent": 0.041, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestManageFilesIntentDeclared::test_translation_prompt_should_not_classify_file_creation_examples_as_build_flow": 0.04, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestRunFlowIntentDeclared::test_prompt_declares_run_flow_intent": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestRunFlowIntentDeclared::test_prompt_has_run_flow_examples": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow_intents.py::TestRunFlowIntentDeclared::test_run_examples_are_not_classified_as_build_flow": 0.044, + "src/backend/tests/unit/agentic/flows/test_translation_flow_requested_model.py::test_prompt_should_declare_requested_model_in_output_format": 0.042, + "src/backend/tests/unit/agentic/flows/test_translation_flow_requested_model.py::test_prompt_should_include_an_example_that_names_a_model": 0.043, + "src/backend/tests/unit/agentic/flows/test_translation_flow_requested_model.py::test_prompt_should_include_an_example_with_empty_model_when_none_named": 0.045, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_be_idempotent_when_workspace_already_exists": 0.042, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_create_parent_dirs_when_missing": 0.039, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_create_workspace_dir_if_missing": 0.04, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_expanduser_in_env_var": 0.041, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_fall_back_to_default_when_env_var_is_blank": 0.039, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_resolve_to_default_when_env_unset": 0.036, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_resolve_to_env_var_when_set": 0.038, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_return_none_when_isolation_module_is_present": 0.04, + "src/backend/tests/unit/agentic/helpers/test_assistant_workspace.py::TestResolveAssistantFsRoot::test_should_strip_whitespace_from_env_var": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_os_popen": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_os_remove": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_os_system": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_shutil_rmtree": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_subprocess_popen": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_subprocess_run": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousAttrCalls::test_should_detect_sys_exit": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousCalls::test_should_detect_compile": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousCalls::test_should_detect_dunder_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousCalls::test_should_detect_eval": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousCalls::test_should_detect_exec": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousCalls::test_should_detect_globals": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_allow_os_import_itself": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_allow_os_path_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_detect_ctypes_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_detect_from_subprocess_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_detect_pickle_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_detect_restricted_os_import": 0.04, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_detect_shutil_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityDangerousImports::test_should_detect_subprocess_import": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityEdgeCases::test_should_handle_empty_code": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityEdgeCases::test_should_handle_none_like_empty": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityEdgeCases::test_should_handle_syntax_error_gracefully": 0.04, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityEdgeCases::test_should_handle_whitespace_only": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityEdgeCases::test_violations_is_tuple": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_detect_builtins_escape": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_detect_func_globals_escape": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_detect_os_environ_secret_read": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_detect_os_getenv_secret_read": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_detect_raw_open_file_access": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_detect_subclasses_sandbox_escape": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_still_allow_getattr": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_still_allow_http_requests": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityExfiltrationAndEscapes::test_should_still_allow_os_path": 0.042, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityMultipleViolations::test_should_detect_import_and_call_violations": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecurityMultipleViolations::test_should_report_all_violations": 0.04, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecuritySafeCode::test_should_pass_basic_component": 0.039, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecuritySafeCode::test_should_pass_http_requests": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecuritySafeCode::test_should_pass_json_operations": 0.043, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecuritySafeCode::test_should_pass_math_operations": 0.041, + "src/backend/tests/unit/agentic/helpers/test_code_security.py::TestScanCodeSecuritySafeCode::test_should_pass_os_path_usage": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestBugsAndEdgeCases::test_extract_friendly_error_with_none_input_crashes": 0.043, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestBugsAndEdgeCases::test_multiple_pattern_match_returns_first": 0.042, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestBugsAndEdgeCases::test_or_in_pattern_match_second_branch_is_redundant": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestBugsAndEdgeCases::test_truncate_exact_limit_plus_one": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestBugsAndEdgeCases::test_truncate_off_by_one_at_min_length": 0.032, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestConstants::test_max_error_message_length_is_reasonable": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestConstants::test_min_meaningful_part_length_is_reasonable": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestErrorPatterns::test_each_pattern_should_have_friendly_message": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestErrorPatterns::test_should_have_expected_pattern_categories": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_be_case_insensitive": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_handle_empty_string": 0.04, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_authentication_error": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_connection_error": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_content_policy_error": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_model_not_found": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_quota_error": 0.039, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_rate_limit_error": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_schema_validation_error_from_weak_model": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_server_error": 0.04, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_friendly_message_for_timeout_error": 0.04, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_return_original_for_short_unknown_errors": 0.05, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestExtractFriendlyError::test_should_truncate_unknown_error_messages": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestTruncateErrorMessage::test_should_extract_meaningful_part_from_colon_separated": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestTruncateErrorMessage::test_should_handle_message_at_exact_limit": 0.042, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestTruncateErrorMessage::test_should_return_original_for_short_messages": 0.04, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestTruncateErrorMessage::test_should_skip_too_short_parts_after_colon": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling.py::TestTruncateErrorMessage::test_should_truncate_long_messages": 0.043, + "src/backend/tests/unit/agentic/helpers/test_error_handling_diagnostic_preservation.py::TestPreservesExistingFriendlyMappings::test_should_still_map_authentication": 0.043, + "src/backend/tests/unit/agentic/helpers/test_error_handling_diagnostic_preservation.py::TestPreservesExistingFriendlyMappings::test_should_still_map_rate_limit": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling_diagnostic_preservation.py::TestPreservesUnderlyingCauseForWrappedErrors::test_should_cap_at_max_length_even_when_preserving_cause": 0.041, + "src/backend/tests/unit/agentic/helpers/test_error_handling_diagnostic_preservation.py::TestPreservesUnderlyingCauseForWrappedErrors::test_should_surface_underlying_message_for_generic_component_wrap": 0.042, + "src/backend/tests/unit/agentic/helpers/test_error_handling_diagnostic_preservation.py::TestPreservesUnderlyingCauseForWrappedErrors::test_should_surface_underlying_message_when_component_wraps_provider_error": 0.04, + "src/backend/tests/unit/agentic/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_forwards_flow_preview_events": 0.04, + "src/backend/tests/unit/agentic/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_forwards_tokens_and_flow_preview": 0.039, + "src/backend/tests/unit/agentic/helpers/test_event_consumer.py::TestParseEventData::test_parse_empty_data": 0.042, + "src/backend/tests/unit/agentic/helpers/test_event_consumer.py::TestParseEventData::test_parse_flow_preview_event": 0.039, + "src/backend/tests/unit/agentic/helpers/test_event_consumer.py::TestParseEventData::test_parse_token_event": 0.04, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestRefusalMessage::test_refusal_message_is_not_empty": 0.042, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestRefusalMessage::test_refusal_message_mentions_langflow": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_act_in_legitimate_context": 0.04, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_component_generation_request": 0.04, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_empty_input": 0.04, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_ignore_in_legitimate_context": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_normal_langflow_question": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_portuguese_question": 0.039, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputCleanInputs::test_should_pass_system_in_legitimate_context": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_case_insensitive": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_disregard_instructions": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_forget_instructions": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_ignore_above_instructions": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_ignore_previous_instructions": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_mixed_case": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_override_keyword": 0.04, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_raw_delimiter_sysml": 0.042, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_raw_delimiter_system": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_role_hijacking_act_as": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_role_hijacking_pretend": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_role_hijacking_you_are_now": 0.042, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_system_prompt_extraction_reveal": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputInjectionDetection::test_should_detect_system_prompt_extraction_what_are": 0.042, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputNormalization::test_should_preserve_normal_newlines_as_space": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputNormalization::test_should_remove_null_bytes": 0.042, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputNormalization::test_should_strip_excessive_whitespace": 0.041, + "src/backend/tests/unit/agentic/helpers/test_input_sanitization.py::TestSanitizeInputNormalization::test_should_truncate_long_input": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestBugsAndEdgeCases::test_attempt_greater_than_max_accepted": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestBugsAndEdgeCases::test_format_cancelled_event_structure": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestBugsAndEdgeCases::test_negative_attempt_accepted_without_validation": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestBugsAndEdgeCases::test_newlines_in_values_are_json_escaped": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestBugsAndEdgeCases::test_non_serializable_data_crashes_without_handling": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatCompleteEvent::test_should_format_complete_event_with_data": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatCompleteEvent::test_should_format_complete_event_with_empty_data": 0.04, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatCompleteEvent::test_should_preserve_nested_data_structure": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatErrorEvent::test_should_format_error_event_with_empty_message": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatErrorEvent::test_should_format_error_event_with_message": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatErrorEvent::test_should_preserve_special_characters_in_message": 0.042, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatFlowUpdateEventProposePlan::test_should_emit_flow_update_event_with_propose_plan_action": 0.042, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatFlowUpdateEventProposePlan::test_should_keep_event_type_when_action_is_propose_plan": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatFlowUpdateEventProposePlan::test_should_preserve_markdown_with_newlines_as_escaped_json": 0.04, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[extracting_code]": 0.04, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[generating]": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[generation_complete]": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[retrying]": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[validated]": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[validating]": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_accept_all_valid_step_types[validation_failed]": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_format_basic_progress_event": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_include_all_optional_fields": 0.042, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_include_optional_class_name": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_include_optional_component_code": 0.046, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_include_optional_error": 0.04, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_include_optional_message": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatProgressEvent::test_should_omit_none_optional_fields": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatTokenEvent::test_should_format_token_event_with_chunk": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatTokenEvent::test_should_format_token_event_with_empty_chunk": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatTokenEvent::test_should_handle_unicode_in_chunk": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatTokenEvent::test_should_preserve_newlines_in_chunk": 0.04, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestFormatTokenEvent::test_should_preserve_whitespace_in_chunk": 0.041, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestSSEFormatConsistency::test_all_events_should_have_consistent_format": 0.04, + "src/backend/tests/unit/agentic/helpers/test_sse.py::TestSSEFormatConsistency::test_events_should_produce_valid_json": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractClassNameRegex::test_should_extract_class_name_from_component_subclass": 0.042, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractClassNameRegex::test_should_extract_from_custom_component_subclass": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractClassNameRegex::test_should_extract_from_multi_parent_class": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractClassNameRegex::test_should_return_none_for_empty_code": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractClassNameRegex::test_should_return_none_when_no_component_class": 0.04, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractIONames::test_should_detect_overlapping_names": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractIONames::test_should_extract_input_and_output_names": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractIONames::test_should_ignore_starred_elements_in_inputs": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractIONames::test_should_return_empty_sets_when_class_not_found": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractIONames::test_should_return_empty_sets_when_no_io": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractOutputMethods::test_should_extract_method_names": 0.042, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractOutputMethods::test_should_return_empty_list_when_class_not_found": 0.042, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestExtractOutputMethods::test_should_return_empty_list_when_no_outputs": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestSafeExtractClassName::test_should_fallback_to_regex_on_syntax_error": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestSafeExtractClassName::test_should_fallback_to_regex_on_type_error": 0.042, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestSafeExtractClassName::test_should_fallback_to_regex_on_value_error": 0.04, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestSafeExtractClassName::test_should_use_ast_when_available": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_handle_component_with_no_outputs": 0.049, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_not_execute_code_during_validation": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_preserve_code_in_result": 0.047, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_return_invalid_on_syntax_error": 0.047, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_return_invalid_when_no_class_name": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_return_invalid_when_output_method_has_no_return": 0.04, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_return_invalid_when_overlapping_io_names": 0.047, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentCode::test_should_return_valid_for_well_formed_component": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentRuntimeExecution::test_should_accept_valid_component_that_consumes_an_input": 0.035, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentRuntimeExecution::test_should_accept_valid_component_with_dict_input": 0.034, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentRuntimeExecution::test_should_reject_component_whose_output_returns_non_dict_built_from_input": 0.033, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentRuntimeExecution::test_should_return_error_when_output_method_builds_data_with_list_payload": 0.043, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentRuntimeExecution::test_should_return_error_when_output_method_builds_message_with_wrong_type": 0.042, + "src/backend/tests/unit/agentic/helpers/test_validation.py::TestValidateComponentRuntimeExecution::test_should_return_none_when_output_method_builds_valid_data": 0.035, + "src/backend/tests/unit/agentic/helpers/test_validation_reserved_name.py::TestRejectReservedOutputName::test_should_accept_well_named_output": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation_reserved_name.py::TestRejectReservedOutputName::test_should_reject_method_to_toolkit": 0.041, + "src/backend/tests/unit/agentic/helpers/test_validation_reserved_name.py::TestRejectReservedOutputName::test_should_reject_output_name_component_as_tool": 0.041, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestEdgeCases::test_should_handle_empty_list": 0.043, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestEdgeCases::test_should_handle_multiple_dicts": 0.042, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestEdgeCases::test_should_handle_non_dict_items": 0.041, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestNormalValues::test_should_keep_empty_string": 0.042, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestNormalValues::test_should_keep_normal_values": 0.044, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestReplaceNanValues::test_should_replace_infinity_string": 0.041, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestReplaceNanValues::test_should_replace_nan_float": 0.04, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestReplaceNanValues::test_should_replace_nan_string": 0.042, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestReplaceNoneValues::test_should_replace_none_with_not_available": 0.039, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestReplaceNoneValues::test_should_replace_null_string_case_insensitive": 0.041, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestRequiredFields::test_should_add_missing_required_fields": 0.04, + "src/backend/tests/unit/agentic/mcp/test_support.py::TestRequiredFields::test_should_handle_no_required_fields": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestBugsAndEdgeCases::test_consume_non_dict_data_should_not_crash": 0.004, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestBugsAndEdgeCases::test_consume_timeout_without_cancel_continues_loop": 0.007, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestBugsAndEdgeCases::test_parse_event_data_invalid_json_raises": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestBugsAndEdgeCases::test_parse_event_data_missing_event_key": 0.643, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestBugsAndEdgeCases::test_parse_event_data_non_dict_data_field": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_check_cancel_during_timeout": 0.006, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_check_disconnection_callback": 0.005, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_handle_unicode_decode_errors": 0.039, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_ignore_disconnection_check_errors": 0.425, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_skip_events_with_empty_chunk": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_skip_malformed_json_events": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_stop_on_none_sentinel": 0.541, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_yield_cancelled_on_cancel_event": 1.043, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_yield_end_event_and_stop": 0.039, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestConsumeStreamingEvents::test_should_yield_token_events": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_handle_event_without_data_field": 0.039, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_handle_nested_data": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_handle_unicode_content": 1.045, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_parse_end_event": 0.044, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_parse_token_event": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_return_none_for_empty_data": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_event_consumer.py::TestParseEventData::test_should_return_none_for_whitespace": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestBugsAndEdgeCases::test_load_graph_returns_none_from_get_graph": 0.038, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestBugsAndEdgeCases::test_resolve_flow_path_empty_string_returns_directory": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestBugsAndEdgeCases::test_resolve_flow_path_only_extension_literal": 0.043, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestBugsAndEdgeCases::test_resolve_flow_path_traversal_escape": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestBugsAndEdgeCases::test_sys_modules_uses_stem_as_module_name": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestBugsAndEdgeCases::test_temporary_sys_path_crashes_if_path_removed_during_context": 0.043, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphForExecution::test_should_pass_api_key_var_to_loader": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphForExecution::test_should_use_json_loader_for_json_type": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphForExecution::test_should_use_python_loader_for_python_type": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_cleanup_sys_modules_on_success": 0.031, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_fallback_to_graph_variable": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_load_graph_from_get_graph_function": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_pass_provider_params_to_get_graph": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_raise_500_on_module_execution_error": 0.038, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_raise_500_when_no_get_graph_or_graph": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_raise_500_when_spec_is_none": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_raise_validation_error_for_blocked_python_graph": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestLoadGraphFromPython::test_should_support_async_get_graph": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_fallback_to_json_when_python_not_found": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_prefer_python_over_json_when_both_exist": 0.044, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_raise_404_when_flow_not_found": 0.051, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_reject_filename_with_backslash_traversal": 0.045, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_reject_filename_with_path_traversal_sequences": 0.045, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_return_json_path_for_explicit_json_extension": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestResolveFlowPath::test_should_return_python_path_for_explicit_py_extension": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestTemporarySysPath::test_should_add_path_to_sys_path_temporarily": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestTemporarySysPath::test_should_not_duplicate_existing_path": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_flow_loader.py::TestTemporarySysPath::test_should_remove_path_even_on_exception": 0.043, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_default_to_question_on_empty_response": 0.046, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_default_to_question_on_flow_error": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_extract_build_flow_intent_from_plaintext": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_extract_intent_from_text_containing_generate_component": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_extract_json_from_markdown_code_block": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_extract_json_with_surrounding_text": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_extract_off_topic_intent_from_plaintext": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_extract_run_flow_intent_from_plaintext": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_handle_missing_intent_field": 0.043, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_handle_missing_translation_field": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_handle_non_json_response": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_not_match_bare_intent_substring_in_prompt_echo": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_not_pass_session_id_to_flow": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_pass_all_parameters_to_flow": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_return_generate_component_intent": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_return_question_for_empty_text": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_return_question_intent": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntent::test_should_use_translation_flow_filename": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentTokenUsage::test_should_expose_tokens_from_translation_flow_result": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentTokenUsage::test_should_not_leak_metrics_key_to_extract_response_text": 0.038, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentTokenUsage::test_should_return_none_tokens_when_translation_flow_metrics_are_missing": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentTokenUsage::test_should_return_none_tokens_when_translation_flow_times_out": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentWithContext::test_should_include_context_in_flow_input_when_context_provided": 0.043, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentWithContext::test_should_send_only_text_when_context_is_none": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestClassifyIntentWithContext::test_should_still_parse_intent_when_context_provided": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestCompoundComponentFlowClassification::test_json_path_returns_component_then_flow": 0.039, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestCompoundComponentFlowClassification::test_non_json_fallback_extracts_component_then_flow": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicEditContinuation::test_continuation_signal_forces_flow_request_without_llm": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicPlanApproval::test_plan_approval_signal_forces_flow_request_without_llm": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicRunFlowDetection::test_does_not_override_a_confident_build_flow_classification": 0.036, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicRunFlowDetection::test_does_not_override_a_confident_compound_classification": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicRunFlowDetection::test_flow_word_without_run_verb_is_not_forced": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicRunFlowDetection::test_non_run_requests_still_go_through_the_llm": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicRunFlowDetection::test_rescues_run_request_in_any_language_via_english_translation": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestDeterministicRunFlowDetection::test_rescues_run_request_only_when_classifier_says_question": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestIntentResult::test_should_allow_generate_component_intent": 0.043, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestIntentResult::test_should_be_comparable": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_classification.py::TestIntentResult::test_should_create_with_translation_and_intent": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_build_context_with_canvas_summary_when_no_turns": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_build_context_with_turns_oldest_first": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_frame_block_as_quoted_context_not_instructions": 0.04, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_keep_the_most_recent_turn_when_over_budget": 0.042, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_return_none_when_no_turns_and_blank_canvas_summary": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_return_none_when_no_turns_and_no_canvas": 0.041, + "src/backend/tests/unit/agentic/services/helpers/test_intent_context.py::test_should_truncate_when_context_exceeds_max_chars": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_build_run_apply.py::TestBuildAndRunAlwaysApplies::test_decision_is_wording_agnostic_even_when_run_regex_misses": 0.048, + "src/backend/tests/unit/agentic/services/test_assistant_service_build_run_apply.py::TestBuildAndRunAlwaysApplies::test_set_flow_and_flow_ran_same_batch_auto_applies_no_gate": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_build_run_apply.py::TestBuildAndRunAlwaysApplies::test_set_flow_then_run_in_later_batch_reapplies": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_build_run_apply.py::TestNoRegression::test_build_only_no_run_stays_a_gated_proposal": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_build_run_apply.py::TestNoRegression::test_build_only_then_no_run_never_double_emits": 0.03, + "src/backend/tests/unit/agentic/services/test_assistant_service_build_run_apply.py::TestNoRegression::test_compound_still_auto_applies": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_component_failure.py::test_should_append_caveat_to_final_message_when_flow_substitutes_failed_component": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_component_failure.py::test_should_not_append_caveat_when_no_component_failed": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_component_failure.py::test_should_yield_validation_failed_when_component_sub_task_fails": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_documents.py::TestFormatFileWrittenEvent::test_format_file_written_event_should_carry_action_path_and_size": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_documents.py::TestFormatFileWrittenEvent::test_format_file_written_event_should_refuse_absolute_path": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_documents.py::TestStepTypeIncludesGeneratingDocument::test_step_type_should_include_generating_document": 0.044, + "src/backend/tests/unit/agentic/services/test_assistant_service_documents.py::TestStreamingEmitsFileWrittenEvents::test_stream_should_emit_generating_document_step_for_manage_files": 0.049, + "src/backend/tests/unit/agentic/services/test_assistant_service_documents.py::TestStreamingEmitsFileWrittenEvents::test_stream_should_yield_file_written_when_file_events_pending": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_summary.py::TestFlowSummaryBadUuid::test_should_skip_context_without_db_call_when_flow_id_is_not_a_uuid": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_summary.py::TestFlowSummaryHardCap::test_should_pass_through_when_summary_is_within_cap": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_summary.py::TestFlowSummaryHardCap::test_should_truncate_when_summary_exceeds_max_chars": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_summary.py::TestFlowSummaryOwnership::test_should_return_none_when_flow_belongs_to_another_user": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_summary.py::TestFlowSummaryOwnership::test_should_return_summary_when_caller_owns_the_flow": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_verification.py::TestCharacterizationNoFlowIdPath::test_should_emit_flow_proposal_ready_then_one_complete_without_caveat": 0.038, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_verification.py::TestFlowVerificationDeliversHonestCaveat::test_kill_switch_disables_verification": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_flow_verification.py::TestFlowVerificationDeliversHonestCaveat::test_should_deliver_caveat_when_built_flow_run_fails_non_fixably": 0.034, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::TestCrossTenantIsolation::test_should_not_leak_history_to_a_different_user_with_the_same_session_id": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::TestCrossTenantIsolation::test_should_still_return_owner_history_when_same_user_reuses_session_id": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_inject_history_should_prefix_input_with_oldest_first_turns": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_inject_history_should_return_unchanged_input_when_no_session_history": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_inject_history_should_return_unchanged_input_when_session_id_none": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_inject_history_should_return_unchanged_input_when_user_id_none": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_record_turn_should_push_completed_exchange_to_buffer": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_record_turn_should_skip_empty_responses": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_record_turn_should_skip_when_session_id_none": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history.py::test_record_turn_should_skip_when_user_id_none": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_history_clear.py::test_clear_session_history_should_be_idempotent_for_unknown_session": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_history_clear.py::test_clear_session_history_should_drop_the_named_session": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_history_clear.py::test_clear_session_history_should_not_drop_other_users_session_with_same_id": 0.046, + "src/backend/tests/unit/agentic/services/test_assistant_service_history_clear.py::test_clear_session_history_should_skip_when_session_id_none": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_history_clear.py::test_clear_session_history_should_skip_when_user_id_none": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_intent_context.py::test_should_load_current_flow_summary_only_once_per_request": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_intent_context.py::test_should_not_leak_working_flow_when_off_topic_after_canvas_seed": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_intent_context.py::test_should_pass_none_context_to_classify_intent_for_fresh_session": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_intent_context.py::test_should_pass_session_context_to_classify_intent_when_session_has_prior_turns": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestProgressEventSequence::test_should_emit_full_success_sequence": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestProgressEventSequence::test_should_emit_retry_sequence_on_failure": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestProgressEventSequence::test_should_end_with_complete_event_on_max_retries": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestProgressEventSequence::test_should_end_with_complete_event_on_success": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestQADoesNotIncludeCode::test_should_not_include_component_code_in_qa_progress": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestRetryingStepIncludesError::test_should_include_error_in_retrying_event": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestRetryingStepIncludesError::test_should_include_retry_attempt_info_in_retrying_event": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestValidatingStepIncludesCode::test_should_include_component_code_before_validation_result": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestValidatingStepIncludesCode::test_should_include_component_code_in_validating_event": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestValidationFailedIncludesDetails::test_should_include_error_and_code_in_validation_failed": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_intermediate_visibility.py::TestValidationFailedIncludesDetails::test_should_include_message_in_validation_failed": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_model_fallback.py::TestModelFallbackOnModelNotFound::test_should_emit_clear_error_naming_provider_when_all_models_exhausted": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_model_fallback.py::TestModelFallbackOnModelNotFound::test_should_fall_back_to_next_model_when_default_returns_model_not_found": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_model_fallback.py::TestModelFallbackOnModelNotFound::test_should_not_fall_back_for_non_model_unavailable_errors": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_no_action_guard.py::test_should_emit_error_not_fake_success_when_no_action_retries_exhausted": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_no_action_guard.py::test_should_not_guard_question_intent_text_only": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_no_action_guard.py::test_should_retry_build_flow_when_agent_emits_no_canvas_actions": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_no_action_guard.py::test_should_succeed_build_flow_when_set_flow_emitted": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_retry_bounds.py::TestRetryLoopBoundary::test_should_return_domain_error_when_max_retries_is_negative": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_available_model_hint_injected_when_provider_and_model_given": 0.942, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_build_flow_that_also_runs_emits_orchestrating_step": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_build_flow_truly_no_action_still_guarded_regression": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_complete_does_not_flag_continuation_for_pure_edit": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_complete_flags_continuation_expected_for_edit_plus_run": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_compound_request_emits_orchestrating_step": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_compound_set_flow_auto_applies_without_continue_gate": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_flow_request_does_not_show_false_planning_label": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_pure_build_without_run_does_not_emit_orchestrating": 0.043, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_run_flow_intent_does_not_trip_no_action_guard": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_run_flow_intent_routes_to_flow_builder_without_plan_gate": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_run_intent.py::test_single_ask_build_flow_still_gates_and_does_not_auto_apply": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestCodeSecurityIntegration::test_non_streaming_should_block_dangerous_code": 0.954, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestCodeSecurityIntegration::test_streaming_should_block_dangerous_code": 0.006, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestCodeSecurityIntegration::test_streaming_should_pass_safe_code": 0.009, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestInputSanitizationIntegration::test_non_streaming_should_block_injection": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestInputSanitizationIntegration::test_streaming_should_block_injection_before_classify_intent": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestInputSanitizationIntegration::test_streaming_should_pass_clean_input": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestOffTopicIntegration::test_streaming_should_allow_question_intent": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_security.py::TestOffTopicIntegration::test_streaming_should_reject_off_topic": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestBuildAndRunAutoApply::test_build_plus_run_sets_auto_apply_and_skips_the_continue_gate": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestCancellation::test_should_emit_cancelled_event_on_disconnect": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestComponentGeneration::test_should_emit_progress_events_on_successful_validation": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestComponentGeneration::test_should_retry_on_validation_failure": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestComponentGeneration::test_should_return_error_when_max_retries_exhausted": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestCompoundOrchestration::test_compound_routes_to_single_agent_loop_no_phase_recursion": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestCurrentUserIdContextVarIsolation::test_should_not_leak_current_user_id_when_pre_try_setup_raises": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestErrorHandling::test_should_emit_complete_event_with_validated_false_when_all_attempts_raise": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestErrorHandling::test_should_emit_error_event_on_http_exception": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestErrorHandling::test_should_emit_error_when_no_result": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestErrorHandling::test_should_retry_component_generation_when_flow_execution_raises": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestFlowProposalReady::test_should_emit_flow_proposal_ready_before_complete_event": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestFlowProposalReady::test_should_emit_flow_proposal_ready_when_build_flow_intent_with_set_flow_event": 0.038, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestFlowProposalReady::test_should_not_emit_flow_proposal_ready_for_generate_component_intent": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestFlowProposalReady::test_should_not_emit_flow_proposal_ready_for_question_intent": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestFlowProposalReady::test_should_not_emit_flow_proposal_ready_when_build_flow_intent_with_only_incremental_edits": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestIntentClassificationCall::test_should_call_classify_intent_without_session_id": 0.04, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestIntentClassificationCall::test_should_pass_provider_and_model_to_classify_intent": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestQAResponse::test_should_return_plain_text_for_qa_with_component_code": 0.042, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestQAResponse::test_should_return_plain_text_for_qa_without_code": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_streaming.py::TestQAResponse::test_should_return_plain_text_when_question_response_contains_example_code": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_token_usage.py::TestAssistantPerTurnUsageReporting::test_should_emit_only_intent_usage_when_intent_is_off_topic": 0.038, + "src/backend/tests/unit/agentic/services/test_assistant_service_token_usage.py::TestAssistantPerTurnUsageReporting::test_should_emit_zero_usage_when_sanitization_blocks_request": 0.041, + "src/backend/tests/unit/agentic/services/test_assistant_service_token_usage.py::TestAssistantPerTurnUsageReporting::test_should_not_leak_metrics_key_into_complete_event_data": 0.038, + "src/backend/tests/unit/agentic/services/test_assistant_service_token_usage.py::TestAssistantPerTurnUsageReporting::test_should_sum_intent_and_agent_tokens_in_complete_event": 0.039, + "src/backend/tests/unit/agentic/services/test_assistant_service_token_usage.py::TestAssistantPerTurnUsageReporting::test_should_treat_missing_intent_tokens_as_zero": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestConcurrency::test_concurrent_pushes_to_same_session_should_preserve_all_turns": 0.04, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestConversationTurnPayload::test_format_for_prompt_should_render_a_compact_user_assistant_block": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestCrossTenantIsolation::test_clear_should_only_affect_the_calling_users_partition": 0.042, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestCrossTenantIsolation::test_get_recent_should_return_empty_for_a_different_user_with_the_same_session_id": 0.042, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestCrossTenantIsolation::test_push_should_not_co_mingle_into_a_different_user_with_the_same_session_id": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestLRUEviction::test_push_should_evict_oldest_session_when_max_sessions_exceeded": 0.04, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestLRUEviction::test_push_should_refresh_session_on_use_so_recently_used_stays": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestPushAndGetRecent::test_get_recent_should_return_empty_list_when_session_unknown": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestPushAndGetRecent::test_get_recent_should_return_turns_in_oldest_first_order": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestPushAndGetRecent::test_get_recent_with_explicit_limit_should_return_only_last_n": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestPushAndGetRecent::test_push_should_cap_at_max_turns_per_session": 0.04, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestPushAndGetRecent::test_push_then_get_recent_should_return_the_pushed_turn": 0.04, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestSessionIsolation::test_clear_should_be_idempotent_on_unknown_session": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestSessionIsolation::test_clear_should_drop_only_the_named_session": 0.042, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::TestSessionIsolation::test_get_recent_should_isolate_sessions": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::test_module_constants_are_within_expected_bounds[max_turns_assertion0]": 0.041, + "src/backend/tests/unit/agentic/services/test_conversation_buffer.py::test_module_constants_are_within_expected_bounds[max_turns_assertion1]": 0.042, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestContextIsolation::test_file_events_should_be_isolated_across_contexts": 0.041, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestContextIsolation::test_file_events_should_be_shared_across_asyncio_tasks_within_same_request": 0.04, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestDrainAndEmitInIsolation::test_drain_file_events_should_clear_queue_after_drain": 0.041, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestDrainAndEmitInIsolation::test_drain_file_events_should_return_empty_when_no_emits": 0.042, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestDrainAndEmitInIsolation::test_emit_file_event_should_preserve_order_when_multiple_events": 0.041, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestDrainAndEmitInIsolation::test_emit_file_event_should_queue_event_with_action_path_and_size": 0.041, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestDrainAndEmitInIsolation::test_reset_file_events_should_clear_pending_entries": 0.042, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestPayloadShape::test_emit_file_event_should_reject_absolute_path": 0.045, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestPayloadShape::test_emit_file_event_should_reject_empty_action": 0.046, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestPayloadShape::test_emit_file_event_should_reject_empty_path": 0.048, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestPayloadShape::test_emit_file_event_should_reject_negative_size": 0.044, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestPayloadShape::test_emit_file_event_should_reject_path_with_drive_letter": 0.045, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_emit_file_written_on_success": 0.041, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_emit_with_provided_action": 0.041, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_not_emit_when_response_carries_error": 0.038, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_not_emit_when_response_has_no_path": 0.037, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_not_emit_when_response_is_not_json": 0.035, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_propagate_kwargs_to_inner_func": 0.037, + "src/backend/tests/unit/agentic/services/test_file_events.py::TestWrapFileToolWithEvent::test_wrapped_tool_should_refuse_emit_with_absolute_path_in_response": 0.034, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_be_resilient_to_malformed_nodes_and_empty_flow": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_flag_agent_with_empty_model_field": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_flag_agent_with_legacy_provider_but_no_model_name": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_flag_agent_with_no_model_field_at_all": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_flag_only_the_agents_that_lack_a_model_when_several_exist": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_ignore_non_agent_nodes_even_if_they_have_a_model_field": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_not_flag_agent_using_legacy_agent_llm_and_model_name": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_agent_model.py::TestFindAgentsMissingModel::test_should_not_flag_agent_with_a_configured_model": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_agent_model_ensure.py::TestEnsureAgentModels::test_should_inject_the_request_model_when_an_agent_lacks_one": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_agent_model_ensure.py::TestEnsureAgentModels::test_should_not_loop_or_raise_when_provider_is_unknown": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_agent_model_ensure.py::TestEnsureAgentModels::test_should_report_no_provider_when_request_has_no_usable_model": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_agent_model_ensure.py::TestEnsureAgentModels::test_should_return_none_needed_when_no_agent_is_missing_a_model": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestBugsAndEdgeCases::test_execute_flow_file_context_none_crashes": 0.007, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestBugsAndEdgeCases::test_execution_result_empty_dict_should_have_result": 0.059, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestBugsAndEdgeCases::test_extract_response_text_empty_dict": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestBugsAndEdgeCases::test_extract_response_text_with_none_crashes": 0.062, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestBugsAndEdgeCases::test_run_graph_context_none_crashes": 0.017, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestBugsAndEdgeCases::test_run_graph_global_vars_overwrite_existing": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestConstants::test_flows_base_path_should_point_to_flows_directory": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestConstants::test_streaming_queue_max_size_should_be_reasonable": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestConstants::test_streaming_timeout_should_be_reasonable": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_execute_flow_with_model_injection": 0.038, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_inject_global_variables": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_raise_400_for_custom_component_validation_error": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_raise_404_for_missing_flow_file": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_raise_500_on_execution_error": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_reraise_http_exception_as_is": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFile::test_should_set_user_and_session_on_loaded_graph": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileStreaming::test_should_raise_404_for_missing_flow_file": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileStreamingEvents::test_should_carry_original_error_internally_without_leaking_in_http_detail": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileStreamingEvents::test_should_handle_preparation_error": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileStreamingEvents::test_should_raise_http_on_execution_error": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileStreamingEvents::test_should_yield_cancelled_on_disconnect": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileStreamingEvents::test_should_yield_end_event_on_success": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileTokenMetrics::test_should_attach_metrics_to_end_event_when_streaming_succeeds": 0.038, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileTokenMetrics::test_should_attach_metrics_to_execute_flow_file_result": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileTokenMetrics::test_should_attach_zero_metrics_when_graph_has_no_token_usage": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExecuteFlowFileTokenMetrics::test_should_not_attach_metrics_when_execute_flow_file_result_is_non_dict": 0.036, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExtractResponseText::test_should_extract_from_exception_message": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExtractResponseText::test_should_extract_from_result_key": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExtractResponseText::test_should_extract_from_text_key": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExtractResponseText::test_should_handle_empty_dict": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExtractResponseText::test_should_prefer_result_over_text": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestExtractResponseText::test_should_return_string_representation_for_unknown_structure": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestFlowExecutionResult::test_should_allow_both_result_and_error": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestFlowExecutionResult::test_should_create_with_defaults": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestFlowExecutionResult::test_should_detect_error": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestFlowExecutionResult::test_should_detect_result": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestParseEventData::test_should_handle_event_without_data": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestParseEventData::test_should_parse_valid_event": 0.045, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestParseEventData::test_should_return_none_for_empty_data": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestParseEventData::test_should_return_none_for_whitespace_only": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestRunGraphWithEvents::test_should_inject_global_variables_into_context": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestRunGraphWithEvents::test_should_set_user_and_session_on_graph": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestRunGraphWithEvents::test_should_signal_completion_via_queue": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestRunGraphWithEvents::test_should_store_error_on_exception": 0.037, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_execute_flow_file_should_not_set_flow_id_when_global_vars_none": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_execute_flow_file_should_preserve_existing_flow_name": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_execute_flow_file_should_set_flow_id_from_global_variables": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_execute_flow_file_should_set_flow_name_to_filename": 0.062, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_run_graph_should_not_set_flow_id_when_missing": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_run_graph_should_preserve_existing_flow_name": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_run_graph_should_set_flow_id_from_global_variables": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_run_graph_should_set_flow_name_when_missing": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_executor.py::TestTracingIntegration::test_should_raise_400_for_custom_component_validation_error": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_graph_build_check.py::TestBuildCheck::test_should_be_ok_when_the_graph_builds": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_graph_build_check.py::TestBuildCheck::test_should_not_crash_on_an_unexpected_error": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_graph_build_check.py::TestBuildCheck::test_should_report_the_deterministic_build_error_when_construction_raises": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestAvailableModelProviders::test_detects_only_providers_with_a_configured_key": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestAvailableModelProviders::test_does_not_hardcode_openai": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestAvailableModelProviders::test_empty_or_blank_keys_yield_no_providers": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_handle_flow_without_filesystem_tool": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_inject_root_path_when_loading_assistant_flow": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_not_overwrite_explicit_root_path": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_replace_empty_root_path_for_filesystem_tool": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_replace_whitespace_only_root_path": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_skip_injection_for_explicit_root_path_when_resolver_returns_none": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_skip_injection_when_resolver_returns_none": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectAssistantFsRoot::test_should_skip_non_filesystem_nodes": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectLfxComponentsPath::test_should_handle_flow_without_nodes": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectLfxComponentsPath::test_should_not_modify_directory_path_when_value_is_not_sentinel": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectLfxComponentsPath::test_should_not_modify_non_directory_nodes": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectLfxComponentsPath::test_should_rewrite_directory_path_to_absolute_lfx_components_when_path_matches_sentinel": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectLfxComponentsPath::test_should_rewrite_sentinel_path_when_loading_assistant_flow": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_handle_flow_without_agent_nodes": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_handle_flow_without_model_in_template": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_include_extra_params_from_config": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_inject_model_into_agent_nodes": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_not_modify_non_agent_nodes": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_not_warn_on_the_normal_agent_path": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_use_provided_api_key_var": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_use_provider_default_api_key_var": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelIntoFlow::test_should_warn_when_an_agent_node_has_no_model_field": 0.037, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelPreservesExplicitModel::test_does_not_touch_a_cross_provider_model": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelPreservesExplicitModel::test_fills_in_an_empty_model_even_when_not_overwriting": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelPreservesExplicitModel::test_keeps_existing_same_provider_model_and_injects_only_the_key": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestInjectModelPreservesExplicitModel::test_overwrite_default_still_swaps_the_model": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestLoadAndPrepareFlow::test_should_load_and_inject_model": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestLoadAndPrepareFlow::test_should_parse_the_flow_file_once_and_reuse_it_across_requests": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_preparation.py::TestLoadAndPrepareFlow::test_should_return_original_when_no_provider": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_probe_input.py::TestApplyProbeInput::test_should_be_resilient_to_malformed_nodes": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_probe_input.py::TestApplyProbeInput::test_should_fill_every_empty_chatinput_when_there_are_several": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_probe_input.py::TestApplyProbeInput::test_should_handle_empty_or_missing_flow_data": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_probe_input.py::TestApplyProbeInput::test_should_inject_probe_value_into_empty_chatinput_and_report_applied": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_probe_input.py::TestApplyProbeInput::test_should_not_overwrite_a_chatinput_that_already_has_a_value": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_probe_input.py::TestApplyProbeInput::test_should_return_false_when_flow_has_no_chatinput": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractGraphTokenUsage::test_coerces_non_numeric_safely": 0.288, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractGraphTokenUsage::test_handles_dict_shaped_graph": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractGraphTokenUsage::test_ignores_vertices_without_result_or_usage": 0.124, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractGraphTokenUsage::test_sums_token_usage_across_vertices": 0.155, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractGraphTokenUsage::test_zeros_when_no_vertices": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_caps_result_length": 0.104, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_falls_back_to_results_when_no_messages": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_handles_dict_shaped_outputs": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_joins_multiple_messages_in_order": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_returns_chat_message_text": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_returns_sentinel_when_nothing": 0.111, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestExtractRunResultText::test_stringifies_list_message": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlow::test_run_error_returns_error_envelope_not_exception": 0.057, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlow::test_success_returns_result_text": 0.006, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlow::test_timeout_returns_error_not_hang": 0.005, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlow::test_timeout_still_reports_elapsed_and_partial_token_metrics": 0.128, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlowSecurityGate::test_should_refuse_on_secret_exfiltration_code": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlowSecurityGate::test_should_refuse_to_run_when_a_node_has_unsafe_code": 0.007, + "src/backend/tests/unit/agentic/services/test_flow_run.py::TestRunWorkingFlowSecurityGate::test_should_run_normally_when_code_is_safe": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_run_builtin_exemption.py::TestBuiltinExemption::test_should_block_unknown_component_type_when_code_has_violations": 0.245, + "src/backend/tests/unit/agentic/services/test_flow_run_builtin_exemption.py::TestBuiltinExemption::test_should_block_when_node_code_diverges_from_canonical": 0.245, + "src/backend/tests/unit/agentic/services/test_flow_run_builtin_exemption.py::TestBuiltinExemption::test_should_fall_back_to_scan_all_when_registry_lookup_raises": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_run_builtin_exemption.py::TestBuiltinExemption::test_should_pass_when_node_code_is_byte_identical_to_canonical": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run_builtin_exemption.py::TestBuiltinExemption::test_should_treat_trivial_whitespace_drift_as_identical": 0.244, + "src/backend/tests/unit/agentic/services/test_flow_run_error_classification.py::TestFixableErrors::test_should_classify_keyerror_as_fixable_not_external_even_when_it_mentions_api_key": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run_error_classification.py::TestTimeout::test_should_classify_as_timeout_when_run_timed_out": 0.082, + "src/backend/tests/unit/agentic/services/test_flow_run_error_classification.py::TestUnknownAndEmpty::test_should_be_case_insensitive": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_run_error_classification.py::TestUnknownAndEmpty::test_should_classify_empty_error_as_unknown[None]": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_run_error_classification.py::TestUnknownAndEmpty::test_should_classify_empty_error_as_unknown[]": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_run_error_classification.py::TestUnknownAndEmpty::test_should_classify_unmatched_error_as_unknown": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecContract::test_should_be_resilient_when_the_flow_cannot_be_serialized": 0.045, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecContract::test_should_not_leave_a_temp_file_behind": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecContract::test_should_report_ok_when_the_validator_finds_no_errors": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecContract::test_should_separate_warnings_from_errors_and_stay_ok_on_warnings_only": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecContract::test_should_skip_credentials_so_a_missing_user_key_is_not_a_blocking_error": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecContract::test_should_surface_errors_with_the_node_name_and_not_be_ok": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_static_validation.py::TestValidateFlowSpecRealReuse::test_should_flag_an_unknown_component_type_via_the_real_validator": 0.037, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_flows_base_path_parent_should_be_agentic": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_flows_base_path_should_exist": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_langflow_assistant_flow_should_be_string": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_max_validation_retries_should_be_positive": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_max_validation_retries_should_be_reasonable": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_streaming_queue_max_size_should_be_positive": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_streaming_queue_max_size_should_be_reasonable": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_streaming_timeout_should_be_positive": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_streaming_timeout_should_be_reasonable": 0.037, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_translation_flow_should_be_string": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestConstants::test_validation_ui_delay_should_be_small": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestFlowExecutionResult::test_should_allow_both_result_and_error": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestFlowExecutionResult::test_should_create_with_defaults": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestFlowExecutionResult::test_should_detect_error_when_set": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestFlowExecutionResult::test_should_detect_result_when_set": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestFlowExecutionResult::test_should_return_false_for_empty_dict_result": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestFlowExecutionResult::test_should_store_exception_details": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestIntentResult::test_should_allow_empty_translation": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestIntentResult::test_should_be_equality_comparable": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestIntentResult::test_should_create_with_translation_and_intent": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestIntentResult::test_should_support_generate_component_intent": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestValidationRetryTemplate::test_should_be_formattable_string": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestValidationRetryTemplate::test_should_format_with_error_and_code": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestValidationRetryTemplate::test_should_format_with_multiline_code": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestValidationRetryTemplate::test_should_include_fix_instruction": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestValidationRetryTemplate::test_should_reference_code": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_types.py::TestValidationRetryTemplate::test_should_reference_error": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::test_should_expose_max_flow_verification_attempts_constant_when_importing_flow_types": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_types.py::test_should_load_flow_verification_module_when_constant_is_present": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestLanguageAndWordingAgnostic::test_function_signature_takes_no_prompt": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestLateRunReconciliation::test_late_reconciliation_is_idempotent_across_batches": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestLateRunReconciliation::test_set_flow_proposed_then_run_in_later_batch_reemits_with_auto_apply": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestNoRegression::test_build_only_no_run_stays_a_proposal": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestNoRegression::test_compound_auto_apply_unchanged": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestNoRegression::test_compound_with_run_does_not_double_emit_set_flow": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestNoRegression::test_incremental_edits_pass_through_untouched": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestNoRegression::test_incremental_edits_plus_run_no_spurious_set_flow": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestNoRegression::test_run_only_batch_emits_no_events": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestSameBatchBuildAndRun::test_flow_ran_before_set_flow_in_same_batch_still_auto_applies": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestSameBatchBuildAndRun::test_flow_ran_is_internal_and_never_forwarded": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_update_reconciliation.py::TestSameBatchBuildAndRun::test_set_flow_then_flow_ran_same_batch_auto_applies": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_caveat_without_looping_when_no_provider_for_agent": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_fail_after_exhausting_attempts_on_a_persistent_error": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_fail_immediately_when_the_agent_cannot_fix": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_not_leak_a_secret_in_the_caveat": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_pass_silently_when_agent_model_was_auto_assigned": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_pass_when_static_and_build_ok_and_no_agent_needs_a_model": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_respect_a_custom_max_attempts_of_one": 0.044, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_retry_then_pass_when_a_tier1_error_is_fixed": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_validation.py::TestVerifyFlow::test_should_retry_then_pass_when_a_tier2_build_error_is_fixed": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_apply_probe_input_before_running": 0.043, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_fail_after_exhausting_attempts_on_a_persistent_fixable_error": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_not_leak_a_secret_in_the_caveat": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_respect_a_custom_max_attempts_of_one": 0.042, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_retry_then_pass_when_a_fixable_error_is_fixed": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_return_passed_when_first_run_succeeds": 0.04, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_stop_and_caveat_on_external_resource_error_without_retrying": 0.041, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_stop_and_caveat_on_timeout_without_retrying": 0.039, + "src/backend/tests/unit/agentic/services/test_flow_verification.py::TestVerifyBuiltFlow::test_should_stop_when_the_agent_cannot_produce_a_fix": 0.041, + "src/backend/tests/unit/agentic/services/test_generate_component_failure_signal.py::test_should_emit_validation_failed_signal_when_generation_fails": 0.04, + "src/backend/tests/unit/agentic/services/test_generate_component_failure_signal.py::test_should_not_emit_signal_when_generation_succeeds": 0.091, + "src/backend/tests/unit/agentic/services/test_generate_component_tool.py::TestGenerateComponentContextIsolation::test_should_preserve_parent_canvas_and_events_when_generating_component_during_build": 0.041, + "src/backend/tests/unit/agentic/services/test_generate_component_tool.py::TestGenerateComponentTool::test_empty_description_refuses_without_calling_pipeline": 0.04, + "src/backend/tests/unit/agentic/services/test_generate_component_tool.py::TestGenerateComponentTool::test_passes_request_provider_model_and_user_from_context": 0.041, + "src/backend/tests/unit/agentic/services/test_generate_component_tool.py::TestGenerateComponentTool::test_success_returns_class_name_for_the_agent": 0.04, + "src/backend/tests/unit/agentic/services/test_generate_component_tool.py::TestGenerateComponentTool::test_validation_failure_surfaces_as_error_not_exception": 0.04, + "src/backend/tests/unit/agentic/services/test_intent_classification_timeout.py::TestClassifyIntentTimeout::test_should_classify_normally_when_flow_responds_in_time": 0.043, + "src/backend/tests/unit/agentic/services/test_intent_classification_timeout.py::TestClassifyIntentTimeout::test_should_fall_back_to_question_when_translation_flow_hangs": 0.005, + "src/backend/tests/unit/agentic/services/test_intent_requested_model.py::test_should_extract_requested_model_and_provider_from_translation_json": 0.039, + "src/backend/tests/unit/agentic/services/test_intent_requested_model.py::test_should_leave_requested_model_none_when_user_named_no_model": 0.039, + "src/backend/tests/unit/agentic/services/test_intent_requested_model.py::test_should_treat_empty_requested_model_as_none": 0.039, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestBugsAndEdgeCases::test_check_api_key_empty_string_triggers_env_fallback": 0.042, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestBugsAndEdgeCases::test_check_api_key_non_empty_falsy_string_not_lost": 0.042, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestBugsAndEdgeCases::test_check_api_key_should_fallback_on_type_error": 0.007, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestBugsAndEdgeCases::test_get_default_model_returns_none_for_model_without_name_key": 0.053, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestBugsAndEdgeCases::test_get_enabled_providers_when_mapping_raises": 0.038, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestBugsAndEdgeCases::test_get_enabled_providers_with_no_required_keys": 0.037, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestCheckApiKey::test_should_accept_string_user_id": 0.046, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestCheckApiKey::test_should_accept_uuid_user_id": 0.044, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestCheckApiKey::test_should_fallback_to_env_when_not_in_service": 0.038, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestCheckApiKey::test_should_return_env_when_service_returns_empty": 0.036, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestCheckApiKey::test_should_return_key_from_variable_service": 0.045, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestCheckApiKey::test_should_return_none_when_not_found_anywhere": 0.043, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestDefaultModels::test_should_resolve_model_for_known_providers": 0.038, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestDefaultModels::test_should_return_none_for_unknown_provider": 0.041, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetDefaultModel::test_should_return_model_for_known_provider": 0.047, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetDefaultModel::test_should_return_model_for_openai": 0.046, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetDefaultModel::test_should_return_none_for_unknown_provider": 0.041, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetEnabledProvidersForUser::test_should_return_all_providers_when_all_have_credentials": 0.038, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetEnabledProvidersForUser::test_should_return_empty_when_get_all_returns_empty": 0.039, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetEnabledProvidersForUser::test_should_return_empty_when_no_credentials": 0.103, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetEnabledProvidersForUser::test_should_return_empty_when_service_not_database": 0.043, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestGetEnabledProvidersForUser::test_should_return_enabled_providers_with_credentials": 0.037, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestPreferredProviders::test_anthropic_should_be_first_preference": 0.04, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestPreferredProviders::test_should_have_at_least_two_providers": 0.045, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestPreferredProviders::test_should_have_expected_providers": 0.042, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestProviderServiceIntegration::test_core_preferred_providers_have_default_models": 0.042, + "src/backend/tests/unit/agentic/services/test_provider_service.py::TestProviderServiceIntegration::test_default_provider_should_have_default_model": 0.042, + "src/backend/tests/unit/agentic/services/test_provider_service_multi.py::TestGetEnabledProvidersForUserMulti::test_should_disable_provider_when_required_var_missing": 0.03, + "src/backend/tests/unit/agentic/services/test_provider_service_multi.py::TestGetEnabledProvidersForUserMulti::test_should_enable_provider_when_all_required_vars_present": 0.038, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_edit_continuation_signal_labels_continuing": 0.043, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_plan_approval_signal_labels_generating_flow": 0.04, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_protocol_signals_are_not_treated_as_build_and_run": 0.043, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags0-expected0]": 0.04, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags1-expected1]": 0.041, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags2-expected2]": 0.041, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags3-expected3]": 0.04, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags4-expected4]": 0.041, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags5-expected5]": 0.041, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags6-expected6]": 0.041, + "src/backend/tests/unit/agentic/services/test_request_framing.py::test_step_matrix[flags7-expected7]": 0.043, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowEmitsRanSignal::test_does_not_emit_flow_ran_when_canvas_empty": 0.041, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowEmitsRanSignal::test_does_not_emit_flow_ran_when_run_errors": 0.041, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowEmitsRanSignal::test_emits_flow_ran_on_successful_run": 0.04, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowEnforcesRequestedModel::test_enforces_the_user_named_model_over_the_runtime_model": 0.04, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowEnforcesRequestedModel::test_enforces_user_model_even_when_agent_left_it_empty": 0.04, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowEnforcesRequestedModel::test_falls_back_to_runtime_model_when_no_model_was_requested": 0.041, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowInjectsVerifiedModel::test_injects_the_assistants_verified_model_into_modelless_agent_before_running": 0.04, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowInjectsVerifiedModel::test_runs_normally_when_no_verified_model_is_bound": 0.04, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowTool::test_exposes_run_metrics_to_the_agent": 0.041, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowTool::test_passes_working_flow_and_flow_id_to_orchestration": 0.041, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowTool::test_refuses_when_canvas_is_empty_without_running": 0.041, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowTool::test_returns_result_text_for_the_agent_on_success": 0.04, + "src/backend/tests/unit/agentic/services/test_run_flow_tool.py::TestRunFlowTool::test_surfaces_run_error_as_data_error_not_exception": 0.041, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallBoundedSize::test_cached_tool_call_should_cap_at_max_cache_entries": 0.04, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallContextIsolation::test_cached_tool_call_should_isolate_across_asyncio_gather_tasks": 0.046, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallContextIsolation::test_cached_tool_call_should_isolate_child_writes_from_parent": 0.042, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallDoesNotCacheErrors::test_cached_tool_call_should_not_cache_errors_so_subsequent_calls_retry": 0.041, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallDoesNotCacheErrors::test_cached_tool_call_should_propagate_producer_exception": 0.04, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallHits::test_cached_tool_call_should_be_order_insensitive_on_dict_args": 0.041, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallHits::test_cached_tool_call_should_distinguish_args": 0.042, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallHits::test_cached_tool_call_should_distinguish_tool_names": 0.042, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallHits::test_cached_tool_call_should_return_cached_value_on_second_call_same_args": 0.041, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestCachedToolCallHits::test_cached_tool_call_should_return_producer_value_on_first_call": 0.041, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestFlowBuilderToolsIntegration::test_describe_component_should_use_request_cache": 0.04, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestFlowBuilderToolsIntegration::test_describe_component_with_different_types_should_miss_cache": 0.041, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestFlowBuilderToolsIntegration::test_reset_tool_cache_should_force_refetch_on_next_describe": 0.047, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestFlowBuilderToolsIntegration::test_search_components_should_use_request_cache": 0.053, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestResetToolCache::test_reset_tool_cache_should_be_idempotent_when_no_cache_exists": 0.047, + "src/backend/tests/unit/agentic/services/test_tool_cache.py::TestResetToolCache::test_reset_tool_cache_should_drop_existing_entries": 0.043, + "src/backend/tests/unit/agentic/services/test_user_component_tool_name.py::test_registered_component_with_generic_method_exposes_class_named_tool": 0.03, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsHappyPath::test_should_be_idempotent_when_called_twice": 0.037, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsHappyPath::test_should_be_idempotent_when_directory_empty": 0.043, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsHappyPath::test_should_delete_all_py_files_in_isolated_user_namespace": 0.038, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsHappyPath::test_should_work_in_auto_login_shared_mode": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsIsolation::test_should_not_touch_files_outside_components_directory": 0.056, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsIsolation::test_should_not_touch_other_users_components": 0.047, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsRefusal::test_should_only_delete_py_files_not_arbitrary_files": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_clear.py::TestClearUserComponentsRefusal::test_should_return_zero_when_user_id_missing_and_auto_login_false": 0.056, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestOverlayEntryCaching::test_overlay_built_once_then_rebuilt_when_file_changes": 0.025, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_build_flow_node_uses_the_user_classs_real_output_method": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_overlay_outputs_match_the_user_classs_real_output": 0.044, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_overlay_template_reflects_real_inputs_and_runs_with_config": 0.019, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_registered_component_actually_runs_in_a_flow": 0.006, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_carry_user_code_into_overlay_template": 0.202, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_include_user_component_in_registry_after_registration": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_isolate_user_components_between_users": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_mark_user_overlay_entry_as_custom": 0.026, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_not_clobber_base_registry_with_user_name_collision": 0.033, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_not_mark_base_builtin_entry_as_custom": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_pick_up_overwritten_component": 0.037, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_return_base_only_when_user_id_is_none": 0.046, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_return_base_registry_when_no_user_components_exist": 0.096, + "src/backend/tests/unit/agentic/services/test_user_components_overlay.py::TestRegistryOverlay::test_should_silently_skip_invalid_files": 0.03, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestAtomicWrite::test_should_not_leave_partial_file_when_write_fails": 0.039, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentHappyPath::test_should_isolate_components_by_user": 0.039, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentHappyPath::test_should_overwrite_when_same_class_name_re_registered": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentHappyPath::test_should_write_python_file_to_isolated_user_namespace": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentHappyPath::test_should_write_python_file_under_shared_in_auto_login_mode": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_max_class_name_length_constant_value": 0.043, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_accept_class_name_exactly_at_max_length": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_class_name_longer_than_max": 0.043, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_dunder_or_leading_dot_class_name": 0.044, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_empty_class_name": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_empty_code": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_oversized_code": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[../escape]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[..]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[.]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[COM1]": 0.039, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[CON]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[LPT9]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[NUL]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[Sum/Component]": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[Sum:Colon]": 0.043, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[Sum\\\\Component]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[\\x00null]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_path_traversal_or_reserved_class_names[subdir/Nested]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_registry.py::TestRegisterUserComponentRefusesUntrustedInputs::test_should_refuse_when_user_id_missing_and_auto_login_false": 0.039, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_glob[.components/X.py]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_glob[.components]": 0.038, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_read[.COMPONENTS/X.py]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_read[.components/SumComponent.py]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_read[.components]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_read[ok/.components/anything]": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_write[.components/Evil.py]": 0.044, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInIsolatedMode::test_should_reject_components_segment_for_write[ok/.components/x]": 0.041, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInSharedMode::test_should_reject_components_segment[.components/X.py]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInSharedMode::test_should_reject_components_segment[.components]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestComponentsReservedInSharedMode::test_should_reject_components_segment[ok/.components/anything]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestExistingLfsigReservationStillHolds::test_should_still_reject_lfsig[.lfsig/x]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestExistingLfsigReservationStillHolds::test_should_still_reject_lfsig[.lfsig]": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_reserved_segment.py::TestExistingLfsigReservationStillHolds::test_should_still_reject_lfsig[ok/.lfsig/y]": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestCurrentUserIdContextVar::test_should_default_to_none": 0.04, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestCurrentUserIdContextVar::test_should_isolate_user_id_across_asyncio_gather_tasks": 0.043, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestCurrentUserIdContextVar::test_should_reset_to_none": 0.042, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestCurrentUserIdContextVar::test_should_set_and_get_user_id": 0.055, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestOverlayConsumesContextVar::test_should_read_overlay_for_contextvar_user": 0.029, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestOverlayConsumesContextVar::test_should_return_base_only_when_contextvar_unset": 0.039, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestRegisterIfValid::test_should_register_on_valid_input": 1.789, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestRegisterIfValid::test_should_return_none_and_swallow_when_class_name_missing": 1.545, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestRegisterIfValid::test_should_return_none_and_swallow_when_class_name_unsafe": 0.043, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestRegisterIfValid::test_should_return_none_and_swallow_when_code_empty": 1.388, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestRegisterIfValid::test_should_return_none_and_swallow_when_user_id_missing": 3.093, + "src/backend/tests/unit/agentic/services/test_user_components_threading.py::TestRegisterIfValid::test_should_still_raise_on_unexpected_errors": 0.491, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestIntentRoutingRealLLM::test_followup_add_agent_with_context_routes_to_build_flow": 1.564, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestIntentRoutingRealLLM::test_fresh_build_request_routes_to_build_flow": 0.012, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestIntentRoutingRealLLM::test_genuinely_off_topic_still_off_topic": 2.347, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestIntentRoutingRealLLM::test_pt_canvas_question_is_not_false_off_topic": 0.012, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestLegacyFilterReal::test_real_registry_search_excludes_legacy_but_describe_resolves": 0.047, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestLegacyFilterReal::test_real_registry_search_includes_beta": 0.048, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestNoFakeSuccessRealAgent::test_real_build_emits_flow_activity_not_silent_text": 27.716, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRealEngineRunReturnsResult::test_real_minimal_flow_runs_and_returns_result": 0.007, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRunFlowIntentRealLLM::test_build_request_is_not_swallowed_by_run_flow": 1.153, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRunFlowIntentRealLLM::test_edit_continuation_signal_routes_as_flow_request": 1.263, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRunFlowIntentRealLLM::test_english_run_request_is_classified_run_flow": 0.008, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRunFlowIntentRealLLM::test_run_request_is_classified_run_flow": 1.407, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRuntimeValidationReal::test_accepts_valid_component": 2.066, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestRuntimeValidationReal::test_rejects_output_returning_non_dict_from_input": 1.658, + "src/backend/tests/unit/agentic/test_assistant_report_e2e.py::TestUserComponentOverlayReal::test_registered_component_is_discoverable_by_class_name": 1.602, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetAllComponentTypes::test_should_return_empty_on_error": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetAllComponentTypes::test_should_return_sorted_keys": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentByName::test_should_find_component": 0.039, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentByName::test_should_return_none_when_not_found": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentByName::test_should_return_none_when_type_mismatch": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentByName::test_should_search_specific_type": 0.04, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentByName::test_should_select_fields": 0.042, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentsByType::test_should_delegate_to_list_all": 0.042, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentsCount::test_should_count_all_components": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentsCount::test_should_count_by_type": 0.042, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestGetComponentsCount::test_should_return_zero_for_unknown_type": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestListAllComponents::test_should_filter_by_description": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestListAllComponents::test_should_filter_by_query": 0.039, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestListAllComponents::test_should_filter_by_type": 0.04, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestListAllComponents::test_should_return_all_components": 0.009, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestListAllComponents::test_should_return_empty_on_error": 0.041, + "src/backend/tests/unit/agentic/utils/test_component_search.py::TestListAllComponents::test_should_select_specific_fields": 0.041, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestGetComponentDetails::test_should_return_component_data": 0.038, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestGetComponentDetails::test_should_return_error_when_component_not_found": 0.041, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestGetComponentDetails::test_should_return_error_when_flow_has_no_data": 0.045, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestGetComponentDetails::test_should_return_error_when_flow_not_found": 0.041, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestGetComponentFieldValue::test_should_return_error_for_missing_field": 0.04, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestGetComponentFieldValue::test_should_return_field_config": 0.042, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestListComponentFields::test_should_return_all_fields": 0.04, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestListComponentFields::test_should_return_error_when_flow_not_found": 0.043, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestUpdateComponentFieldValue::test_should_check_user_permission": 0.061, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestUpdateComponentFieldValue::test_should_persist_new_value": 0.039, + "src/backend/tests/unit/agentic/utils/test_flow_component.py::TestUpdateComponentFieldValue::test_should_return_error_for_missing_component": 0.042, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowAsciiGraph::test_should_return_ascii_string": 0.04, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowAsciiGraph::test_should_return_error_string": 0.043, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphRepresentations::test_should_handle_draw_graph_failure": 0.041, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphRepresentations::test_should_return_all_data": 0.041, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphRepresentations::test_should_return_error_when_flow_not_found": 0.041, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphRepresentations::test_should_return_error_when_no_data": 0.042, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphRepresentations::test_should_return_none_ascii_when_no_vertices": 0.039, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphSummary::test_should_return_error_when_not_found": 0.044, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowGraphSummary::test_should_return_metadata": 0.04, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::TestGetFlowTextRepr::test_should_return_repr_string": 0.16, + "src/backend/tests/unit/agentic/utils/test_flow_graph.py::test_get_flow_graph_summary_blocks_custom_components": 0.022, + "src/backend/tests/unit/agentic/utils/test_template_create.py::TestCreateFlowFromTemplate::test_should_build_correct_link_format": 0.076, + "src/backend/tests/unit/agentic/utils/test_template_create.py::TestCreateFlowFromTemplate::test_should_create_flow_from_template": 0.038, + "src/backend/tests/unit/agentic/utils/test_template_create.py::TestCreateFlowFromTemplate::test_should_raise_400_for_invalid_target_folder": 0.076, + "src/backend/tests/unit/agentic/utils/test_template_create.py::TestCreateFlowFromTemplate::test_should_raise_400_for_wrong_user_folder": 0.104, + "src/backend/tests/unit/agentic/utils/test_template_create.py::TestCreateFlowFromTemplate::test_should_raise_404_when_template_not_found": 0.077, + "src/backend/tests/unit/agentic/utils/test_template_create.py::TestCreateFlowFromTemplate::test_should_use_target_folder_when_provided": 0.038, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_empty_query_string": 0.125, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_empty_tags_list": 0.041, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_field_selection_with_nonexistent_fields": 0.042, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_none_query_treated_as_no_filter": 0.065, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_none_tags_treated_as_no_filter": 0.077, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_special_characters_in_query": 0.086, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_very_long_query": 0.041, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestEdgeCases::test_whitespace_only_query": 0.042, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetAllTags::test_get_all_unique_tags": 0.021, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetAllTags::test_tags_are_sorted": 0.058, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetAllTags::test_tags_are_unique": 0.062, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetAllTags::test_tags_match_template_tags": 0.04, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplateById::test_get_all_fields": 0.026, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplateById::test_get_existing_template": 0.065, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplateById::test_get_multiple_templates_by_id": 0.044, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplateById::test_get_nonexistent_template": 0.026, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplateById::test_get_template_with_field_selection": 0.025, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplatesCount::test_count_empty_directory": 0.076, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestGetTemplatesCount::test_count_matches_list": 0.04, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestIntegrationScenarios::test_discover_templates_workflow": 0.007, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestIntegrationScenarios::test_pagination_simulation": 0.011, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestIntegrationScenarios::test_search_and_filter_workflow": 0.006, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_combined_query_and_tag_filter": 0.047, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_empty_fields_returns_all_fields": 0.041, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_filter_by_multiple_tags": 0.066, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_filter_by_single_tag": 0.04, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_filter_by_tag_with_field_selection": 0.043, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_list_all_templates": 0.04, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_list_with_field_selection": 0.081, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_list_with_multiple_fields": 0.044, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_no_matches_invalid_query": 0.043, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_no_matches_invalid_tag": 0.04, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_nonexistent_directory": 0.081, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_search_by_query_case_insensitive": 0.004, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_search_by_query_matches_description": 0.061, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestListTemplates::test_search_by_query_matches_name": 0.067, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestPerformance::test_large_field_list": 0.007, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestPerformance::test_many_tags_filter": 0.069, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestPerformance::test_repeated_calls_consistency": 0.007, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestSearchFunctionality::test_filter_by_each_tag": 0.081, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestSearchFunctionality::test_search_common_terms": 0.047, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestSearchFunctionality::test_search_partial_words": 0.084, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestTemplateStructure::test_all_templates_have_required_fields": 0.041, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestTemplateStructure::test_template_descriptions_exist": 0.539, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestTemplateStructure::test_template_ids_are_unique": 0.084, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestTemplateStructure::test_template_names_are_not_empty": 0.077, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestTemplateStructure::test_template_tags_are_lists": 0.041, + "src/backend/tests/unit/agentic/utils/test_template_search.py::TestTemplateStructure::test_templates_have_data_field": 0.161, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_counts_multiple_duplicate_groups": 0.041, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_handles_empty_table": 0.041, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_leaves_duplicate_plaintext_rows_unhashed": 0.039, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_only_processes_null_hash_rows": 0.041, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_skips_rows_with_null_api_key": 0.038, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_skips_undecryptable_rows": 0.04, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_skips_when_decrypt_raises": 0.04, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_treats_legacy_plaintext_keys_as_plaintext": 0.039, + "src/backend/tests/unit/alembic/test_d306e5c17c41_backfill.py::test_backfill_unique_keys_get_hashed": 0.038, + "src/backend/tests/unit/alembic/test_existing_migrations.py::TestExistingMigrations::test_legacy_migrations_flagged": 0.038, + "src/backend/tests/unit/alembic/test_existing_migrations.py::test_validator_catches_bad_contract": 0.039, + "src/backend/tests/unit/alembic/test_existing_migrations.py::test_validator_catches_bad_expand": 0.042, + "src/backend/tests/unit/alembic/test_existing_migrations.py::test_validator_passes_good_expand": 0.383, + "src/backend/tests/unit/alembic/test_migration_execution.py::TestFilterSqliteNoise::test_modify_nullable_always_suppressed": 0.044, + "src/backend/tests/unit/alembic/test_migration_execution.py::TestFilterSqliteNoise::test_non_fk_diffs_preserved": 0.042, + "src/backend/tests/unit/alembic/test_migration_execution.py::TestFilterSqliteNoise::test_paired_fk_different_target_preserved": 0.041, + "src/backend/tests/unit/alembic/test_migration_execution.py::TestFilterSqliteNoise::test_paired_fk_same_target_suppressed": 0.041, + "src/backend/tests/unit/alembic/test_migration_execution.py::TestFilterSqliteNoise::test_unpaired_add_fk_preserved": 0.041, + "src/backend/tests/unit/alembic/test_migration_execution.py::TestFilterSqliteNoise::test_unpaired_remove_fk_preserved": 0.04, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_deployment_display_name_downgrade_restores_name_unique_constraint[postgres]": 0.043, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_message_ingestion_message_fk_repaired[postgres]": 0.043, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_message_ingestion_message_fk_repaired[sqlite]": 0.04, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_no_phantom_migrations[postgres]": 5.982, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_no_phantom_migrations[sqlite]": 1.33, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_upgrade_from_main_branch[postgres]": 0.043, + "src/backend/tests/unit/alembic/test_migration_execution.py::test_upgrade_from_main_branch[sqlite]": 0.039, + "src/backend/tests/unit/alembic/test_migration_guidelines.py::TestMigrationRuntimeGuidelines::test_expand_phase_compatibility_and_rollback": 0.039, + "src/backend/tests/unit/alembic/test_migration_guidelines.py::TestMigrationValidator::test_contract_phase_missing_data_check": 0.04, + "src/backend/tests/unit/alembic/test_migration_guidelines.py::TestMigrationValidator::test_contract_phase_validation": 0.04, + "src/backend/tests/unit/alembic/test_migration_guidelines.py::TestMigrationValidator::test_invalid_direct_rename_explicit": 0.043, + "src/backend/tests/unit/alembic/test_migration_guidelines.py::TestMigrationValidator::test_invalid_expand_migration_breaking_change": 0.041, + "src/backend/tests/unit/alembic/test_migration_guidelines.py::TestMigrationValidator::test_valid_expand_migration": 0.04, + "src/backend/tests/unit/alembic/test_migration_validator.py::TestMigrationValidatorScripts::test_common_mistakes": 0.039, + "src/backend/tests/unit/alembic/test_migration_validator.py::TestMigrationValidatorScripts::test_contract_phase": 0.04, + "src/backend/tests/unit/alembic/test_migration_validator.py::TestMigrationValidatorScripts::test_expand_phase": 0.041, + "src/backend/tests/unit/alembic/test_migration_validator.py::TestMigrationValidatorScripts::test_phase_detection": 0.039, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_admin_has_share_administration_permissions": 0.04, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_admin_includes_developer_permissions": 0.042, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_developer_includes_viewer_permissions": 0.043, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_permission_slugs_use_resource_action_format": 0.043, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_revision_chain_is_linear_after_api_key_expires_at": 0.043, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_three_system_roles_are_seeded": 0.041, + "src/backend/tests/unit/alembic/test_seed_authz_system_roles.py::test_viewer_has_only_read_and_execute_grants": 0.043, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_crlf_not_in_output": 0.041, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_empty_filename": 0.048, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_happy_path[../etc/passwd-../etc/passwd-..%2Fetc%2Fpasswd]": 0.087, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_happy_path[a\"b.txt-a\\\\\"b.txt-a%22b.txt]": 0.039, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_happy_path[a\\\\b.txt-a\\\\\\\\b.txt-a%5Cb.txt]": 0.039, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_happy_path[simple.txt-simple.txt-simple.txt]": 0.041, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_strips_control_chars[bell\\x07.txt]": 0.041, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_strips_control_chars[evil\\x00.txt]": 0.042, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_strips_control_chars[tab\\there.txt]": 0.056, + "src/backend/tests/unit/api/test_api_utils.py::test_build_content_disposition_very_long_filename": 0.043, + "src/backend/tests/unit/api/test_api_utils.py::test_get_outdated_components": 0.041, + "src/backend/tests/unit/api/test_api_utils.py::test_get_suggestion_message": 0.04, + "src/backend/tests/unit/api/test_api_utils.py::test_remove_api_keys": 0.04, + "src/backend/tests/unit/api/test_s3_endpoints.py::TestS3FileEndpoints::test_delete_file_calls_storage_with_correct_params": 0.036, + "src/backend/tests/unit/api/test_s3_endpoints.py::TestS3FileEndpoints::test_download_file_parses_path_correctly": 0.039, + "src/backend/tests/unit/api/test_s3_endpoints.py::TestS3FileEndpoints::test_download_file_returns_content_string": 0.037, + "src/backend/tests/unit/api/test_s3_endpoints.py::TestS3FileEndpoints::test_download_file_returns_streaming_response": 0.036, + "src/backend/tests/unit/api/test_s3_endpoints.py::TestS3FileEndpoints::test_storage_error_converted_to_http_exception": 0.035, + "src/backend/tests/unit/api/test_s3_endpoints.py::TestS3FileEndpoints::test_upload_saves_to_storage_service": 0.038, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestAutoConfigureStarterProjectsMcp::test_auto_configure_disabled": 0.341, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestAutoConfigureStarterProjectsMcp::test_auto_configure_no_users": 0.47, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestAutoConfigureStarterProjectsMcp::test_auto_configure_success": 0.498, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestAutoConfigureStarterProjectsMcp::test_auto_configure_user_without_starter_folder": 9.814, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPPatchServerConfig::test_patch_allows_explicit_header_clear": 1.628, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPPatchServerConfig::test_patch_preserves_existing_headers_when_omitted": 17.782, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPPatchServerConfig::test_patch_replaces_headers_instead_of_deep_merging": 9.69, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPServerValidationResult::test_has_conflict_property": 8.631, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPServerValidationResult::test_init_defaults": 0.041, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPServerValidationResult::test_init_with_values": 14.647, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPServerValidationResult::test_should_proceed_property": 8.233, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPServerValidationResult::test_should_skip_property": 8.731, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPWithDefaultFolderName::test_mcp_finds_default_folder_standard_mode": 8.921, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPWithDefaultFolderName::test_mcp_skips_wrong_folder_name": 6.069, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMCPWithDefaultFolderName::test_mcp_with_legacy_folder_after_migration": 11.445, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMultiUserMCPServerAccess::test_cross_user_mcp_server_access_prevention[sse]": 10.902, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestMultiUserMCPServerAccess::test_cross_user_mcp_server_access_prevention[streamable]": 9.65, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_different_operations_messages[sse]": 3.305, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_different_operations_messages[streamable]": 11.433, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_exception_handling": 10.689, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_exists_project_doesnt_match[sse]": 9.985, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_exists_project_doesnt_match[streamable]": 0.975, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_exists_project_matches[sse]": 13.029, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_exists_project_matches[streamable]": 9.972, + "src/backend/tests/unit/api/utils/test_config_utils.py::TestValidateMcpServerForProject::test_validate_server_not_exists": 16.234, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormalisationIsNonMutating::test_original_unchanged": 0.04, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeForImport::test_none_code_value_passthrough": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeForImport::test_original_unchanged": 0.042, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeForImport::test_rejoins_list_to_string": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeForImport::test_string_format_passthrough": 0.042, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeToLines::test_already_list_code_unchanged": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeToLines::test_code_field_becomes_list": 0.042, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeToLines::test_code_lines_content": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeToLines::test_empty_code_string": 0.04, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeToLines::test_no_data_nodes_safe": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseCodeToLines::test_non_code_field_untouched": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseNodeUiState::test_keeps_position": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseNodeUiState::test_strips_dragging": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseNodeUiState::test_strips_position_absolute": 9.016, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseNodeUiState::test_strips_selected": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_keeps_stable_fields": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_missing_volatile_fields_do_not_raise": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_strips_access_type": 0.04, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_strips_created_at": 0.04, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_strips_folder_id": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_strips_gradient": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_strips_updated_at": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestNormaliseVolatileFields::test_strips_user_id": 0.041, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestRoundTrip::test_code_round_trips_to_identical_string": 0.067, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestRoundTrip::test_sorted_keys_top_level": 2.179, + "src/backend/tests/unit/api/utils/test_export_normalisation.py::TestRoundTrip::test_two_exports_byte_identical": 1.193, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestCreateRun::test_seeds_initial_metadata_on_job": 9.862, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestCreateRun::test_skips_when_job_id_is_none": 1.825, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestCreateRun::test_swallows_missing_job_row": 12.573, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestFinalizeRun::test_writes_counters_and_items": 21.221, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestMarkRunning::test_transitions_status": 9.037, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestPrivatePatchHelper::test_creates_metadata_when_absent": 7.595, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestPrivatePatchHelper::test_shallow_merges_existing_keys": 6.422, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestPrivatePatchHelper::test_swallows_missing_job": 0.041, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestRunRowProjection::test_get_run_filters_by_job_type": 3.042, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestRunRowProjection::test_get_run_returns_none_for_other_user": 9.982, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestRunRowProjection::test_get_run_returns_runrow_for_owner": 10.757, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestRunRowProjection::test_list_runs_for_kb_filters_and_paginates": 9.703, + "src/backend/tests/unit/api/utils/test_ingestion_run_service.py::TestRunRowProjection::test_list_runs_for_kb_uses_indexed_asset_id_when_record_exists": 6.359, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParsePerFileMetadata::test_empty_returns_dict": 0.042, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParsePerFileMetadata::test_non_dict_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParsePerFileMetadata::test_per_file_inner_validates": 0.004, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParsePerFileMetadata::test_too_many_files_rejected": 0.043, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParsePerFileMetadata::test_valid_payload": 0.088, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_array_non_string_entry_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_array_too_long_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_array_value_accepted": 0.005, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_empty_returns_dict": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_invalid_json_rejected": 0.04, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_invalid_keys_rejected[Source]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_invalid_keys_rejected[]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_invalid_keys_rejected[tag-name]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_invalid_keys_rejected[tag.name]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_invalid_keys_rejected[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]": 0.04, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_nested_object_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_non_dict_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_numeric_and_bool_accepted": 8.245, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[chunk_index]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[file_name]": 0.04, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[ingested_at]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[job_id]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[source]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[source_metadata]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[source_type]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_reserved_keys_rejected[total_chunks]": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_string_value_too_long_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_too_many_keys_rejected": 0.041, + "src/backend/tests/unit/api/utils/test_kb_metadata.py::TestParseUserMetadata::test_valid_payload_round_trips": 0.039, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestFlowCreateSchema::test_id_field_accepts_uuid": 0.043, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestFlowCreateSchema::test_id_field_accepts_uuid_string": 0.042, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestFlowCreateSchema::test_id_field_is_optional": 0.012, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestFlowCreateSchema::test_id_from_dict_roundtrip": 0.043, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestFlowCreateSchema::test_no_id_in_dict_gives_none": 15.598, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestUploadUpsertBranches::test_id_owned_by_other_user_clears_id": 0.04, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestUploadUpsertBranches::test_id_owned_by_same_user_calls_update": 0.072, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestUploadUpsertBranches::test_new_id_not_in_db_calls_new_flow_with_id": 1.327, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestUploadUpsertBranches::test_no_id_calls_new_flow": 0.038, + "src/backend/tests/unit/api/utils/test_preserve_flow_id.py::TestUpsertEndpointVisibility::test_upsert_route_in_openapi_schema": 0.042, + "src/backend/tests/unit/api/v1/test_api_key.py::test_create_api_key_route": 10.312, + "src/backend/tests/unit/api/v1/test_api_key.py::test_create_api_key_route_with_expiry": 0.996, + "src/backend/tests/unit/api/v1/test_api_key.py::test_create_folder": 19.499, + "src/backend/tests/unit/api/v1/test_api_key.py::test_delete_api_key_route": 15.35, + "src/backend/tests/unit/api/v1/test_api_key.py::test_delete_api_key_route_unauthorized": 9.231, + "src/backend/tests/unit/api/v1/test_api_key.py::test_save_store_api_key": 9.716, + "src/backend/tests/unit/api/v1/test_api_schemas.py::TestResultDataResponseTokenUsageValidator::test_converts_usage_pydantic_model_to_dict": 0.052, + "src/backend/tests/unit/api/v1/test_api_schemas.py::TestResultDataResponseTokenUsageValidator::test_passes_through_none_as_none": 3.418, + "src/backend/tests/unit/api/v1/test_api_schemas.py::TestResultDataResponseTokenUsageValidator::test_passes_through_plain_dict_unchanged": 2.139, + "src/backend/tests/unit/api/v1/test_api_schemas.py::TestResultDataResponseTokenUsageValidator::test_token_usage_included_in_serialize_model_output": 3.669, + "src/backend/tests/unit/api/v1/test_api_schemas.py::TestResultDataResponseTokenUsageValidator::test_token_usage_none_in_serialize_model_output": 0.041, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_combined_fields": 10.589, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_logs": 3.415, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_nested_structures": 0.047, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_outputs": 12.468, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_special_types": 0.878, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_result_data_response_truncation": 10.415, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_vertex_build_response_serialization": 0.005, + "src/backend/tests/unit/api/v1/test_api_schemas.py::test_vertex_build_response_with_long_data": 0.038, + "src/backend/tests/unit/api/v1/test_auth_optional.py::test_optional_auth_returns_none_with_invalid_api_key": 8.27, + "src/backend/tests/unit/api/v1/test_auth_optional.py::test_optional_auth_returns_none_with_invalid_token": 1.543, + "src/backend/tests/unit/api/v1/test_auth_optional.py::test_optional_auth_returns_none_without_credentials": 0.005, + "src/backend/tests/unit/api/v1/test_auth_optional.py::test_optional_auth_returns_user_with_valid_bearer": 0.006, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_add_member_duplicate_returns_409": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_add_member_invalidates_target_user": 0.043, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_assignment_invalid_user_404": 0.052, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_assignment_invokes_invalidate_user": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_assignment_succeeds_when_invalidate_user_fails": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_role_409_on_name_conflict": 0.047, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_role_persists_and_invalidates": 0.027, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_role_requires_superuser": 0.052, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_create_team_requires_superuser": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_delete_assignment_succeeds_when_both_invalidations_fail": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_delete_assignment_succeeds_when_invalidate_user_fails": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_delete_role_409_when_assigned": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_delete_role_blocks_system_role": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_assignments_no_user_id_defaults_to_self": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_assignments_non_superuser_blocked_from_other_user": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_assignments_passes_limit_offset_to_query": 0.037, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_assignments_self_allowed_for_non_superuser": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_endpoint_pagination_bounds_match_convention[langflow.api.v1.authz_role_assignments]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_endpoint_pagination_bounds_match_convention[langflow.api.v1.authz_roles]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_endpoint_pagination_bounds_match_convention[langflow.api.v1.authz_teams]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_members_passes_limit_offset_to_query": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_roles_passes_limit_offset_to_query": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_list_teams_passes_limit_offset_to_query": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_actions_dedupe_keeps_under_cap": 0.045, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_actions_empty_after_normalization_becomes_none": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_actions_none_stays_none": 0.043, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_actions_normalized_and_deduped": 0.043, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_actions_over_cap_rejected": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_caps_resource_ids_at_500": 0.037, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_empty_request_returns_empty": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_handler_uses_normalized_actions": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_me_permissions_returns_per_resource_actions": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_remove_member_succeeds_when_invalidate_user_fails": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_assignment_create_global_must_omit_domain_id": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_assignment_create_rejects_unknown_domain_type": 0.043, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_assignment_create_scoped_requires_domain_id[org]": 0.044, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_assignment_create_scoped_requires_domain_id[project]": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_assignment_create_scoped_requires_domain_id[workspace]": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_canonical_permission_slugs": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[deployment:execute]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[file:read]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[flow:*]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[flow:deploy]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[flow:execute]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[knowledge_base:*]": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[knowledge_base:ingest]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[project:delete]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[share:*]": 0.056, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[share:create]": 0.043, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[share:update]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_accepts_per_resource_action_pairs[variable:write]": 0.044, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[*:read]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[Flow:read]": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[deployment:deploy]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[file:deploy]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[flow:*:read]": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[flow:READ]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[flow:invent]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[flow:read:extra]": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[flow]": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[project:ingest]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[share:execute]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[share:write]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[unknown:read]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_create_rejects_non_canonical_permission_slugs[variable:execute]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_role_update_validates_permissions_when_provided": 0.044, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_safe_invalidate_user_falls_back_to_invalidate_all": 0.043, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_safe_invalidate_user_happy_path_skips_invalidate_all": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_safe_invalidate_user_swallows_invalidate_all_failure": 0.04, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_blocks_system_role": 0.045, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_clears_description_via_explicit_null": 0.038, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_clears_parent_via_explicit_null": 0.034, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_clears_permissions_via_empty_list": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_omitted_fields_untouched": 0.029, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_rejects_null_name": 0.039, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_rejects_null_permissions": 0.042, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_role_rejects_self_parent": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_team_adom_change_triggers_invalidate_all": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_team_clears_description_via_explicit_null": 0.028, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_team_display_only_change_skips_invalidate_all": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_team_is_active_change_triggers_invalidate_all": 0.041, + "src/backend/tests/unit/api/v1/test_authz_admin_routes.py::test_update_team_omitted_description_untouched": 0.04, + "src/backend/tests/unit/api/v1/test_authz_audit_schemas.py::test_audit_log_read_accepts_minimal_row": 0.045, + "src/backend/tests/unit/api/v1/test_authz_audit_schemas.py::test_audit_log_read_carries_details_dict": 0.044, + "src/backend/tests/unit/api/v1/test_authz_audit_schemas.py::test_audit_log_read_requires_id_and_action": 0.046, + "src/backend/tests/unit/api/v1/test_authz_audit_schemas.py::test_audit_page_envelope_round_trip": 0.048, + "src/backend/tests/unit/api/v1/test_authz_audit_schemas.py::test_audit_page_rejects_negative_total": 0.044, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_create_share_allows_owner_under_oss_passthrough": 0.037, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_create_share_allows_superuser_under_oss_passthrough": 0.036, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_create_share_blocks_non_owner_under_oss_passthrough": 0.039, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_create_share_denied_when_plugin_denies_non_owner": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_create_share_invokes_plugin_enforce_for_non_owner": 0.039, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_create_share_returns_404_when_resource_missing": 0.043, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_delete_share_allows_owner_under_oss_passthrough": 0.039, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_delete_share_blocks_non_owner_under_oss_passthrough": 0.04, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_delete_share_denied_when_plugin_denies_share_creator": 0.039, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_floor_is_skipped_when_plugin_active": 0.038, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_get_share_team_member_can_see": 0.04, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_get_share_team_non_member_gets_404": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_invalidate_for_share_non_user_scope_invalidates_all[private-None]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_invalidate_for_share_non_user_scope_invalidates_all[public-None]": 0.04, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_invalidate_for_share_non_user_scope_invalidates_all[team-team]": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_invalidate_for_share_user_scope_targets_user": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_list_shares_filters_by_visibility_for_non_superuser": 0.039, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_share_visible_owner_and_creator_always_see": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_share_visible_private_hidden_from_non_owner": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_share_visible_public_is_visible_to_anyone": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_share_visible_team_scope_follows_membership_flag": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_share_visible_user_scope_matches_target_only": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_update_share_allows_owner_under_oss_passthrough": 0.038, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_update_share_blocks_non_owner_under_oss_passthrough": 0.044, + "src/backend/tests/unit/api/v1/test_authz_share_routes.py::test_update_share_invokes_plugin_enforce_for_share_creator": 0.039, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_private_scope_rejects_target_id": 0.044, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_public_scope_rejects_target_id": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_public_scope_without_target_is_valid": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_team_scope_requires_target_id": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_unknown_permission_level_rejected": 0.042, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_unknown_resource_type_rejected": 0.043, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_user_scope_requires_target_id": 0.041, + "src/backend/tests/unit/api/v1/test_authz_share_schemas.py::test_user_scope_with_target_is_valid": 0.041, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_non_403_exception_not_converted": 0.041, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_non_owner_cannot_override_flow_data": 0.04, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_owner_can_override_flow_data": 0.04, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_owner_succeeds": 0.039, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_plugin_deny_returns_404_not_403": 0.041, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_public_fallback_when_share_aware_misses": 0.04, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_shared_private_non_owner_succeeds": 0.041, + "src/backend/tests/unit/api/v1/test_chat_build_flow_authz.py::test_build_flow_unknown_flow_returns_404": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestAdapterDescriptionValidation::test_create_payload_accepts_long_description": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestAdapterDescriptionValidation::test_update_payload_accepts_explicit_null_description": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestAdapterDescriptionValidation::test_update_payload_accepts_long_description": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestCreateResponse::test_description_none_when_not_set": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestCreateResponse::test_surfaces_description_from_db_row": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestCreateResponse::test_uses_enum_type_from_row": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestDeploymentModel::test_deployment_accepts_deployment_type_enum": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestDeploymentModel::test_deployment_accepts_description": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestDeploymentModel::test_deployment_description_defaults_to_none": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestDeploymentModel::test_deployment_read_description_defaults_to_none": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestDeploymentModel::test_deployment_read_has_description_and_enum_type": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestMapperUpdateResult::test_description_none_from_row": 0.047, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestMapperUpdateResult::test_no_description_kwarg_needed": 0.046, + "src/backend/tests/unit/api/v1/test_deployment_description_and_type.py::TestMapperUpdateResult::test_reads_description_from_row": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_guard_with_empty_flow_ids_skips_sync": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_guard_with_none_flow_ids_skips_sync": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_non_guard_error_propagates_without_sync": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_on_deployment_guard_error_instance_succeeds_after_sync": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_on_deployment_guard_propagates_second_guard": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_on_deployment_guard_succeeds_after_sync": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_propagates_sync_failure": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_flows_retry_success_on_first_attempt_skips_sync": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_projects_retry_non_guard_error_propagates_without_sync": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_projects_retry_on_deployment_guard_error_instance_uses_project_sync": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_projects_retry_on_deployment_guard_uses_project_sync": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_projects_retry_propagates_sync_failure": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_guard_retry.py::test_projects_retry_success_on_first_attempt_skips_sync": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_api_payload_field_names_match_adapter_registry": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_execution_provider_data_shapers_passthrough": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_exposes_reconciliation_resolvers": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_flow_version_item_data_defaults_to_none": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_formats_conflict_detail_with_generic_fallback": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_config_list_adapter_params_omits_deployment_ids_when_key_none": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_config_list_adapter_params_passthrough": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_credentials_raises_not_implemented": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_deployment_create_raises_not_implemented": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_deployment_list_adapter_params_passthrough": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_deployment_list_adapter_params_returns_none_when_unfiltered": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_deployment_update_raises_not_implemented": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_execution_create_passthrough_when_slot_not_configured": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_execution_create_rejects_invalid_provider_data_when_slot_configured": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_execution_create_validates_provider_data_when_slot_configured": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_kwargs_for_metadata_update_raises_not_implemented": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_provider_account_create_raises_not_implemented": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_provider_account_update_name_only": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_provider_account_update_provider_data_raises": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_snapshot_list_adapter_params_omits_deployment_ids_when_key_none": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_snapshot_list_adapter_params_passthrough": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolve_verify_credentials_raises_not_implemented": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_apply_normalize_policy_when_slot_configured": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_passthrough_none_payload_when_slot_configured[resolve_deployment_config]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_passthrough_none_payload_when_slot_configured[resolve_deployment_spec]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_passthrough_none_payload_when_slot_configured[resolve_execution_input]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_passthrough_when_slot_not_configured[resolve_deployment_config-payload1]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_passthrough_when_slot_not_configured[resolve_deployment_spec-payload0]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_passthrough_when_slot_not_configured[resolve_execution_input-payload2]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_reject_invalid_payload_for_configured_slots[resolve_deployment_config]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_reject_invalid_payload_for_configured_slots[resolve_deployment_spec]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_reject_invalid_payload_for_configured_slots[resolve_execution_input]": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_validate_configured_slots_without_re_serializing[resolve_deployment_config-payload1]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_validate_configured_slots_without_re_serializing[resolve_deployment_spec-payload0]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_resolvers_validate_configured_slots_without_re_serializing[resolve_execution_input-payload2]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shape_deployment_get_data_raises_not_implemented": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapers_passthrough_provider_payload[shape_deployment_item_data]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapers_passthrough_provider_payload[shape_deployment_operation_result]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_deployment_create_result": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_deployment_list_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_deployment_update_result": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_execution_create_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_execution_status_result_with_none_execution_id": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_flow_version_list_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_shapes_provider_account_response": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_util_create_result_from_existing_resource_raises_not_implemented": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_base_mapper_util_existing_deployment_resource_key_for_create_raises_not_implemented": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_has_resolve_method_for_all_inbound_slots": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_has_shape_method_for_all_outbound_slots": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_registry_accessor_returns_singleton": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_registry_get_returns_cached_instance_for_key": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_registry_re_register_same_key_replaces_mapper": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_registry_rejects_non_mapper_classes": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_registry_returns_default_when_unregistered": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_mapper_registry_returns_registered_mapper": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_shape_deployment_list_items_with_filter": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_shape_deployment_list_items_with_filter_empty_matches": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_base.py::test_shape_deployment_list_items_without_filter": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_adapter_slot_rejects_missing_adapter_result": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_adapter_slot_requires_configured_slot": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_adapter_slot_sanitizes_validation_errors": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_api_request_slot_maps_missing_outer_validation_hook": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_api_request_slot_rejects_missing_provider_data": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_api_request_slot_requires_configured_slot": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_parse_api_request_slot_sanitizes_validation_errors": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_provider_label_must_be_defined": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_rejects_outer_request_validation_without_hook": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_base_mapper_wraps_outer_request_value_error": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_list_item_provider_data_rejects_blank_environment": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_bind_tool_operation": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_bind_tool_with_empty_app_ids": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_bind_with_empty_app_ids": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_existing_agent_id_only": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_flow_version_bind_contract": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_flow_version_create_bind_contract": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_flow_version_unbind_and_remove_contract": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_llm_only_update_contract": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_remove_tool_by_id_operation": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_unbind_tool_operation": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_accepts_update_without_llm": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_conflicting_tool_id_operations": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_create_without_display_name": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_create_without_llm": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_duplicate_credential_keys": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_existing_agent_id_with_any_extra_field[extra_provider_data0]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_existing_agent_id_with_any_extra_field[extra_provider_data1]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_existing_agent_id_with_any_extra_field[extra_provider_data2]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_existing_agent_id_with_any_extra_field[extra_provider_data3]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_existing_agent_id_with_any_extra_field[extra_provider_data4]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_existing_agent_id_with_outer_description": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_metadata_only_create_contract": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_null_existing_agent_id": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_null_update_scalars[display_name]": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_rejects_null_update_scalars[llm]": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_api_payload_unbind_tool_rejects_connection_app_ids": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_create_payload_accepts_bind_tool_operation": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_create_payload_bind_tool_without_prefix": 0.05, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_created_tool_includes_tool_id": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_bind_creates_new_tool_when_no_attachment": 0.034, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_bind_reuse_with_empty_app_ids_emits_attach_tool": 0.034, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_bind_reuses_existing_tool_when_attachment_exists": 0.034, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_config_list_exposes_connection_id_app_id_and_type": 0.082, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_config_list_fails_fast_when_environment_missing": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_config_list_fails_fast_when_type_missing": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_config_list_rejects_missing_type_even_with_other_provider_data": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_model_passes_adapter_result_description": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_model_uses_adapter_result_description": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_preserves_env_var_source_in_connection_payloads": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_reports_missing_llm_field_name": 0.05, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_reports_unknown_field_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_response_rejects_non_uuid_source_ref_in_created_tools": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_result_from_existing_resource_includes_empty_payload": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_skips_empty_bind_operations_but_keeps_raw_tools": 0.033, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_utilities_default_when_provider_data_missing": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_create_utilities_reject_explicit_null_provider_data": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_deployment_list_result_rejects_unknown_flattened_entry_fields": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_accepts_supported_request_shapes[provider_data0]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_accepts_supported_request_shapes[provider_data1]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_accepts_supported_request_shapes[provider_data2]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_rejects_agent_id_override_field": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_rejects_none_provider_data": 0.121, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_rejects_unknown_fields": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_requires_exactly_one_input_source[provider_data0]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_requires_exactly_one_input_source[provider_data1]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_execution_input_requires_exactly_one_input_source[provider_data2]": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_create_model_passes_description_for_db_write": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_create_model_uses_provider_metadata": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_onboarding_allows_db_only_payload": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_onboarding_rejects_description_mutation": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_onboarding_rejects_provider_mutations[provider_data0]": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_onboarding_rejects_provider_mutations[provider_data1]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_agent_onboarding_rejects_provider_mutations[provider_data2]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_existing_resource_result_preserves_description_before_db_write": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_exposes_reconciliation_resolvers": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_extracts_list_item_provider_data": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_flow_version_item_data_from_snapshot_connections": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_flow_version_list_result_degrades_when_required_snapshot_missing": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_flow_version_list_result_degrades_when_snapshot_result_missing": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_flow_version_list_result_fails_fast_on_invalid_attachment_snapshot_id[None]": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_flow_version_list_result_returns_empty_app_ids_when_snapshot_has_no_connections": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_flow_version_patch_without_provider_data_is_empty": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_get_metadata_sync_kwargs_include_display_name": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_is_registered": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_llm_list_result_raises_for_missing_provider_payload": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_load_from_provider_params_force_draft_filter": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_maps_create_adapter_payload_validation_errors_to_500": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_metadata_sync_kwargs_include_display_name": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_metadata_sync_passes_list_description": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_provider_list_entry_flattens_provider_data_and_uses_id": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_provider_list_entry_rejects_blank_tool_id": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_provider_list_entry_rejects_non_dict_provider_data": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_deployment_list_adapter_params_passthrough": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_deployment_list_passes_none_through": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_update_null_description_does_not_set_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_update_passthrough_without_provider_data": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_update_preserves_explicit_null_description": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_update_rejects_explicit_null_provider_data": 0.049, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_verify_credentials_for_update_prefers_new_provider_data": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_verify_credentials_for_update_rejects_tenant_id_update": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_verify_credentials_for_update_rejects_url_update": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolve_verify_credentials_for_update_returns_none_without_provider_data": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_resolves_kwargs_for_metadata_update_from_adapter_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shape_synced_list_items_rejects_missing_provider_data_key": 0.082, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shape_synced_list_items_requires_provider_data_map": 0.124, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_config_list_result_with_environment_metadata": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_config_list_result_with_full_slot_validation": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_create_response_with_provider_names": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_deployment_list_result_with_flattened_entries": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_flow_version_list_result_with_enrichment": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_get_provider_agent_metadata": 0.165, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_get_provider_agent_metadata_requires_llm": 0.163, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_llm_list_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_snapshot_list_result_without_nested_provider_data": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_synced_list_items_with_provider_data": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_update_response_from_result_schema": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_update_response_with_non_uuid_source_ref": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_update_response_with_provider_display_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_shapes_update_response_with_tool_id": 0.048, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_skips_empty_bind_operations_but_keeps_raw_tools": 0.034, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_snapshot_list_result_ignores_extra_provider_result_fields": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_tool_display_name_override_generates_valid_technical_name": 0.036, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_tool_display_name_rename_compatible_with_all_update_operation_families": 0.034, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_bind_tool_into_provider_operations": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_create_bind_into_raw_tool_payload": 0.035, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_create_bind_with_tool_display_name_override": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_flow_version_bind_into_raw_tool_payload": 0.031, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_llm_only_update_payload": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_remove_tool_by_id_into_provider_operations": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_unbind_and_remove_via_attachment_snapshot_ids": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_translates_unbind_tool_into_provider_operations": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_trusts_top_level_deployment_id": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_update_response_rejects_non_uuid_source_ref": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_update_snapshot_bindings_filters_non_uuid_source_refs": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_upsert_flow_with_add_remove_and_tool_display_name_emits_bind_unbind_rename": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_mapper_upsert_flow_with_tool_display_name_emits_rename_for_existing_attachment": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_watsonx_update_result_data_preserves_provider_owned_strings": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_flow_version_item_data_rejects_empty_provider_data": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_flow_version_item_data_rejects_empty_tool_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_provider_account_create_assembles_model": 0.047, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_provider_account_create_requires_tenant": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_provider_account_create_uses_url_tenant_fallback": 0.048, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_provider_account_response_includes_tenant_id": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_resolve_credentials_rejects_empty": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_resolve_credentials_rejects_tenant_metadata": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_resolve_credentials_returns_api_key": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_resolve_credentials_strips_whitespace": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_resolve_verify_credentials_rejects_extra_fields": 0.051, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_update_allows_name_changes_only_for_non_credential_fields": 0.048, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_verify_credentials_create_accepts_missing_tenant": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_verify_credentials_create_filters_non_credential_fields": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_mapper_watsonx.py::test_wxo_mapper_verify_credentials_create_rejects_unknown_fields": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestConfigAndSnapshotListRoutes::test_list_configs_global_scope_uses_provider_id": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestConfigAndSnapshotListRoutes::test_list_snapshots_deployment_scope_resolves_provider_from_deployment": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentExistingAgent::test_existing_agent_conflict_when_resource_key_already_persisted": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentExistingAgent::test_existing_agent_with_extra_provider_field_rejected_before_provider_lookup": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentExistingAgent::test_existing_agent_without_mutation_skips_provider_calls": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentProjectValidation::test_empty_flow_version_ids_skips_validation": 0.035, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentProjectValidation::test_validation_called_before_adapter": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentRollback::test_no_rollback_on_success": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentRollback::test_rollback_called_on_commit_failure": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestCreateDeploymentSchemaValidation::test_mapper_schema_validation_error_surfaces_422": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestDeleteDeployment::test_commit_failure_retries_local_cleanup_once": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestDeleteDeployment::test_include_provider_false_skips_adapter_delete": 0.299, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestDeleteDeployment::test_include_provider_true_calls_adapter_delete": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestDeleteDeployment::test_non_404_provider_error_does_not_delete_local_row": 0.006, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestDeleteDeployment::test_provider_not_found_still_deletes_local_row": 0.447, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestDeleteDeployment::test_repeated_local_cleanup_failure_returns_500": 0.01, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_binding_aware_sync_and_fallback_count_failure_raises": 0.411, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_binding_aware_sync_error_falls_back_to_unverified_count": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_binding_aware_sync_prunes_detached_attachments": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_get_deployment_does_not_inject_resource_key_into_provider_data": 0.435, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_get_sync_passes_provider_description_and_keeps_display_name_in_provider_data": 0.38, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_non_404_adapter_error_does_not_delete_row": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_service_unavailable_returns_503": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_snapshot_sync_corrects_attached_count": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_stale_row_deleted_when_provider_returns_not_found": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestGetDeploymentSync::test_unsupported_provider_get_sync_raises": 0.007, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_authentication_error_to_401": 0.35, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_conflict_passes_structured_resource_name_to_mapper_formatter": 0.083, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_conflict_passes_structured_resource_to_mapper_formatter": 0.005, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_conflict_with_mapper_formatter": 0.004, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_conflict_without_mapper_passthrough": 0.005, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_not_found_to_404": 0.004, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_not_implemented_to_501": 0.307, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_maps_service_unavailable_to_503": 0.434, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestHandleAdapterErrors::test_passes_through_http_exception": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentFlowVersionsRoute::test_returns_paginated_flow_versions": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentLlms::test_list_llms_maps_adapter_error": 0.005, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentLlms::test_list_llms_returns_shaped_response": 0.394, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsFlowIdsFilter::test_flow_ids_and_flow_version_ids_mutually_exclusive": 0.046, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsFlowIdsFilter::test_flow_ids_no_versions_returns_empty": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsFlowIdsFilter::test_flow_ids_resolves_to_flow_version_ids": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsLoadFromProvider::test_load_from_provider_bypasses_db_view": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsLoadFromProvider::test_load_from_provider_rejects_flow_ids_filter": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsLoadFromProvider::test_load_from_provider_rejects_flow_version_filters": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsMetadataSync::test_provider_description_passed_and_display_name_stays_in_provider_data": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsProjectIdFilter::test_load_from_provider_rejects_project_id": 0.049, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsProjectIdFilter::test_project_id_none_when_omitted": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestListDeploymentsProjectIdFilter::test_project_id_threaded_to_synced": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_create_provider_account_conflict_returns_409": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_delete_provider_account_falls_back_to_local_count_when_reconciliation_raises": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_delete_provider_account_prunes_stale_rows_before_delete": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_delete_provider_account_rejects_when_deployments_exist": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_delete_provider_account_sets_deployment_provider_scope_for_reconciliation": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_delete_provider_account_skips_reconciliation_when_no_local_deployments": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_update_provider_account_conflict_returns_409": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_update_provider_account_name_only_skips_credential_verification": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_update_provider_account_propagates_deployment_guard_error_instance": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_update_provider_account_raw_guard_exception_propagates": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestProviderAccountRoutes::test_update_provider_account_verify_failure_returns_401": 0.007, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestResolveDeploymentAdapter::test_adapter_lookup_error_raises_500": 0.347, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestResolveDeploymentAdapter::test_empty_provider_key_raises_400": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestResolveDeploymentAdapter::test_unknown_provider_key_raises_503": 0.385, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestResolveDeploymentAdapter::test_valid_provider_key_returns_adapter": 0.436, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestResolveDeploymentAdapter::test_whitespace_only_provider_key_raises_400": 0.413, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentAlreadyAttachedFiltering::test_all_flow_versions_already_attached_passes_empty_list": 0.032, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentAlreadyAttachedFiltering::test_already_attached_flow_versions_excluded_from_snapshot_resolution": 0.047, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentAlreadyAttachedFiltering::test_no_existing_attachments_passes_all_flow_versions": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentMetadataPersistence::test_provider_update_metadata_is_persisted_from_adapter_result": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentProjectValidation::test_validation_called_before_adapter": 0.367, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentRollback::test_no_rollback_on_success": 0.049, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateDeploymentRollback::test_rollback_called_on_commit_failure": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_commit_failure_attempts_provider_compensation": 0.035, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_one_owner_spanning_multiple_provider_accounts_returns_409": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_project_scope_validation_runs_before_provider_update": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_share_aware_multiple_authorized_groups_returns_409": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_share_aware_one_authorized_group_ignores_unauthorized_collision": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_share_aware_zero_authorized_groups_returns_404": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_route_handlers.py::TestUpdateSnapshotRoute::test_updates_all_attachment_rows_for_snapshot": 0.339, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestCredentialSecurity::test_provider_account_response_dump_excludes_credentials": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestCredentialSecurity::test_provider_account_response_excludes_api_key": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestCredentialSecurity::test_provider_account_response_includes_provider_data": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentConfigListResponse::test_allows_null_provider_data": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentConfigListResponse::test_has_provider_data_and_pagination_fields_only": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentConfigListResponse::test_provider_data_contains_connections": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentConfigListResponsePagination::test_rejects_negative_total": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentConfigListResponsePagination::test_rejects_page_less_than_one": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentConfigListResponsePagination::test_rejects_size_less_than_one": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentFlowVersionListSchemas::test_flow_version_list_item_does_not_expose_description_or_created_at": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentFlowVersionListSchemas::test_flow_version_list_item_uses_attached_at": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentFlowVersionListSchemas::test_flow_version_list_response_wraps_items_with_pagination": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentListItemFlowVersionIds::test_accepts_empty_list": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentListItemFlowVersionIds::test_accepts_flow_version_ids_list": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentListItemFlowVersionIds::test_defaults_to_none": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentListResponse::test_allows_provider_only_shape": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentSnapshotListResponse::test_allows_null_provider_data": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentSnapshotListResponse::test_has_provider_data_and_pagination_fields_only": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentSnapshotListResponse::test_provider_data_contains_tools": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentSpecPayloadCompatibility::test_create_request_accepts_long_description": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentSpecPayloadCompatibility::test_create_request_accepts_provider_data_payload": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentSpecPayloadCompatibility::test_create_request_rejects_provider_spec_dict": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentUpdateRequest::test_accepts_explicit_null_description": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentUpdateRequest::test_accepts_long_description": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentUpdateRequest::test_accepts_provider_data_only": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestDeploymentUpdateRequest::test_rejects_empty_payload": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_accepts_string_uuid": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_deduplicates": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_none_passes_through": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_rejects_empty_list": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_rejects_invalid_uuid": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_rejects_more_than_one": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestFlowIdsQueryValidation::test_single_valid_uuid": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_create_accepts_valid_name": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_create_rejects_empty_name": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_create_rejects_missing_name": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_create_rejects_whitespace_only_name": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_create_strips_name_whitespace": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_response_includes_name": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_update_accepts_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountName::test_update_rejects_null_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountProviderDataBoundary::test_create_accepts_provider_data_url": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountProviderDataBoundary::test_create_rejects_top_level_tenant_id_field": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountProviderDataBoundary::test_create_rejects_top_level_url_field": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountProviderDataBoundary::test_update_rejects_tenant_id_field": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderAccountProviderDataBoundary::test_update_rejects_url_field": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderKeyEnum::test_accepts_valid_enum_value": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderKeyEnum::test_accepts_valid_string_value": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderKeyEnum::test_rejects_empty_string": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestProviderKeyEnum::test_rejects_invalid_provider_key": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestRunCreateRequest::test_rejects_extra_fields": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestRunCreateResponse::test_required_deployment_id": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestSnapshotUpdateRequest::test_rejects_extra_fields": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestSnapshotUpdateRequest::test_requires_flow_version_id": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestSnapshotUpdateResponse::test_requires_flow_version_id": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_schemas.py::TestSnapshotUpdateResponse::test_requires_provider_snapshot_id": 0.298, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestCreateSnapshotMapping::test_resolve_snapshot_map_for_create_maps_source_ref_to_flow_version_ids": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestCreateSnapshotMapping::test_resolve_snapshot_map_for_create_rejects_missing_bindings": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_does_not_match_by_name": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_empty_provider_id_raises_value_error": 0.263, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_empty_provider_response": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_empty_resource_keys_returns_empty_set": 0.047, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_passes_deployment_type_filter": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_passes_resource_keys_as_deployment_ids": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_provider_deployment_service_error_uses_mapped_http_status": 0.006, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_provider_error_raises_500_for_unhandled_exception": 0.008, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderResourceKeys::test_returns_ids_only": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderSnapshotKeys::test_empty_snapshot_ids_returns_empty_set": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderSnapshotKeys::test_falsy_snapshot_id_from_provider_raises_value_error": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderSnapshotKeys::test_provider_error_raises_500": 0.007, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFetchProviderSnapshotKeys::test_returns_recognized_snapshot_ids": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFlowVersionDeploymentAttachmentCrud::test_count_attachments_by_deployment_ids_joins_flow_version": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFlowVersionDeploymentAttachmentCrud::test_count_deployment_attachments_returns_scalar_count": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFlowVersionDeploymentAttachmentCrud::test_delete_orphan_attachments_for_flow_ids_joins_flow_version_and_deployment": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFlowVersionDeploymentAttachmentCrud::test_delete_orphan_attachments_for_project_joins_flow_scope_and_deployment": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFlowVersionDeploymentAttachmentCrud::test_list_deployment_attachments_with_versions_orders_by_attachment_timestamps": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestFlowVersionDeploymentAttachmentCrud::test_list_deployment_attachments_with_versions_skips_query_when_limit_non_positive": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentFlowVersionsSynced::test_fails_fast_when_attachment_snapshot_ids_are_falsy": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentFlowVersionsSynced::test_forwards_flow_ids_filter_to_attachment_queries": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentFlowVersionsSynced::test_provider_snapshot_result_with_falsy_id_falls_back_without_enrichment": 0.046, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentFlowVersionsSynced::test_snapshot_sync_errors_fall_back_to_db_rows_without_enrichment": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentFlowVersionsSynced::test_snapshot_sync_savepoint_failure_clears_enrichment_payload": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentFlowVersionsSynced::test_syncs_snapshots_with_snapshot_ids_and_returns_enrichment": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_cursor_does_not_advance_on_delete": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_deletes_stale_rows": 0.036, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_empty_batch_stops_loop": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_keeps_provider_confirmed_rows": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_merges_list_item_provider_data_across_refill_rounds": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_mismatched_type_not_in_known_skips_without_deleting": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_page_offset_calculation": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_passes_flow_version_ids_through": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_passes_project_id_through": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_passes_provider_description_before_batch_metadata_sync": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSynced::test_stops_after_one_refill": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSyncedBindingPhase::test_binding_cleanup_runs_inside_savepoint": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSyncedBindingPhase::test_binding_cleanup_runs_with_empty_bindings": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSyncedBindingPhase::test_binding_sync_corrects_attached_count": 0.037, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestListDeploymentsSyncedBindingPhase::test_binding_sync_error_preserves_original_counts": 0.033, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_flow_deployment_state_continues_when_orphan_cleanup_fails": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_flow_deployment_state_deduplicates_flow_ids": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_flow_deployment_state_passes_provider_account_filter": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_flow_deployment_state_returns_early_when_flow_ids_empty": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_flow_version_attachments_continues_when_orphan_cleanup_fails": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_flow_version_attachments_passes_provider_account_filter": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_project_deployments_continues_when_orphan_cleanup_fails": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_project_deployments_passes_provider_account_filter": 0.046, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestProviderAccountScopedSync::test_sync_project_deployments_returns_when_no_deployments": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderCreate::test_calls_adapter_delete": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderCreate::test_falls_back_to_delete_when_extended_rollback_fails": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderCreate::test_skips_delete_fallback_when_disabled_and_extended_rollback_fails": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderCreate::test_swallows_delete_failure": 0.006, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderCreate::test_uses_extended_provider_result_rollback_when_available": 0.301, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderUpdate::test_calls_adapter_update_with_rollback_payload": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderUpdate::test_returns_early_when_mapper_returns_none": 0.038, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderUpdate::test_swallows_adapter_update_failure": 0.049, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestRollbackProviderUpdate::test_swallows_mapper_failure": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncAttachmentSnapshotIds::test_all_snapshots_known_nothing_deleted": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncAttachmentSnapshotIds::test_deletes_stale_attachments": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncAttachmentSnapshotIds::test_extra_known_provider_snapshots_are_ignored": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncAttachmentSnapshotIds::test_falsy_snapshot_short_circuits_before_batch_delete": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncAttachmentSnapshotIds::test_raises_on_falsy_snapshot_id": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncDeploymentsAndAttachmentsByProvider::test_batches_stale_deletions_once_per_provider_group": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestSyncFlowVersionAttachments::test_snapshot_cleanup_runs_inside_savepoint": 0.039, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestUpdateSnapshotMapping::test_resolve_added_snapshot_bindings_for_update_maps_source_ref": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestUpdateSnapshotMapping::test_resolve_added_snapshot_bindings_for_update_rejects_missing_expected_source_ref": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestUpdateSnapshotMapping::test_resolve_added_snapshot_bindings_for_update_rejects_unexpected_source_ref": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestUpdateSnapshotMapping::test_resolve_snapshot_map_for_create_rejects_unexpected_source_ref": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestWxoResolveRollbackUpdate::test_builds_put_tools_from_attachment_snapshot_ids": 0.045, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestWxoResolveRollbackUpdate::test_empty_attachments_produces_empty_put_tools": 0.044, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::TestWxoResolveRollbackUpdate::test_returns_none_when_deployment_not_found": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_base_mapper_extract_snapshot_bindings_for_get_raises_not_implemented": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_base_mapper_extract_snapshot_bindings_raises_not_implemented": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_resolve_flow_version_patch_for_update_watsonx_operations": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_sync_deployment_display_metadata_passes_provider_metadata": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_validate_project_scoped_flow_version_ids_accepts_all_ids": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_validate_project_scoped_flow_version_ids_rejects_out_of_project_ids": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_allows_empty_tool_ids": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_for_get": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_for_get_requires_provider_data": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_for_get_requires_tool_ids": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_for_get_requires_tool_ids_list_type": 0.04, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_from_provider_view": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_requires_contract_fields": 0.041, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_extract_snapshot_bindings_requires_provider_data_object": 0.043, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_shape_deployment_get_data_hides_internal_sync_fields": 0.042, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_shape_deployment_get_data_requires_provider_data": 0.282, + "src/backend/tests/unit/api/v1/test_deployment_sync.py::test_watsonx_mapper_util_created_snapshot_ids_uses_adapter_slot": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_config_list_result_empty": 0.109, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_config_list_result_pagination": 0.103, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_create_result_maps_db_identity_and_provider_result": 0.042, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_create_result_with_empty_dict_provider_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_create_result_with_none_provider_result": 0.104, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_list_items_basic": 0.039, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_list_items_with_flow_filter": 0.04, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_list_result_null_provider_data_on_item": 0.04, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_list_result_with_entries": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_list_result_with_extra_provider_data_fields": 0.101, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_deployment_update_result_maps_db_identity_and_provider_result": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_response_mapping.py::test_shape_execution_create_result_with_provider_data": 0.043, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_configs_path_matches_configs_endpoint": 0.064, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_configs_route_excludes_none_fields_in_response_model": 0.075, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_deployment_flows_path_matches_flow_versions_endpoint": 0.004, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_deployment_status_path_is_not_registered": 0.005, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_include_deployment_router_adds_routes_when_feature_enabled": 0.003, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_include_deployment_router_skips_routes_when_feature_disabled": 0.039, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_llms_path_matches_llms_endpoint": 0.057, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_snapshot_patch_path_matches_update_endpoint": 0.003, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_snapshots_path_matches_snapshots_endpoint": 0.083, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_snapshots_route_excludes_none_fields_in_response_model": 0.067, + "src/backend/tests/unit/api/v1/test_deployments_routes.py::test_types_path_matches_types_endpoint": 0.089, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_create_deployment_run_telemetry": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_create_deployment_telemetry": 0.042, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_create_provider_account_telemetry": 0.04, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_create_provider_account_telemetry_error": 0.046, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_cross_route_smoke_exception_after_provider_set": 0.05, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_delete_deployment_telemetry": 0.047, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_delete_provider_account_telemetry": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_update_deployment_telemetry": 0.046, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_update_provider_account_telemetry": 0.041, + "src/backend/tests/unit/api/v1/test_deployments_telemetry.py::test_update_snapshot_telemetry": 0.045, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_deduplicates_across_versions": 0.042, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_deduplicates_flow_version_ids_in_request": 4.162, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_fails_fast_for_missing_flow_versions": 0.039, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_fails_fast_for_missing_nodes_list": 0.039, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_fails_fast_for_non_dict_data": 0.035, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_fails_fast_for_non_list_nodes": 3.415, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_filters_out_non_existing_variable_names": 0.067, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_ignores_non_string_and_blank_variable_values": 2.017, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_ignores_password_only_fields": 0.04, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_load_from_db_is_used_even_when_password_fields_exist": 0.041, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_rejects_empty_flow_version_ids": 0.042, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_rejects_more_than_50_flow_version_ids": 0.042, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_returns_global_variable_refs": 0.041, + "src/backend/tests/unit/api/v1/test_detect_env_vars.py::TestDetectEnvVars::test_strips_whitespace_from_detected_variable_name": 9.932, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_create_admin_only_allows_known_template_refresh": 11.715, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_create_admin_only_allows_superuser": 10.513, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_create_admin_only_blocks_unknown_custom_code": 12.361, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_endpoint_metadata_consistency": 8.114, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_endpoint_returns_metadata": 8.433, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_update_admin_only_allows_known_template_refresh": 11.499, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_update_admin_only_allows_superuser": 11.996, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_custom_component_update_admin_only_blocks_unknown_custom_code": 9.798, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_deprecated_upload_authenticated_succeeds": 10.408, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_deprecated_upload_enforces_max_file_size": 2.773, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_deprecated_upload_rejects_unauthenticated": 0.49, "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config": 1.8237768740218598, - "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_version": 1.906218040996464, - "src/backend/tests/unit/api/v1/test_endpoints.py::test_update_component_model_name_options": 2.521151998982532, - "src/backend/tests/unit/api/v1/test_endpoints.py::test_update_component_outputs": 2.477914999006316, - "src/backend/tests/unit/api/v1/test_files.py::test_delete_file": 2.4448377909720875, - "src/backend/tests/unit/api/v1/test_files.py::test_download_file": 2.474699292011792, - "src/backend/tests/unit/api/v1/test_files.py::test_file_operations": 2.4727731659659185, - "src/backend/tests/unit/api/v1/test_files.py::test_list_files": 3.317764541017823, - "src/backend/tests/unit/api/v1/test_files.py::test_upload_file": 2.4290035419980995, - "src/backend/tests/unit/api/v1/test_files.py::test_upload_file_size_limit": 2.4718297510116827, - "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow": 2.582368832983775, - "src/backend/tests/unit/api/v1/test_flows.py::test_create_flows": 2.7334314990148414, - "src/backend/tests/unit/api/v1/test_flows.py::test_read_basic_examples": 3.6504871669749264, - "src/backend/tests/unit/api/v1/test_flows.py::test_read_flow": 2.5697394589951728, - "src/backend/tests/unit/api/v1/test_flows.py::test_read_flows": 2.6436516670219135, - "src/backend/tests/unit/api/v1/test_flows.py::test_read_flows_user_isolation": 3.153951084037544, - "src/backend/tests/unit/api/v1/test_flows.py::test_update_flow": 2.5014465000131167, - "src/backend/tests/unit/api/v1/test_folders.py::test_create_folder": 2.4833494579943363, - "src/backend/tests/unit/api/v1/test_folders.py::test_read_folder": 2.4764065820199903, - "src/backend/tests/unit/api/v1/test_folders.py::test_read_folders": 2.487064291985007, - "src/backend/tests/unit/api/v1/test_folders.py::test_update_folder": 2.504634041019017, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_disconnect_error": 2.765244457987137, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_invalid_json": 2.8167178750154562, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_no_auth": 2.149924541998189, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_server_error": 2.772359000024153, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_success": 3.952213873999426, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_get_endpoint_invalid_auth": 2.181764957989799, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_head_endpoint": 2.1777867930359207, - "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_head_endpoint_no_auth": 2.1754070409806445, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_handle_project_messages_success": 2.476644499984104, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers": 2.455380542000057, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers_error_handling": 2.670027624000795, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_project_sse_creation": 2.1437969590188004, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_empty_settings": 2.50428270699922, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_invalid_json": 2.481030208989978, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_invalid_project": 2.5376452500058804, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_other_user_project": 2.7707887919677887, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_success": 2.5892928339890204, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_user_can_only_access_own_projects": 4.1938177490083035, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_user_can_update_own_flow_mcp_settings": 2.511545791028766, - "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_user_data_isolation_with_real_db": 2.8074080410588067, - "src/backend/tests/unit/api/v1/test_projects.py::test_create_and_read_project_cyrillic": 2.555548208008986, - "src/backend/tests/unit/api/v1/test_projects.py::test_create_project": 2.4998485410178546, - "src/backend/tests/unit/api/v1/test_projects.py::test_create_project_validation_error": 2.500857791979797, - "src/backend/tests/unit/api/v1/test_projects.py::test_delete_project_then_404": 2.5153850420028903, - "src/backend/tests/unit/api/v1/test_projects.py::test_read_project": 2.4847323760332074, - "src/backend/tests/unit/api/v1/test_projects.py::test_read_project_invalid_id_format": 3.9964210420148447, - "src/backend/tests/unit/api/v1/test_projects.py::test_read_projects": 2.469938791007735, - "src/backend/tests/unit/api/v1/test_projects.py::test_read_projects_empty": 2.7520287910010666, - "src/backend/tests/unit/api/v1/test_projects.py::test_read_projects_pagination": 2.4880284999962896, - "src/backend/tests/unit/api/v1/test_projects.py::test_update_project": 2.5021324589906726, - "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_basic": 2.5396002079651225, - "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_gaps_in_numbering": 2.5215593749890104, - "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_regex_patterns": 2.5361030000203755, - "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_special_characters": 2.5226703330117743, - "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_with_non_numeric_suffixes": 2.513904042018112, - "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_with_numbers_in_original": 2.5571109160082415, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_structure_when_truncate_applies": 0.023025040980428457, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_structure_without_truncate": 0.0024828329915180802, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[0-0]": 0.0007958330097608268, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_authenticated_returns_full_config": 11.88, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_basic": 10.09, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_embedded_mode_cascades_hide_flags": 10.241, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_embedded_mode_false_keeps_individual_hide_flags": 10.444, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_mcp_base_url_defaults_to_empty": 6.31, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_mcp_base_url_from_settings": 9.173, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_returns_500_on_settings_error": 8.817, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_returns_mcp_and_admin_only_flags": 19.059, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_returns_mcp_base_url": 10.503, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_unauthenticated_does_not_expose_sensitive_fields": 10.358, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_unauthenticated_returns_correct_field_types": 2.114, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_unauthenticated_returns_expected_fields": 10.492, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_config_without_authentication_returns_public_config": 8.532, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_get_version": 11.792, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_update_component_model_name_options": 10.135, + "src/backend/tests/unit/api/v1/test_endpoints.py::test_update_component_outputs": 17.327, + "src/backend/tests/unit/api/v1/test_extension_events_endpoint.py::test_empty_string_keyspace_is_also_rejected": 0.041, + "src/backend/tests/unit/api/v1/test_extension_events_endpoint.py::test_keyspace_query_param_is_rejected_with_typed_422": 8.306, + "src/backend/tests/unit/api/v1/test_extension_events_endpoint.py::test_request_without_keyspace_returns_events": 0.04, + "src/backend/tests/unit/api/v1/test_extension_events_endpoint.py::test_service_unavailable_short_circuits_without_touching_keyspace_check": 0.039, + "src/backend/tests/unit/api/v1/test_extensions_route_guard.py::test_guard_passes_when_enabled": 0.041, + "src/backend/tests/unit/api/v1/test_extensions_route_guard.py::test_guard_raises_404_when_disabled": 8.745, + "src/backend/tests/unit/api/v1/test_extensions_route_guard.py::test_guard_treats_missing_attribute_as_disabled": 0.039, + "src/backend/tests/unit/api/v1/test_extensions_route_guard.py::test_no_runtime_mutation_routes": 7.524, + "src/backend/tests/unit/api/v1/test_extensions_route_guard.py::test_route_is_mounted_unconditionally": 5.281, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file": 8.796, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_forward_slash_traversal_blocked[..%2F..%2F..%2Fetc%2Fpasswd]": 10.434, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_forward_slash_traversal_blocked[../../../etc/passwd]": 20.287, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_forward_slash_traversal_blocked[../secret.txt]": 11.771, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_forward_slash_traversal_blocked[subdir%2Ffile.txt]": 8.882, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_forward_slash_traversal_blocked[subdir/file.txt]": 12.253, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_path_traversal_rejected[..\\\\..\\\\..\\\\etc\\\\passwd]": 10.511, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_path_traversal_rejected[..\\\\secret.txt]": 0.154, + "src/backend/tests/unit/api/v1/test_files.py::test_delete_file_path_traversal_rejected[..txt]": 9.898, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file": 10.697, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_forward_slash_traversal_blocked[..%2F..%2F..%2Fetc%2Fpasswd]": 11.487, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_forward_slash_traversal_blocked[../../../etc/passwd]": 10.785, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_forward_slash_traversal_blocked[../secret.txt]": 9.933, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_forward_slash_traversal_blocked[subdir%2Ffile.txt]": 8.938, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_forward_slash_traversal_blocked[subdir/file.txt]": 12.533, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_non_ascii_content_disposition[\\u65e5\\u672c\\u8a9e\\u30d5\\u30a1\\u30a4\\u30eb.txt-%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt]": 12.086, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_non_ascii_content_disposition[\\u6d4b\\u8bd5\\u6587\\u4ef6.txt-%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6.txt]": 11.114, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_non_ascii_content_disposition[\\u9f99.txt-%E9%BE%99.txt]": 10.481, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_non_ascii_content_disposition[na\\xefve_r\\xe9sum\\xe9.txt-na%C3%AFve_r%C3%A9sum%C3%A9.txt]": 2.607, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_non_ascii_content_disposition[normal_file.txt-normal_file.txt]": 10.856, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_path_traversal_rejected[..\\\\..\\\\..\\\\etc\\\\passwd]": 11.323, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_path_traversal_rejected[..\\\\secret.txt]": 10.216, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_path_traversal_rejected[..txt]": 0.311, + "src/backend/tests/unit/api/v1/test_files.py::test_download_file_path_traversal_rejected[test..secret]": 12.139, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_for_browser": 10.437, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_forward_slash_traversal_blocked[..%2F..%2Fimage.png]": 11.621, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_forward_slash_traversal_blocked[../../../etc/passwd.png]": 10.188, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_forward_slash_traversal_blocked[../secret.png]": 9.504, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_forward_slash_traversal_blocked[subdir%2Fimage.png]": 11.465, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_forward_slash_traversal_blocked[subdir/image.png]": 12.1, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_path_traversal_rejected[..\\\\..\\\\..\\\\etc\\\\passwd.png]": 10.099, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_path_traversal_rejected[..\\\\secret.png]": 11.775, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_path_traversal_rejected[..png]": 10.499, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_rejects_non_image_files": 10.369, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_requires_authentication": 9.167, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_returns_404_for_other_users_flow": 11.614, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_returns_correct_content_type": 9.702, + "src/backend/tests/unit/api/v1/test_files.py::test_download_image_with_invalid_flow_id": 8.842, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_config_dir_takes_precedence": 13.036, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_content_is_valid_svg": 12.081, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_fallback_to_package": 11.278, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_invalid_folder": 9.068, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_not_found": 12.165, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_not_found_in_both_locations": 10.441, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_path_traversal_attempt": 1.232, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_people": 0.852, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_space_rocket": 9.978, + "src/backend/tests/unit/api/v1/test_files.py::test_download_profile_picture_special_characters_in_filename": 10.476, + "src/backend/tests/unit/api/v1/test_files.py::test_file_operations": 2.884, + "src/backend/tests/unit/api/v1/test_files.py::test_list_files": 8.527, + "src/backend/tests/unit/api/v1/test_files.py::test_list_profile_pictures": 12.501, + "src/backend/tests/unit/api/v1/test_files.py::test_list_profile_pictures_config_dir_takes_precedence": 10.256, + "src/backend/tests/unit/api/v1/test_files.py::test_list_profile_pictures_empty_response_format": 2.33, + "src/backend/tests/unit/api/v1/test_files.py::test_list_profile_pictures_fallback_to_package": 8.775, + "src/backend/tests/unit/api/v1/test_files.py::test_profile_pictures_different_file_types": 9.959, + "src/backend/tests/unit/api/v1/test_files.py::test_profile_pictures_fallback_with_partial_config_dir": 10.161, + "src/backend/tests/unit/api/v1/test_files.py::test_profile_pictures_with_s3_storage": 10.383, + "src/backend/tests/unit/api/v1/test_files.py::test_upload_file": 22.01, + "src/backend/tests/unit/api/v1/test_files.py::test_upload_file_size_limit": 10.03, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_create_and_get_flow_events": 11.687, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_full_event_lifecycle": 19.519, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_get_events_cursor_based": 10.932, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_invalid_event_type_returns_422": 10.66, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_missing_event_type_returns_422": 12.858, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_nonexistent_flow_returns_404": 9.29, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_settled_on_flow_settled_event": 12.835, + "src/backend/tests/unit/api/v1/test_flow_events.py::test_summary_max_length_returns_422": 9.144, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_create_flow_after_all_folders_deleted_creates_default_folder": 11.31, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_create_flow_with_nonexistent_folder_id_assigns_default_folder": 9.613, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_create_flow_without_folder_id_assigns_default_folder": 11.178, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_flow_created_is_retrievable_in_folder": 10.77, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_update_flow_with_nonexistent_folder_id_assigns_default_folder": 9.035, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_update_flow_without_folder_id_keeps_existing_folder": 12.516, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_upload_flow_with_nonexistent_folder_id_assigns_default": 12.474, + "src/backend/tests/unit/api/v1/test_flow_folder_integrity.py::test_upsert_flow_with_nonexistent_folder_id_on_create": 9.661, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_creates_auto_snapshot": 11.639, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_entry_belonging_to_different_flow": 18.316, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_nonexistent_version_entry": 10.724, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_skips_auto_snapshot_when_save_draft_false": 9.989, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_version_overwrites_flow_data": 20.738, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_version_with_null_data": 9.358, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_activate_with_deeply_nested_data": 8.528, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_create_snapshot": 10.961, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_create_snapshot_accepts_max_description": 20.667, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_create_snapshot_omits_is_deployed": 9.48, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_create_snapshot_rejects_long_description": 11.397, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_create_snapshot_without_description": 12.04, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_delete_entry_belonging_to_different_flow": 9.414, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_delete_nonexistent_version_entry": 9.309, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_delete_version_entry": 1.023, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_deleting_flow_cascades_to_versions": 9.296, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_full_lifecycle": 9.194, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_flow_version_entries_by_ids_rejects_oversized_batch": 7.347, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_nonexistent_version_entry": 11.036, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_entry_strips_api_keys": 11.038, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_version_does_not_trigger_sync_prune": 9.925, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_version_entry_includes_data": 0.708, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_version_reports_unknown_deployment_status_when_attached": 10.067, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_version_reports_unknown_deployment_status_when_feature_disabled": 6.842, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_version_reports_unknown_deployment_status_when_unattached": 10.203, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_single_version_sync_failure_does_not_block_response": 9.757, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_get_versions_for_nonexistent_flow": 12.185, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_empty": 10.958, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_hides_deployment_state_when_feature_disabled": 17.217, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_invalid_limit_zero": 10.154, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_is_deployed_scoped_to_provider": 9.906, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_limit_exceeds_max": 9.303, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_limit_of_one": 11.257, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_omits_is_deployed_without_provider_scope": 10.613, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_pagination": 12.098, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_plain_mode_returns_all": 11.761, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_rejects_foreign_provider_id": 10.258, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_rejects_provider_id_when_feature_disabled": 9.454, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_rejects_unknown_provider_id": 8.726, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_response_includes_max_entries": 10.638, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_returns_entries_newest_first": 11.983, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_sync_failure_does_not_block_response": 10.401, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_list_versions_sync_prunes_stale_attachment": 5.347, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_lowered_limit_prunes_excess_on_next_snapshot": 11.216, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_pruning_deletes_oldest_by_data_content": 11.385, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_rapid_snapshots_with_low_limit": 8.728, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_snapshot_and_activate_with_complex_flow_data": 11.183, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_snapshot_captures_current_flow_data": 9.632, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_snapshot_preserves_full_node_metadata": 10.67, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_unauthenticated_request_is_rejected": 9.771, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_version_entry_scoped_to_flow": 9.408, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_version_limit_enforcement": 10.564, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_version_limit_keeps_newest": 10.613, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_version_number_is_always_positive": 11.55, + "src/backend/tests/unit/api/v1/test_flow_version.py::test_version_numbers_auto_increment": 19.769, + "src/backend/tests/unit/api/v1/test_flows.py::test_bulk_delete_with_deployed_flow_returns_409": 10.447, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow": 11.623, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_accepts_nested_relative_path": 21.277, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_accepts_relative_path": 11.858, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_allows_none_path": 0.172, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_absolute_path_outside_allowed_directory": 10.069, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_directory_traversal": 11.506, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_empty_path": 11.967, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_multiple_traversal": 10.302, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_null_bytes": 16.439, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_traversal_in_subpath": 11.609, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flow_rejects_windows_absolute_path_outside_allowed_directory": 21.566, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flows": 11.461, + "src/backend/tests/unit/api/v1/test_flows.py::test_create_flows_with_explicit_folder": 12.124, + "src/backend/tests/unit/api/v1/test_flows.py::test_delete_flow_with_deployed_versions_returns_409": 9.133, + "src/backend/tests/unit/api/v1/test_flows.py::test_get_flows_with_malformed_bearer_token_returns_401": 10.346, + "src/backend/tests/unit/api/v1/test_flows.py::test_patch_flow_allows_clearing_endpoint_with_null": 12.406, + "src/backend/tests/unit/api/v1/test_flows.py::test_patch_flow_folder_move_with_deployed_versions_returns_409": 7.426, + "src/backend/tests/unit/api/v1/test_flows.py::test_patch_flow_keeps_existing_endpoint_when_not_provided": 11.029, + "src/backend/tests/unit/api/v1/test_flows.py::test_patch_flow_updates_access_and_action_fields": 10.077, + "src/backend/tests/unit/api/v1/test_flows.py::test_read_basic_examples": 12.247, + "src/backend/tests/unit/api/v1/test_flows.py::test_read_flow": 8.853, + "src/backend/tests/unit/api/v1/test_flows.py::test_read_flows": 8.701, + "src/backend/tests/unit/api/v1/test_flows.py::test_read_flows_user_isolation": 9.874, + "src/backend/tests/unit/api/v1/test_flows.py::test_update_flow": 21.726, + "src/backend/tests/unit/api/v1/test_flows.py::test_update_flow_accepts_relative_path": 10.066, + "src/backend/tests/unit/api/v1/test_flows.py::test_update_flow_rejects_absolute_path_outside_allowed_directory": 1.101, + "src/backend/tests/unit/api/v1/test_flows.py::test_upload_flow_accepts_valid_endpoint_name": 8.535, + "src/backend/tests/unit/api/v1/test_flows.py::test_upload_flow_rejects_absolute_path": 10.129, + "src/backend/tests/unit/api/v1/test_flows.py::test_upload_flow_rejects_endpoint_name_with_dots": 10.48, + "src/backend/tests/unit/api/v1/test_flows.py::test_upload_flow_rejects_list_payload": 9.044, + "src/backend/tests/unit/api/v1/test_flows.py::test_upload_flow_rejects_scalar_payload": 22.5, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_allows_clearing_endpoint_with_null": 10.826, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_allows_updating_own_flow_name": 10.515, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_auto_renames_name_on_create_conflict": 11.931, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_creates_new_flow_with_specified_id": 10.75, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_folder_move_with_deployed_versions_returns_409": 12.045, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_ignores_user_id_from_body": 9.174, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_keeps_existing_endpoint_when_not_provided": 11.684, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_keeps_existing_folder_on_update_when_not_provided": 12.458, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_returns_400_for_invalid_folder_id": 9.253, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_returns_404_for_other_users_flow": 11.252, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_returns_409_for_endpoint_conflict_on_update": 11.293, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_returns_409_for_endpoint_name_conflict_on_create": 10.079, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_returns_409_for_name_conflict_on_update": 12.861, + "src/backend/tests/unit/api/v1/test_flows.py::test_upsert_flow_updates_existing_flow": 10.898, + "src/backend/tests/unit/api/v1/test_flows_helpers.py::test_new_flow_with_validate_folder_rejects_unknown_folder": 0.006, + "src/backend/tests/unit/api/v1/test_flows_helpers.py::test_save_flow_to_fs_returns_500_on_os_error": 0.006, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_accepts_absolute_path_within_allowed_directory": 0.036, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_accepts_deeply_nested_path": 0.041, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_accepts_nested_relative_path": 0.041, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_accepts_paths_with_double_slash": 0.043, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_accepts_simple_relative_path": 3.345, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_accepts_valid_filename_characters": 0.042, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_handles_leading_slash_in_relative_path": 8.28, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_path_is_user_isolated": 0.04, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_path_resolves_within_base_directory": 0.04, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_absolute_path_outside_allowed_directory": 0.04, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_backslash_directory_traversal": 0.041, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_directory_traversal": 0.041, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_empty_path": 0.039, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_multiple_traversal": 0.042, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_null_bytes": 0.041, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_symlink_to_prefix_collision_sibling": 0.351, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_traversal_in_subpath": 0.04, + "src/backend/tests/unit/api/v1/test_flows_path_validation.py::TestPathValidation::test_rejects_windows_backslash_traversal": 0.04, + "src/backend/tests/unit/api/v1/test_folders.py::test_create_folder": 12.501, + "src/backend/tests/unit/api/v1/test_folders.py::test_read_folder": 2.639, + "src/backend/tests/unit/api/v1/test_folders.py::test_read_folders": 6.748, + "src/backend/tests/unit/api/v1/test_folders.py::test_update_folder": 9.129, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyGlobalVariableDefaultsAsync::test_applies_defaults_from_variable_service": 1.603, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyGlobalVariableDefaultsAsync::test_no_user_id_returns_input_unchanged": 0.325, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyGlobalVariableDefaultsAsync::test_variable_service_exception_is_swallowed": 0.989, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_empty_field_with_matching_display_name_is_bound": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_empty_unavailable_map_returns_input_unchanged": 0.042, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_field_already_load_from_db_is_left_alone": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_field_with_existing_value_is_left_alone": 0.038, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_hidden_field_is_skipped": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_input_is_not_mutated": 0.043, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_malformed_graph_is_tolerated": 1.202, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_multiple_nodes_mixed_eligibility": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[NestedDict]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[bool]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[code]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[dict]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[float]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[int]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[sortableList]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_non_str_field_types_are_skipped[table]": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_skips_type_marker_field": 2.66, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestApplyUnavailableFieldsToGraph::test_unmatched_display_name_is_left_alone": 0.042, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestBuildUnavailableFieldsMap::test_empty_input": 0.04, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestBuildUnavailableFieldsMap::test_empty_or_none_default_fields_skipped": 0.04, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestBuildUnavailableFieldsMap::test_later_variable_wins_on_collision": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestBuildUnavailableFieldsMap::test_multiple_variables": 0.039, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestBuildUnavailableFieldsMap::test_non_string_field_entries_skipped": 0.041, + "src/backend/tests/unit/api/v1/test_global_variable_defaults.py::TestBuildUnavailableFieldsMap::test_single_variable_with_default_fields": 0.039, + "src/backend/tests/unit/api/v1/test_mcp.py::test_find_validation_error_with_context": 0.042, + "src/backend/tests/unit/api/v1/test_mcp.py::test_find_validation_error_with_pydantic_error": 0.04, + "src/backend/tests/unit/api/v1/test_mcp.py::test_find_validation_error_without_pydantic_error": 0.881, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_disconnect_error": 22.653, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_invalid_json": 9.712, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_no_auth": 10.378, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_server_error": 12.54, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_post_endpoint_success": 14.726, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_context_token_management": 2.719, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_get_endpoint_invalid_auth": 19.56, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_head_endpoint": 15.515, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_head_endpoint_no_auth": 8.301, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_post_endpoint": 1.728, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_post_endpoint_disconnect_error": 9.09, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_post_endpoint_server_error": 11.177, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_sse_validation_error_logged": 0.44, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_delete_endpoint": 8.034, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_delete_endpoint_no_auth": 8.644, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_get_endpoint": 14.775, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_get_endpoint_no_auth": 9.056, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_post_endpoint": 0.007, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_post_endpoint_disconnect_error": 14.25, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_post_endpoint_no_auth": 9.748, + "src/backend/tests/unit/api/v1/test_mcp.py::test_mcp_streamable_post_endpoint_server_error": 9.099, + "src/backend/tests/unit/api/v1/test_mcp.py::test_streamable_http_start_failure_keeps_manager_unavailable": 0.04, + "src/backend/tests/unit/api/v1/test_mcp.py::test_streamable_http_start_failure_surfaces_exception_once": 0.038, + "src/backend/tests/unit/api/v1/test_mcp.py::test_streamable_http_start_stop_lifecycle": 0.039, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestAddComponent::test_add_component": 19.597, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestAddComponent::test_add_unknown_component_raises": 19.5, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestBatch::test_batch_bad_ref_raises": 18.013, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestBatch::test_batch_build_flow": 22.465, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestBatch::test_batch_unknown_tool_raises": 9.94, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestComponentsTool::test_describe_mode": 9.435, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestComponentsTool::test_list_all": 21.519, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestComponentsTool::test_search_mode": 15.52, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestConfigureComponent::test_configure_dynamic_field": 9.175, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestConfigureComponent::test_configure_nonexistent_component_raises": 9.006, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestConfigureComponent::test_configure_static_param": 10.328, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestConnectComponents::test_connect_component_as_tool_auto_enables_tool_mode": 22.058, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestConnectComponents::test_connect_components": 9.848, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlow::test_create_flow": 9.09, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlow::test_create_flow_default_name": 9.751, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec": 14.533, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec_coerces_numeric_config": 10.452, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec_prompt_multiple_variables": 22.37, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec_unknown_node_in_config": 16.664, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec_unknown_node_in_edge": 17.931, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec_with_config": 19.878, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestCreateFlowFromSpec::test_create_flow_from_spec_with_tool_mode": 10.801, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDeleteFlow::test_delete_flow": 12.048, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDescribeComponentType::test_describe_advanced_fields": 11.09, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDescribeComponentType::test_describe_chat_input": 11.871, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDescribeComponentType::test_describe_unknown_raises": 11.507, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDisconnectComponents::test_disconnect_components": 3.024, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDisconnectComponents::test_disconnect_no_match_raises": 10.782, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestDuplicateFlow::test_duplicate_flow": 2.253, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestExportFlow::test_export_flow_redacts_secrets": 12.172, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestExportFlow::test_export_flow_structure": 20.182, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestFreezeComponent::test_freeze_and_unfreeze": 9.18, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestFreezeComponent::test_freeze_unknown_component_raises": 10.894, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetBuildResults::test_get_build_results_after_run": 11.877, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetBuildResults::test_get_build_results_empty_flow": 10.942, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetBuildResults::test_get_component_output_after_run": 26.084, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetComponentInfo::test_get_component_info": 10.97, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetComponentInfo::test_get_component_info_redacts_secrets": 12.38, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetComponentInfo::test_get_single_field": 9.529, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetComponentInfo::test_get_single_field_redacts_secret": 20.213, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetComponentInfo::test_get_single_field_unknown_raises": 10.056, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGetFlowInfo::test_get_flow_info": 10.912, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGraphRepr::test_get_flow_info_includes_graph": 11.296, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestGraphRepr::test_list_flows_includes_graph": 13.007, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestLayoutFlow::test_layout_flow": 4.282, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestListComponents::test_list_components": 20.071, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestListFlows::test_list_flows_after_create": 9.728, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestListFlows::test_list_flows_empty": 12.63, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestRemoveComponent::test_remove_component": 7.534, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestRenameFlow::test_rename_flow_description": 0.124, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestRenameFlow::test_rename_flow_name": 10.929, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestRenameFlow::test_rename_flow_no_args_raises": 9.414, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestRunFlow::test_run_simple_flow": 10.799, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestRunFlow::test_stream_post_yields_events": 13.927, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestSearchComponentTypes::test_search_all": 9.391, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestSearchComponentTypes::test_search_by_category": 9.305, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestSearchComponentTypes::test_search_by_output_type": 12.764, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestSearchComponentTypes::test_search_by_query": 13.526, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestSpecSummaryInResponses::test_get_flow_info_includes_spec_summary": 11.003, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestSpecSummaryInResponses::test_list_flows_includes_spec_summary": 17.595, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestStarterProjects::test_list_starter_projects": 3.061, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestStarterProjects::test_use_starter_project": 12.721, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestStarterProjects::test_use_starter_project_unknown_raises": 13.669, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestUpdateFlowFromSpec::test_update_preserves_flow_id": 14.118, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestUpdateFlowFromSpec::test_update_rejects_bad_edge_reference": 10.783, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestUpdateFlowFromSpec::test_update_replaces_flow_content": 12.841, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestValidateFlow::test_validate_empty_flow": 1.673, + "src/backend/tests/unit/api/v1/test_mcp_client_server.py::TestValidateFlow::test_validate_flow_returns_structured_result": 19.041, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_args_reference_urls_filters_strings_only[None-urls0-False]": 9.411, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_args_reference_urls_filters_strings_only[args1-urls1-False]": 12.479, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_args_reference_urls_filters_strings_only[args2-urls2-False]": 12.371, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_args_reference_urls_filters_strings_only[args3-urls3-True]": 16.008, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_args_reference_urls_filters_strings_only[args4-urls4-False]": 3.949, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_args_reference_urls_matches_non_last_string_argument": 9.215, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_handle_list_tools_filters_by_user_id_for_defense_in_depth": 7.164, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_handle_project_messages_success": 21.425, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_handle_project_streamable_messages_success": 11.927, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers": 10.901, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers_error_handling": 11.165, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers_error_handling_streamable": 12.101, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers_reconciles_existing_apikey_project_server_config": 11.079, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers_reconciles_project_server_auth_when_oauth_falls_back": 10.139, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_init_mcp_servers_rolls_back_auth_update_when_reconciliation_fails": 10.609, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_install_mcp_config_defaults_to_sse_transport": 11.71, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_install_mcp_config_streamable_transport": 14.23, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_is_mcp_servers_locked_does_not_fire_for_magicmock_settings": 12.375, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_is_mcp_servers_locked_respects_explicit_true_flag": 7.379, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_list_project_tools_response_structure": 12.724, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_list_project_tools_with_mcp_enabled_filter": 12.097, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_mcp_longterm_token_fails_without_superuser": 12.363, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_patch_project_mcp_settings_syncs_server_config_for_apikey": 11.097, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_project_session_manager_lifespan_handles_cleanup": 2.476, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_project_sse_creation": 12.144, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_settings_model_declares_mcp_servers_locked_field": 22.5, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_should_report_available_false_when_app_directory_does_not_exist": 6.54, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_should_report_available_true_when_app_directory_exists_but_config_file_missing": 5.234, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_should_report_available_true_when_config_file_has_corrupt_json": 6.08, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_should_report_installed_false_when_config_file_has_no_matching_url": 13.459, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_should_report_installed_true_when_config_file_contains_matching_url": 11.12, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_sse_rejects_unauthenticated_oauth_project": 0.424, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_streamable_oauth_project_accepts_valid_api_key": 14.091, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_streamable_oauth_project_accepts_valid_composer_backend_token": 12.39, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_streamable_oauth_project_rejects_invalid_api_key": 22.459, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_streamable_rejects_unauthenticated_oauth_project": 0.157, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_streamable_rejects_unauthenticated_oauth_project_trailing_slash": 3.964, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_auth_settings_encryption": 11.938, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_empty_settings": 22.889, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_invalid_json": 1.249, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_invalid_project": 13.044, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_other_user_project": 12.017, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_other_user_project_with_composer": 11.998, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_update_project_mcp_settings_success": 12.841, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_user_can_only_access_own_projects": 14.202, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_user_can_update_own_flow_mcp_settings": 10.628, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_user_data_isolation_with_real_db": 0.579, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_v2_mcp_servers_locked_allows_superuser_add_patch_delete": 11.608, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_v2_mcp_servers_locked_blocks_non_superuser_add_patch_delete": 1.708, + "src/backend/tests/unit/api/v1/test_mcp_projects.py::test_v2_mcp_servers_unlocked_allows_non_superuser_add_patch_delete": 10.74, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestForwardedPrefixMiddleware::test_forwarded_prefix_header_sets_downstream_root_path": 0.031, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestForwardedPrefixMiddleware::test_middleware_ignores_header_when_root_path_not_configured": 0.079, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestForwardedPrefixMiddleware::test_middleware_rejects_invalid_prefix": 0.052, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestForwardedPrefixMiddleware::test_middleware_sets_root_path_when_enabled": 0.029, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestForwardedPrefixMiddleware::test_no_header_preserves_root_path": 0.028, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestRootPathSetting::test_root_path_can_be_set": 0.001, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestRootPathSetting::test_root_path_default_empty": 0.08, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestSseTransportRootPath::test_endpoint_stored": 0.041, + "src/backend/tests/unit/api/v1/test_mcp_reverse_proxy.py::TestSseTransportRootPath::test_project_transport_endpoint": 0.041, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::TestExtractGlobalVariablesFromHeaders::test_auth_header_matching_is_case_insensitive": 0.094, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::TestExtractGlobalVariablesFromHeaders::test_auth_headers_extracted_under_lowercase_when_opted_in": 0.091, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::TestExtractGlobalVariablesFromHeaders::test_auth_headers_not_extracted_by_default": 0.082, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::TestExtractGlobalVariablesFromHeaders::test_both_categories_extracted_together": 0.042, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::TestExtractGlobalVariablesFromHeaders::test_langflow_global_var_prefix_still_extracted": 0.042, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_call_tool_falls_back_when_session_id_blank": 0.042, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_call_tool_generates_session_id_when_omitted": 0.039, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_call_tool_uses_provided_session_id": 3.883, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_list_resources_includes_flow_and_user_files": 0.043, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_list_resources_project_scoped_excludes_user_bucket": 7.001, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_list_resources_requires_current_user": 0.005, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_list_tools_requires_current_user_on_global_server": 0.041, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_list_tools_skips_blocked_custom_flows": 0.038, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_read_resource_allows_user_level_bucket": 0.042, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_read_resource_denies_other_users_flow": 0.007, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_read_resource_denies_user_bucket_under_project_scope": 6.096, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_handle_read_resource_rejects_path_traversal": 0.008, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_json_schema_from_flow_includes_optional_session_id": 3.177, + "src/backend/tests/unit/api/v1/test_mcp_utils.py::test_json_schema_from_flow_preserves_flow_defined_session_id": 4.265, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_backward_compatible_variable_mapping": 12.199, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_enabled_providers_after_credential_creation": 12.552, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_enabled_providers_after_credential_deletion": 9.63, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_enabled_providers_empty_initially": 14.328, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_enabled_providers_filter_by_specific_providers": 15.479, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_enabled_providers_multiple_credentials": 11.859, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_enabled_providers_reflects_models_endpoint": 12.289, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_list_models_ollama_empty_when_live_fetch_returns_empty": 10.961, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_list_models_returns_live_ollama_models_when_configured": 13.439, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_provider_variable_mapping_multi_variable_provider": 8.539, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_provider_variable_mapping_returns_full_variable_info": 11.363, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_security_credential_value_never_exposed_in_variables_endpoint": 12.428, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_variables_credential_redaction": 12.977, + "src/backend/tests/unit/api/v1/test_models_enabled_providers.py::test_variables_multiple_credentials_all_redacted": 12.171, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_delete_messages_session_requires_auth": 2.046, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_delete_messages_session_with_fake_token": 11.917, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_delete_messages_session_with_valid_auth": 1.154, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_get_messages_requires_auth": 13.829, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_get_messages_with_fake_token": 3.006, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_get_messages_with_valid_auth": 2.765, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_get_transactions_requires_auth": 11.178, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_get_transactions_with_fake_token": 10.809, + "src/backend/tests/unit/api/v1/test_monitor_auth.py::test_get_transactions_with_valid_auth": 2.588, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_compute_virtual_flow_id_accepts_string_identifier": 0.041, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_compute_virtual_flow_id_differs_between_users": 0.046, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_compute_virtual_flow_id_differs_per_flow": 8.513, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_compute_virtual_flow_id_differs_per_user": 6.41, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_compute_virtual_flow_id_is_deterministic": 9.158, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_compute_virtual_flow_id_returns_uuid": 11.144, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_delete_shared_session_removes_messages": 10.919, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_delete_shared_session_requires_auth": 10.038, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_get_shared_messages_empty_for_wrong_flow": 12.357, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_get_shared_messages_requires_auth": 15.29, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_get_shared_messages_returns_messages": 0.062, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_get_shared_sessions_requires_auth": 3.577, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_get_shared_sessions_returns_user_sessions": 12.76, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_rename_shared_session": 15.793, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_rename_shared_session_requires_auth": 14.079, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_shared_messages_isolated_between_users": 11.032, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_update_shared_message_requires_auth": 9.478, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_update_shared_message_returns_404_for_nonexistent_id": 2.728, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_update_shared_message_returns_404_for_wrong_flow": 0.008, + "src/backend/tests/unit/api/v1/test_monitor_shared.py::test_update_shared_message_updates_properties": 2.254, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_empty_body_returns_default": 0.704, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_json_body_preserves_user_id": 0.041, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_json_body_still_parsed": 0.057, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_malformed_json_returns_default": 9.198, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_multipart_form_data_preserves_session_id_and_input": 4.782, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_multipart_form_data_preserves_user_id": 0.039, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_multipart_ignores_file_in_known_fields": 0.041, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_multipart_invalid_tweaks_json_does_not_crash": 0.04, + "src/backend/tests/unit/api/v1/test_parse_input_request_from_body.py::test_multipart_tweaks_parsed_as_json": 10.989, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_auto_login_disabled_adds_api_key_auth": 11.771, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_oauth_not_implemented": 10.296, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_oauth_not_implemented_legacy_sse": 13.127, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_with_mcp_auto_add_disabled": 22.362, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_with_mcp_auto_add_enabled_success": 9.766, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_with_mcp_auto_add_enabled_success_legacy_sse": 11.803, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_with_mcp_server_conflict": 12.823, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_create_project_with_mcp_server_conflict_legacy_sse": 11.281, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_delete_project_mcp_server_different_project": 11.306, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_delete_project_mcp_server_different_project_legacy_sse": 13.44, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_delete_project_with_mcp_server_cleanup": 12.545, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_delete_project_with_mcp_server_cleanup_legacy_sse": 11.94, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_project_mcp_exception_handling": 3.505, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_project_mcp_exception_handling_legacy_sse": 11.432, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_update_project_name_with_mcp_conflict": 11.838, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_update_project_name_with_mcp_conflict_legacy_sse": 1.419, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_update_project_name_with_mcp_server_update": 20.417, + "src/backend/tests/unit/api/v1/test_projects.py::TestProjectMCPIntegration::test_update_project_name_with_mcp_server_update_legacy_sse": 16.154, + "src/backend/tests/unit/api/v1/test_projects.py::TestReadProjectBugFix::test_read_project_consistent_response_structure": 9.248, + "src/backend/tests/unit/api/v1/test_projects.py::TestReadProjectBugFix::test_read_project_error_handling_consistency": 11.52, + "src/backend/tests/unit/api/v1/test_projects.py::TestReadProjectBugFix::test_read_project_with_filtering_params": 12.982, + "src/backend/tests/unit/api/v1/test_projects.py::TestReadProjectBugFix::test_read_project_with_pagination_params": 12.832, + "src/backend/tests/unit/api/v1/test_projects.py::TestReadProjectBugFix::test_read_project_with_partial_pagination_params": 4.468, + "src/backend/tests/unit/api/v1/test_projects.py::TestReadProjectBugFix::test_read_project_without_pagination_params": 8.882, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_and_read_project_cyrillic": 12.226, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_project": 12.133, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_project_does_not_reassign_other_users_flows": 11.256, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_project_duplicate_name_escapes_like_wildcards": 12.801, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_project_validation_error": 11.348, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_project_with_deployed_flow_returns_409_guard": 11.695, + "src/backend/tests/unit/api/v1/test_projects.py::test_create_project_with_own_flows_assigns_them_correctly": 12.331, + "src/backend/tests/unit/api/v1/test_projects.py::test_delete_project_then_404": 11.679, + "src/backend/tests/unit/api/v1/test_projects.py::test_delete_project_with_deployments_returns_409_project_guard": 9.872, + "src/backend/tests/unit/api/v1/test_projects.py::test_download_file_starter_project": 10.808, + "src/backend/tests/unit/api/v1/test_projects.py::test_download_project_missing_returns_404": 10.877, + "src/backend/tests/unit/api/v1/test_projects.py::test_download_project_sanitizes_windows_path_characters": 9.776, + "src/backend/tests/unit/api/v1/test_projects.py::test_download_project_with_no_flows_returns_404": 11.471, + "src/backend/tests/unit/api/v1/test_projects.py::test_read_project": 22.979, + "src/backend/tests/unit/api/v1/test_projects.py::test_read_project_invalid_id_format": 11.96, + "src/backend/tests/unit/api/v1/test_projects.py::test_read_project_paginated_only_returns_current_users_flows": 12.886, + "src/backend/tests/unit/api/v1/test_projects.py::test_read_projects": 12.132, + "src/backend/tests/unit/api/v1/test_projects.py::test_read_projects_empty": 11.31, + "src/backend/tests/unit/api/v1/test_projects.py::test_read_projects_pagination": 0.73, + "src/backend/tests/unit/api/v1/test_projects.py::test_update_project": 11.229, + "src/backend/tests/unit/api/v1/test_projects.py::test_update_project_preserves_components": 11.921, + "src/backend/tests/unit/api/v1/test_projects.py::test_update_project_preserves_flows": 11.64, + "src/backend/tests/unit/api/v1/test_projects.py::test_update_project_preserves_mixed_flows_and_components": 11.409, + "src/backend/tests/unit/api/v1/test_projects.py::test_update_project_with_deployed_component_returns_409_guard": 14.07, + "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_basic": 12.153, + "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_gaps_in_numbering": 1.735, + "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_regex_patterns": 10.111, + "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_special_characters": 4.316, + "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_with_non_numeric_suffixes": 6.362, + "src/backend/tests/unit/api/v1/test_rename_flow_to_save.py::test_duplicate_flow_name_with_numbers_in_original": 12.34, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_structure_when_truncate_applies": 0.043, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_structure_without_truncate": 0.042, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[0-0]": 11.18, "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[100-100]": 0.0012827390000325067, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[1000-1000]": 0.007933541986858472, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[1000-1000]": 0.053, "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[1100-101]": 0.002772633000006408, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[2000-1001]": 0.008365543006220832, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[2000-1001]": 0.037, "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[2100-101]": 0.004317118000017217, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[3000-1001]": 0.009354082983918488, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[3000-1001]": 0.026, "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[3100-101]": 0.0056621729999619674, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[4000-1001]": 0.009598375007044524, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[4000-1001]": 9.03, "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[42-42]": 0.0015994080000609756, - "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[8-8]": 0.0007110010192263871, - "src/backend/tests/unit/api/v1/test_starter_projects.py::test_get_starter_projects": 2.6394810419878922, - "src/backend/tests/unit/api/v1/test_store.py::test_check_if_store_is_enabled": 1.876104333990952, - "src/backend/tests/unit/api/v1/test_users.py::test_add_user": 4.005188834009459, - "src/backend/tests/unit/api/v1/test_users.py::test_delete_user": 2.7974890820041765, - "src/backend/tests/unit/api/v1/test_users.py::test_patch_user": 3.1082065000082366, - "src/backend/tests/unit/api/v1/test_users.py::test_read_all_users": 2.507381165982224, - "src/backend/tests/unit/api/v1/test_users.py::test_read_current_user": 2.514553042012267, - "src/backend/tests/unit/api/v1/test_users.py::test_reset_password": 3.102323331986554, - "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_code": 2.5075825010135304, - "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_code_with_unauthenticated_user": 2.0713883750140667, - "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_prompt": 2.6730809160217177, - "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_prompt_with_invalid_data": 3.50601858299342, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable": 2.6408770410052966, + "src/backend/tests/unit/api/v1/test_schemas.py::test_vertex_response_truncation_behavior[8-8]": 0.063, + "src/backend/tests/unit/api/v1/test_starter_projects.py::test_get_starter_projects": 1.626, + "src/backend/tests/unit/api/v1/test_store.py::test_check_if_store_is_enabled": 1.994, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTrace::test_should_return_204_on_success": 0.041, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTrace::test_should_return_404_when_trace_not_found": 0.023, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTrace::test_should_return_422_for_invalid_trace_id": 0.044, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTrace::test_should_return_500_on_unexpected_error": 0.028, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTracesByFlow::test_should_execute_bulk_delete_not_individual": 0.015, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTracesByFlow::test_should_return_204_on_success": 0.045, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTracesByFlow::test_should_return_404_when_flow_not_found": 0.12, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTracesByFlow::test_should_return_422_for_invalid_flow_id": 0.026, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTracesByFlow::test_should_return_422_when_flow_id_missing": 0.023, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestDeleteTracesByFlow::test_should_return_500_on_unexpected_error": 0.004, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_pass_correct_user_id_to_fetch": 0.037, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_return_200_with_trace": 0.04, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_return_404_when_trace_not_found": 0.043, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_return_422_for_invalid_trace_id": 0.163, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_return_500_on_operational_error": 0.041, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_return_500_on_unexpected_error": 0.026, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTrace::test_should_return_504_on_timeout": 0.028, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_accept_page_zero_as_first_page": 0.042, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_pass_flow_id_filter": 0.041, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_pass_none_query_when_query_is_whitespace_only": 0.04, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_pass_sanitized_query_to_fetch_traces": 0.038, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_pass_status_filter": 0.041, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_propagate_unexpected_error": 0.285, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_reject_size_above_maximum": 0.049, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_return_200_with_trace_list": 0.037, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_return_empty_list_on_operational_error": 0.038, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_return_empty_list_on_programming_error": 0.039, + "src/backend/tests/unit/api/v1/test_traces_api.py::TestGetTraces::test_should_return_empty_list_on_timeout": 0.036, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_is_sensitive_key_matches_expected_keys": 0.042, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_case_insensitive": 0.042, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_handles_lists": 0.043, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_handles_nested_dicts": 0.042, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_masks_api_key": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_masks_password": 0.043, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_masks_various_sensitive_keys": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_preserves_non_sensitive_data": 0.04, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_removes_code_key": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestSanitizeData::test_sanitize_data_returns_none_for_none_input": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_creation": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_filters_code_from_inputs": 0.04, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_flow_id_string_conversion": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_sanitizes_nested_sensitive_data": 0.04, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_sanitizes_sensitive_data_in_inputs": 0.042, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_sanitizes_sensitive_data_in_outputs": 0.042, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_base_with_error": 0.04, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionModels::test_transaction_logs_response_from_table": 0.04, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionTransformers::test_transform_transaction_table_for_logs_list": 1.645, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionTransformers::test_transform_transaction_table_for_logs_single": 11.074, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionTransformers::test_transform_transaction_table_list": 0.039, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionTransformers::test_transform_transaction_table_single": 3.514, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionWithOutputs::test_transaction_base_outputs_sanitization": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionWithOutputs::test_transaction_base_with_explicit_outputs": 0.041, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionWithOutputs::test_transaction_logs_response_includes_outputs": 7.314, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionWithOutputs::test_transaction_table_with_outputs": 6.201, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionsEndpoint::test_get_transactions_invalid_flow_id_format": 19.631, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionsEndpoint::test_get_transactions_requires_auth": 10.836, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionsEndpoint::test_get_transactions_requires_flow_id": 12.707, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionsEndpoint::test_get_transactions_response_structure": 11.243, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionsEndpoint::test_get_transactions_returns_paginated_response": 9.15, + "src/backend/tests/unit/api/v1/test_transactions.py::TestTransactionsEndpoint::test_get_transactions_with_pagination_params": 8.391, + "src/backend/tests/unit/api/v1/test_users.py::test_add_user": 9.788, + "src/backend/tests/unit/api/v1/test_users.py::test_add_user_duplicate_username": 10.025, + "src/backend/tests/unit/api/v1/test_users.py::test_add_user_public_signup": 13.315, + "src/backend/tests/unit/api/v1/test_users.py::test_delete_user": 10.573, + "src/backend/tests/unit/api/v1/test_users.py::test_patch_user": 8.467, + "src/backend/tests/unit/api/v1/test_users.py::test_patch_user_deactivate_other_user_allowed": 9.617, + "src/backend/tests/unit/api/v1/test_users.py::test_patch_user_self_deactivation_forbidden": 11.704, + "src/backend/tests/unit/api/v1/test_users.py::test_patch_user_self_deactivation_forbidden_superuser": 19.287, + "src/backend/tests/unit/api/v1/test_users.py::test_read_all_users": 10.601, + "src/backend/tests/unit/api/v1/test_users.py::test_read_all_users_search": 10.809, + "src/backend/tests/unit/api/v1/test_users.py::test_read_current_user": 8.396, + "src/backend/tests/unit/api/v1/test_users.py::test_reset_password": 12.557, + "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_code": 9.229, + "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_code_with_unauthenticated_user": 9.719, + "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_prompt": 11.09, + "src/backend/tests/unit/api/v1/test_validate.py::test_post_validate_prompt_with_invalid_data": 12.476, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable": 10.742, "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__Exception": 5.891528583015315, "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__HTTPException": 2.8841335409670137, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__exception": 2.5489250009995885, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__httpexception": 2.5547019169898704, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__anthropic_api_key_validation_failure": 9.246, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__anthropic_api_key_validation_success": 7.123, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__exception": 11.041, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__google_api_key_validation_success": 10.901, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__httpexception": 10.811, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__model_provider_network_error_allows_creation": 12.578, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__ollama_base_url_validation_failure": 10.513, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__ollama_base_url_validation_success": 10.943, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__openai_api_key_validation_failure": 12.046, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__openai_api_key_validation_success": 11.055, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__openrouter_api_key_validation_failure": 9.764, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__openrouter_api_key_validation_success": 19.402, "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_alread_exists": 3.690157334029209, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_already_exists": 2.5517429169849493, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_and_value_cannot_be_empty": 2.5338064569805283, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_cannot_be_empty": 2.58213637501467, - "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_value_cannot_be_empty": 5.253880292963004, - "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable": 2.557073792995652, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_already_exists": 9.368, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_and_value_cannot_be_empty": 9.628, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_name_cannot_be_empty": 10.749, + "src/backend/tests/unit/api/v1/test_variable.py::test_create_variable__variable_value_cannot_be_empty": 8.784, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_non_provider_credential_does_not_cleanup_models": 4.725, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_provider_credential_cleans_up_disabled_models": 10.888, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_provider_credential_cleans_up_enabled_models": 12.623, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable": 11.018, "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable__Exception": 3.1565893749939278, "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable__exception": 2.568733041989617, - "src/backend/tests/unit/api/v1/test_variable.py::test_read_variables": 2.582863333984278, - "src/backend/tests/unit/api/v1/test_variable.py::test_read_variables__": 2.563697667006636, - "src/backend/tests/unit/api/v1/test_variable.py::test_read_variables__empty": 2.5792906249698717, - "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable": 2.556691708014114, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable__not_found": 12.141, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable_cross_user_allowed_with_plugin": 9.172, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable_cross_user_denied_with_plugin": 1.805, + "src/backend/tests/unit/api/v1/test_variable.py::test_delete_variable_non_owner_returns_404_under_oss": 8.712, + "src/backend/tests/unit/api/v1/test_variable.py::test_detect_env_vars_endpoint__rejects_missing_nodes": 11.066, + "src/backend/tests/unit/api/v1/test_variable.py::test_detect_env_vars_endpoint__returns_detected_names": 0.876, + "src/backend/tests/unit/api/v1/test_variable.py::test_read_variables": 8.596, + "src/backend/tests/unit/api/v1/test_variable.py::test_read_variables__": 9.11, + "src/backend/tests/unit/api/v1/test_variable.py::test_read_variables__empty": 10.48, + "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable": 13.371, "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable__Exception": 3.202228542009834, - "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable__exception": 2.612043667031685, - "src/backend/tests/unit/api/v2/test_files.py::test_delete_file": 2.5786768340331037, - "src/backend/tests/unit/api/v2/test_files.py::test_download_file": 2.569752043025801, - "src/backend/tests/unit/api/v2/test_files.py::test_edit_file": 2.5710495410021394, - "src/backend/tests/unit/api/v2/test_files.py::test_list_files": 2.6288422499783337, - "src/backend/tests/unit/api/v2/test_files.py::test_mcp_servers_file_replacement": 2.607162458007224, - "src/backend/tests/unit/api/v2/test_files.py::test_unique_filename_counter_handles_gaps": 2.6284001680032816, - "src/backend/tests/unit/api/v2/test_files.py::test_unique_filename_path_storage": 2.6036685010185465, - "src/backend/tests/unit/api/v2/test_files.py::test_upload_file": 2.5614012499863748, - "src/backend/tests/unit/api/v2/test_files.py::test_upload_files_with_different_extensions_same_name": 2.603973582998151, - "src/backend/tests/unit/api/v2/test_files.py::test_upload_files_with_same_name_creates_unique_names": 2.623052831972018, - "src/backend/tests/unit/api/v2/test_files.py::test_upload_files_without_extension_creates_unique_names": 5.934239873953629, - "src/backend/tests/unit/api/v2/test_files.py::test_upload_list_delete_and_validate_files": 2.613800998980878, - "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_mcp_servers_upload_replace": 0.012480165984015912, - "src/backend/tests/unit/base/load/test_load.py::test_run_flow_from_json_params": 0.003475541976513341, - "src/backend/tests/unit/base/load/test_load.py::test_run_flow_with_fake_env": 0.043105750024551526, - "src/backend/tests/unit/base/load/test_load.py::test_run_flow_with_fake_env_tweaks": 0.027037374005885795, + "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable__exception": 9.793, + "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable_cross_user_allowed_with_plugin": 12.179, + "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable_cross_user_denied_with_plugin": 21.184, + "src/backend/tests/unit/api/v1/test_variable.py::test_update_variable_non_owner_returns_404_under_oss": 7.626, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_both_source_and_file": 0.042, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_llm_component": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_non_dict_content": 0.042, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_non_message_type": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_retriever": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_save_to_file": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestBuildMetadataForNonOutput::test_build_metadata_vector_store": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestCreateErrorResponse::test_create_error_response_error_details": 0.042, + "src/backend/tests/unit/api/v2/test_converters.py::TestCreateErrorResponse::test_create_error_response_preserves_globals": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestCreateErrorResponse::test_create_error_response_preserves_inputs": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestCreateErrorResponse::test_create_error_response_structure": 0.042, + "src/backend/tests/unit/api/v2/test_converters.py::TestCreateJobResponse::test_create_job_response_structure": 0.042, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractFilePath::test_extract_file_path_case_insensitive": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractFilePath::test_extract_file_path_missing_message": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractFilePath::test_extract_file_path_valid": 0.042, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractFilePath::test_extract_file_path_wrong_component_type": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractModelSource::test_extract_model_source_anthropic": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractModelSource::test_extract_model_source_missing_model_name": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractModelSource::test_extract_model_source_missing_structure": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractModelSource::test_extract_model_source_openai": 0.043, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_from_chroma_output": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_from_pinecone_output": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_from_result_data_object": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_from_retriever_output": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_from_weaviate_output": 0.043, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_message_from_chat_output": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_model_output_message_model_name": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_nested_value_error_handling": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_result_message_from_data_output": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractNestedValue::test_extract_text_from_output_value": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_direct_message_string": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_direct_text_string": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_chat_output_nested_message": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_embedding_output": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_llm_output_message_text": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_output_value_message_structure": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_text_message_structure": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_text_text_structure": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_from_tool_output": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_no_extractable_text": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_non_string_values": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_priority_message_message_first": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_priority_message_text_over_direct_text": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_text_circular_reference": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_text_extremely_nested": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestExtractTextFromMessage::test_extract_text_mixed_types_in_path": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestGetRawContent::test_get_raw_content_fallback": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestGetRawContent::test_get_raw_content_from_dict_results": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestGetRawContent::test_get_raw_content_from_messages": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestGetRawContent::test_get_raw_content_from_outputs": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestGetRawContent::test_get_raw_content_from_results": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestGetRawContent::test_get_raw_content_priority_outputs": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_basic": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_deeply_nested_dict": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_dict_values": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_empty": 0.039, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_empty_collections": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_explicit_none_values": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_malformed_key_no_dot": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_mixed_formats": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_multiple_params_same_component": 0.043, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_multiple_session_ids": 0.039, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_null_values": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_special_characters_in_keys": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestParseFlatInputs::test_parse_flat_inputs_with_session_id": 0.039, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_basic_output_node": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_corrupted_vertex_data": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_data_type_non_output": 5.424, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_duplicate_display_names": 0.965, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_empty_outputs": 7.644, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_fallback_terminal_detection": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_missing_required_fields": 9.911, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_non_output_terminal_node": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_preserves_globals": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_preserves_inputs": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_retriever_with_metadata": 0.337, + "src/backend/tests/unit/api/v2/test_converters.py::TestRunResponseToWorkflowResponse::test_run_response_vector_store_terminal": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_data_type": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_data_type_no_extraction": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_message_no_text_found": 0.04, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_message_type": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_non_dict_content": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_text_type": 0.041, + "src/backend/tests/unit/api/v2/test_converters.py::TestSimplifyOutputContent::test_simplify_unknown_type": 0.041, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_batch_delete_message_all_successful": 0.036, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_batch_delete_message_with_transient_failures": 0.027, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_batch_delete_with_mixed_failures": 0.022, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_delete_all_files_message_all_successful": 0.026, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_delete_all_files_message_with_transient_failures": 0.04, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_delete_file_with_permanent_failure_deletes_from_db": 0.03, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_delete_file_with_transient_failure_keeps_in_db": 0.027, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_is_permanent_storage_failure_fallback_string_matching": 0.055, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_is_permanent_storage_failure_file_not_found_error": 0.062, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_is_permanent_storage_failure_s3_no_such_bucket": 0.056, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_is_permanent_storage_failure_s3_no_such_key": 0.066, + "src/backend/tests/unit/api/v2/test_files.py::TestStorageFailureHandling::test_is_permanent_storage_failure_transient_error": 0.057, + "src/backend/tests/unit/api/v2/test_files.py::test_batch_download_files_non_ascii_content_disposition": 3.654, + "src/backend/tests/unit/api/v2/test_files.py::test_delete_file": 11.1, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file": 10.948, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file_non_ascii_content_disposition[\\u65e5\\u672c\\u8a9e\\u30d5\\u30a1\\u30a4\\u30eb.txt-%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.txt]": 10.735, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file_non_ascii_content_disposition[\\u6d4b\\u8bd5\\u6587\\u4ef6.txt-%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6.txt]": 10.331, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file_non_ascii_content_disposition[\\u9f99.txt-%E9%BE%99.txt]": 6.506, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file_non_ascii_content_disposition[na\\xefve_r\\xe9sum\\xe9.txt-na%C3%AFve_r%C3%A9sum%C3%A9.txt]": 5.987, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file_non_ascii_content_disposition[normal_file.txt-normal_file.txt]": 0.004, + "src/backend/tests/unit/api/v2/test_files.py::test_download_file_not_found": 10.75, + "src/backend/tests/unit/api/v2/test_files.py::test_edit_file": 11.964, + "src/backend/tests/unit/api/v2/test_files.py::test_list_files": 12.717, + "src/backend/tests/unit/api/v2/test_files.py::test_mcp_servers_file_replacement": 9.889, + "src/backend/tests/unit/api/v2/test_files.py::test_should_not_persist_in_my_files_when_upload_is_ephemeral": 10.74, + "src/backend/tests/unit/api/v2/test_files.py::test_should_return_path_with_forward_slashes_when_uploading_file": 11.927, + "src/backend/tests/unit/api/v2/test_files.py::test_unique_filename_counter_handles_gaps": 0.326, + "src/backend/tests/unit/api/v2/test_files.py::test_unique_filename_path_storage": 11.691, + "src/backend/tests/unit/api/v2/test_files.py::test_upload_file": 12.613, + "src/backend/tests/unit/api/v2/test_files.py::test_upload_files_with_different_extensions_same_name": 8.508, + "src/backend/tests/unit/api/v2/test_files.py::test_upload_files_with_same_name_creates_unique_names": 10.618, + "src/backend/tests/unit/api/v2/test_files.py::test_upload_files_without_extension_creates_unique_names": 10.671, + "src/backend/tests/unit/api/v2/test_files.py::test_upload_list_delete_and_validate_files": 13.032, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_concurrent_update_server_should_not_lose_servers": 0.04, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_enforce_immutable_server_name_passthrough_without_name": 0.042, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_enforce_immutable_server_name_rejects_mismatch": 0.041, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_enforce_immutable_server_name_strips_matching_name": 0.044, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_mcp_servers_upload_replace": 0.036, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_patch_server_rejects_name_change": 0.039, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_patch_server_strips_matching_name_before_persist": 0.043, + "src/backend/tests/unit/api/v2/test_mcp_servers_file.py::test_post_server_rejects_name_mismatch": 0.071, + "src/backend/tests/unit/api/v2/test_registration.py::TestAPIEndpoints::test_get_registration_error": 3.92, + "src/backend/tests/unit/api/v2/test_registration.py::TestAPIEndpoints::test_get_registration_exists": 0.082, + "src/backend/tests/unit/api/v2/test_registration.py::TestAPIEndpoints::test_get_registration_not_exists": 0.032, + "src/backend/tests/unit/api/v2/test_registration.py::TestAPIEndpoints::test_register_user_invalid_email": 5.799, + "src/backend/tests/unit/api/v2/test_registration.py::TestAPIEndpoints::test_register_user_save_fails": 9.963, + "src/backend/tests/unit/api/v2/test_registration.py::TestAPIEndpoints::test_register_user_success": 0.017, + "src/backend/tests/unit/api/v2/test_registration.py::TestDataModels::test_register_request_invalid_email": 0.043, + "src/backend/tests/unit/api/v2/test_registration.py::TestDataModels::test_register_request_valid_email": 0.01, + "src/backend/tests/unit/api/v2/test_registration.py::TestDataModels::test_register_response": 0.061, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_ensure_registration_file_creates_directory": 0.041, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_ensure_registration_file_handles_error": 0.041, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_load_registration_corrupted_file": 0.038, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_load_registration_empty_file": 0.046, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_load_registration_file_not_exists": 0.041, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_load_registration_valid_file": 0.05, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_save_registration_handles_error": 0.081, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_save_registration_new": 0.081, + "src/backend/tests/unit/api/v2/test_registration.py::TestHelperFunctions::test_save_registration_replace_existing": 0.049, + "src/backend/tests/unit/api/v2/test_registration.py::TestIntegration::test_api_integration": 9.358, + "src/backend/tests/unit/api/v2/test_registration.py::TestIntegration::test_full_registration_flow": 3.794, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowBackgroundQueueing::test_background_execution_flow": 10.819, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowBackgroundQueueing::test_background_execution_invalid_flow": 0.257, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowBackgroundQueueing::test_background_execution_queue_exception": 10.222, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowBackgroundQueueing::test_background_execution_uses_body_globals_with_unicode": 10.374, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowBackgroundQueueing::test_sync_execution_error_handling": 18.107, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_all_endpoints_require_api_key_authentication": 16.009, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_execute_workflow_allowed_when_dev_api_enabled_flow_exists": 10.006, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_execute_workflow_allowed_when_dev_api_enabled_flow_not_found": 9.754, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_execute_workflow_blocked_when_dev_api_disabled": 2.174, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_get_workflow_allowed_when_dev_api_enabled_job_exists": 12.198, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_get_workflow_allowed_when_dev_api_enabled_job_not_found": 10.869, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_get_workflow_blocked_when_dev_api_disabled": 10.772, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_stop_workflow_allowed_when_dev_api_enabled_job_exists": 12.411, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_stop_workflow_allowed_when_dev_api_enabled_job_not_found": 1.72, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowDeveloperAPIProtection::test_stop_workflow_blocked_when_dev_api_disabled": 11.565, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_background_mode_returns_501": 10.917, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_database_error_returns_503": 13.674, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_error_response_structure": 10.569, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_execution_timeout_with_real_delay": 11.807, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_flow_not_found_returns_404_with_error_code": 10.751, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_flow_with_no_data_returns_500": 11.871, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_graph_build_failure_returns_500": 10.108, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_streaming_mode_returns_501": 12.476, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowErrorHandling::test_workflow_validation_error_propagation": 10.788, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_background_job_stores_user_id_and_blocks_cross_user_access": 4.498, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_get_workflow_status_allowed_for_legacy_job_with_no_user_id": 11.789, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_get_workflow_status_allowed_for_own_job": 9.303, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_get_workflow_status_forbidden_for_other_user_job": 9.445, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_get_workflow_status_returns_404_for_non_workflow_job_type": 0.13, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_stop_workflow_allowed_for_legacy_job_with_no_user_id": 11.826, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_stop_workflow_allowed_for_own_job": 11.795, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_stop_workflow_forbidden_for_other_user_job": 12.738, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowIDORProtection::test_stop_workflow_returns_404_for_non_workflow_job_type": 2.411, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStatus::test_get_status_completed_reconstruction": 12.133, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStatus::test_get_status_failed": 10.899, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStatus::test_get_status_not_found": 12.726, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStatus::test_get_status_queued": 21.754, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStatus::test_get_status_timed_out": 10.473, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStop::test_stop_workflow_already_cancelled": 10.235, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStop::test_stop_workflow_not_found": 0.007, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowStop::test_stop_workflow_success": 1.201, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_component_error_returns_200_with_error_in_body": 10.312, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_honors_legacy_global_variable_headers_with_deprecation": 10.938, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_rejects_oversized_globals_value": 10.737, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_response_structure_validation": 11.902, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_uses_body_globals_with_unicode": 12.213, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_with_chat_input_output": 3.774, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_with_empty_flow_returns_200": 13.643, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_with_file_save_output": 11.988, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_with_llm_output": 10.143, + "src/backend/tests/unit/api/v2/test_workflow.py::TestWorkflowSyncExecution::test_sync_execution_with_multiple_terminal_nodes": 10.182, + "src/backend/tests/unit/api/v2/test_workflow_reconstruction.py::TestWorkflowReconstruction::test_reconstruct_blocks_custom_components_when_disabled": 0.035, + "src/backend/tests/unit/api/v2/test_workflow_reconstruction.py::TestWorkflowReconstruction::test_reconstruct_fails_when_flow_has_no_data": 0.039, + "src/backend/tests/unit/api/v2/test_workflow_reconstruction.py::TestWorkflowReconstruction::test_reconstruct_fails_when_no_vertex_builds": 0.039, + "src/backend/tests/unit/api/v2/test_workflow_reconstruction.py::TestWorkflowReconstruction::test_reconstruct_filters_to_terminal_nodes_only": 0.03, + "src/backend/tests/unit/api/v2/test_workflow_reconstruction.py::TestWorkflowReconstruction::test_reconstruct_success_with_terminal_nodes": 0.029, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_basic": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_case_insensitive": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_document_length_normalization": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_duplicate_terms_in_query": 0.044, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_empty_documents": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_empty_query_terms": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_idf_calculation": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_mathematical_properties": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_no_documents": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_parameters": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_single_document": 0.042, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_special_characters": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_term_frequency_saturation": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_two_documents_positive_scores": 0.042, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_whitespace_handling": 0.043, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_bm25_zero_parameters": 0.043, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_basic": 0.04, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_case_insensitive": 0.04, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_duplicate_terms_in_query": 0.042, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_empty_documents": 0.039, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_empty_query_terms": 0.04, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_idf_calculation": 0.042, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_mathematical_properties": 0.043, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_no_documents": 0.04, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_single_document": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_special_characters": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_term_frequency_calculation": 0.042, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_two_documents_positive_scores": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_compute_tfidf_whitespace_handling": 0.041, + "src/backend/tests/unit/base/data/test_kb_utils.py::TestKBUtils::test_tfidf_vs_bm25_comparison": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCloudProviderMapping::test_map_cloud_providers_dev_content": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCloudProviderMapping::test_map_cloud_providers_prod_content": 0.038, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCloudProviderMapping::test_map_cloud_providers_structure": 0.039, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCollectionCreation::test_create_collection_api_no_name": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCollectionCreation::test_create_collection_api_with_dimension": 0.043, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCollectionCreation::test_create_collection_api_with_vectorize": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCollectionDataRetrieval::test_collection_data_error_handling": 0.039, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCollectionDataRetrieval::test_collection_data_success": 0.043, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestCollectionDataRetrieval::test_collection_data_with_provided_database": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestDatabaseCreation::test_create_database_api_success": 0.042, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestDatabaseIdExtraction::test_get_database_id_instance_method": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestDatabaseIdExtraction::test_get_database_id_static_case_insensitive": 0.043, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestDatabaseIdExtraction::test_get_database_id_static_no_uuid": 0.043, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestDatabaseIdExtraction::test_get_database_id_static_valid_uuid": 0.042, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestGetDatabaseObject::test_get_database_object_error": 0.038, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestGetDatabaseObject::test_get_database_object_success": 0.038, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestGetDatabaseObject::test_get_database_object_with_custom_endpoint": 0.038, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestKeyspaceHandling::test_get_keyspace_default": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestKeyspaceHandling::test_get_keyspace_with_empty_string": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestKeyspaceHandling::test_get_keyspace_with_value": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestUpdateBuildConfig::test_update_build_config_first_run": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestUpdateBuildConfig::test_update_build_config_no_token": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_base_component.py::TestUpdateBuildConfig::test_update_build_config_search_method_change_to_hybrid": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCoerceDocuments::test_empty_value": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCoerceDocuments::test_list_passes_through": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCoerceDocuments::test_rejects_non_dict_entries": 0.046, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCoerceDocuments::test_rejects_wrong_type": 0.039, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCoerceDocuments::test_single_dict_wrapped": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCountOperations::test_count_documents": 0.043, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCountOperations::test_estimated_count": 0.005, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCreateCollectionAstrapyOnly::test_bring_your_own_dimension": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCreateCollectionAstrapyOnly::test_missing_name_rejected": 0.042, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCreateCollectionAstrapyOnly::test_no_langchain_astradb_import": 0.1, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCreateCollectionAstrapyOnly::test_plain_collection_no_vector": 0.086, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCreateCollectionAstrapyOnly::test_unknown_provider_rejected": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestCreateCollectionAstrapyOnly::test_vectorize_provider": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestDataFrameOutput::test_as_dataframe_empty": 0.036, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestDataFrameOutput::test_as_dataframe_from_find": 0.037, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestDeleteOperations::test_delete_many": 0.202, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestDeleteOperations::test_delete_one": 0.045, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestDeleteOperations::test_delete_requires_filter": 0.416, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestErrorPropagation::test_astrapy_errors_wrapped": 0.065, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestErrorPropagation::test_missing_collection_name_raises": 0.088, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestErrorPropagation::test_unknown_operation_raises": 0.042, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestFindOneOperation::test_find_one_no_match_returns_empty": 0.239, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestFindOneOperation::test_find_one_with_match": 0.208, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestFindOperation::test_find_omits_empty_options": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestFindOperation::test_find_raw_result": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestFindOperation::test_find_respects_skip_projection_sort": 0.043, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestFindOperation::test_find_returns_list_of_data": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestInsertManyOperation::test_insert_many_empty_rejected": 0.009, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestInsertManyOperation::test_insert_many_success": 0.843, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestInsertOneOperation::test_insert_one_rejects_non_dict": 0.191, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestInsertOneOperation::test_insert_one_success": 0.15, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestOperationVisibility::test_count_shows_upper_bound": 0.046, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestOperationVisibility::test_estimated_count_hides_everything": 0.048, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestOperationVisibility::test_find_shows_query_fields": 0.042, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestOperationVisibility::test_insert_many_shows_documents_and_ordered": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestOperationVisibility::test_insert_one_shows_document": 0.046, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestOperationVisibility::test_update_ops_show_filter_update_upsert": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStaticConfiguration::test_all_operations_have_fields": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStaticConfiguration::test_all_operations_have_icons": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStaticConfiguration::test_component_metadata": 0.042, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStaticConfiguration::test_operation_field_names_exist_on_inputs": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStaticConfiguration::test_outputs_defined": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStaticConfiguration::test_tool_mode_inputs": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStringify::test_none_returns_none": 0.046, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStringify::test_objects_stringified": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestStringify::test_primitives_pass_through": 0.041, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestUpdateBuildConfig::test_operation_change_toggles_fields": 0.038, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestUpdateOperations::test_update_many_success": 0.04, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestUpdateOperations::test_update_one_requires_filter": 0.01, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestUpdateOperations::test_update_one_requires_update_doc": 0.009, + "src/backend/tests/unit/base/datastax/test_astradb_data_api_component.py::TestUpdateOperations::test_update_one_success": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFileUploadSource::test_describe_redacts_bytes": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFileUploadSource::test_round_trip": 0.042, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFileUploadSource::test_validate_rejects_malformed_entries": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFileUploadSource::test_validate_requires_files": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_empty_allow_list_refuses": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_inside_allow_list_passes": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_outside_allow_list_refused": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_rejects_file_path": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_rejects_missing_path": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_rejects_nonexistent_path": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceAllowList::test_symlink_escape_blocked": 0.039, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceListAndFetch::test_extension_filter_applied": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceListAndFetch::test_fetch_content_refuses_escape": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceListAndFetch::test_oversized_file_skipped": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestFolderSourceListAndFetch::test_recursive_walk": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestIngestionSummary::test_record_item_updates_counters": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestPerFileMetadata::test_file_upload_describe_counts_metadata": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestPerFileMetadata::test_file_upload_per_file_metadata_propagates": 0.042, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestPerFileMetadata::test_folder_metadata_absent_for_unmatched_files": 0.043, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestPerFileMetadata::test_folder_per_file_metadata_relative_path_wins": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestRegistry::test_builtins_registered": 0.005, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestRegistry::test_create_source_accepts_string": 0.007, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestRegistry::test_register_idempotent_but_collision_raises": 0.044, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestRegistry::test_unknown_source_type_raises": 0.006, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_ingestion_sources.py::TestRegistry::test_unregistered_known_type_raises": 0.005, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_registry_plugin_discovery.py::test_builtin_sources_are_not_shadowed_by_entry_points": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_registry_plugin_discovery.py::test_entry_point_registers_plugin_source": 0.039, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_registry_plugin_discovery.py::test_lfx_toml_registers_plugin_source": 0.074, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_registry_plugin_discovery.py::test_unknown_plugin_key_raises_unknown_not_unregistered": 0.086, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourceDirectInstantiation::test_validate_config_raises[google_drive-GoogleDriveSource]": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourceDirectInstantiation::test_validate_config_raises[onedrive-OneDriveSource]": 3.038, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourceDirectInstantiation::test_validate_config_raises[s3-S3Source]": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourceDirectInstantiation::test_validate_config_raises[sharepoint-SharePointSource]": 0.042, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_create_source_raises[google_drive-cls]": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_create_source_raises[onedrive-cls]": 0.042, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_create_source_raises[s3-cls]": 0.005, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_create_source_raises[sharepoint-cls]": 0.043, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_not_in_registry[google_drive-cls]": 0.04, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_not_in_registry[onedrive-cls]": 0.006, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_not_in_registry[s3-cls]": 0.041, + "src/backend/tests/unit/base/knowledge_bases/ingestion_sources/test_s3_source.py::TestStubbedSourcesNotRegistered::test_not_in_registry[sharepoint-cls]": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_chroma_registered_by_default": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_create_backend_accepts_string_identifier": 3.479, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_create_backend_returns_chroma_instance": 1.058, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_opensearch_registered_by_default": 0.04, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_register_backend_is_idempotent": 5.486, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_register_backend_rejects_conflicting_registration": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_registered_backends_returns_stable_ordering": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_resolve_backend_type_rejects_garbage_strings": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_backends_registry.py::TestBackendRegistry::test_stubbed_backends_are_not_registered": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_add_and_count": 1.01, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_add_documents_is_noop_on_empty_list": 0.406, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_delete_by_removes_matching_documents": 0.009, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_iter_documents_returns_empty_for_empty_collection": 4.736, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_iter_documents_yields_batches": 4.318, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_similarity_search_returns_tuples": 0.007, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendDocumentLifecycle::test_similarity_search_with_scores": 2.484, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendLifecycle::test_backend_type_constant": 0.195, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendLifecycle::test_teardown_is_idempotent": 2.853, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendLifecycle::test_vector_store_is_lazy": 2.896, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendStorage::test_storage_size_is_zero_for_missing_path": 0.04, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaBackendStorage::test_storage_size_reports_nonzero_after_ingest": 2.445, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_build_vector_store_uses_cloud_client": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_delete_collection_calls_client_delete_collection": 10.342, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_delete_collection_propagates_cloud_errors": 9.391, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_get_cloud_client_omits_host_port_when_not_configured": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_get_cloud_client_passes_optional_host_port": 8.677, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_is_cloud_false_by_default": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_is_cloud_false_when_mode_is_local": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_is_cloud_true_when_mode_is_cloud": 0.043, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_resolve_secrets_api_key_is_required": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_resolve_secrets_defaults_to_env_var_names": 0.039, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_resolve_secrets_noop_in_local_mode": 0.04, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_resolve_secrets_tenant_database_are_optional": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_storage_size_zero_in_cloud_mode": 5.446, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_teardown_cloud_does_not_touch_shared_registry": 0.006, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_test_connection_cloud_credential_error_is_caught": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_test_connection_cloud_failure": 7.705, + "src/backend/tests/unit/base/knowledge_bases/test_chroma_backend.py::TestChromaCloudMode::test_test_connection_cloud_success": 2.056, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorCatalog::test_returns_only_registered_connectors": 8.776, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorIngest::test_rejects_unbounded_chunk_parameters": 10.509, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorIngest::test_stubbed_source_type_returns_400[google_drive]": 12.682, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorIngest::test_stubbed_source_type_returns_400[onedrive]": 9.654, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorIngest::test_stubbed_source_type_returns_400[s3]": 10.829, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorIngest::test_stubbed_source_type_returns_400[sharepoint]": 12.301, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestConnectorIngest::test_unknown_source_type_returns_400": 10.939, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestFolderIngest::test_connector_ingest_blocked_for_memory_base_kb": 12.273, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestFolderIngest::test_dispatches_folder_source_with_settings_allow_list": 0.127, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestFolderIngest::test_folder_ingest_blocked_for_memory_base_kb": 10.928, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestFolderIngest::test_folder_ingest_rejects_unbounded_chunk_parameters": 12.391, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestFolderIngest::test_folder_ingest_with_real_settings_returns_400_not_500": 22.141, + "src/backend/tests/unit/base/knowledge_bases/test_connector_endpoints.py::TestFolderIngest::test_rejects_folder_outside_settings_allow_list_before_job": 11.383, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestChunksFilters::test_multiple_filters_combine_with_and": 13.307, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestChunksFilters::test_single_metadata_filter_narrows_results[?file_name=a.pdf-expected_source_types1]": 12.199, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestChunksFilters::test_single_metadata_filter_narrows_results[?job_id=deadbeef-expected_source_types2]": 10.496, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestChunksFilters::test_single_metadata_filter_narrows_results[?source_type=folder-expected_source_types0]": 11.186, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestGetIngestionRun::test_other_users_run_returns_404": 11.653, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestGetIngestionRun::test_returns_full_detail_with_items": 12.682, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestGetIngestionRun::test_run_from_different_kb_returns_404": 13.224, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestListIngestionRuns::test_excludes_other_users_runs": 11.514, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestListIngestionRuns::test_exposes_source_name_from_source_config": 10.18, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestListIngestionRuns::test_pagination": 0.085, + "src/backend/tests/unit/base/knowledge_bases/test_ingestion_run_endpoints.py::TestListIngestionRuns::test_returns_runs_for_kb_newest_first": 10.946, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillAllUsersFromDisk::test_backfill_all_users_scans_each_user_root": 8.985, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillFromDisk::test_backfill_inserts_missing_rows": 10.768, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillFromDisk::test_backfill_is_idempotent": 10.496, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillFromDisk::test_backfill_missing_root_returns_zero": 11.416, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillFromDisk::test_backfill_skips_directories_with_deletion_sentinel": 2.78, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillFromDisk::test_backfill_skips_missing_metadata": 10.176, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestBackfillFromDisk::test_backfill_uses_recounted_disk_stats": 5.341, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestCreateAndRead::test_create_and_get_by_user_and_name": 10.303, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestCreateAndRead::test_get_by_user_and_name_returns_none_when_missing": 10.515, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestCreateAndRead::test_list_by_user_orders_newest_first": 10.162, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestDelete::test_delete_by_user_and_name_removes_row": 0.006, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestDelete::test_delete_missing_is_noop": 13.64, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestNormalization::test_record_to_metadata_dict_maps_zero_chunk_ready_kb_to_empty_status": 1.324, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestNormalization::test_record_to_metadata_dict_matches_json_shape": 0.183, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestReadMetadata::test_read_metadata_falls_back_to_disk": 8.385, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestReadMetadata::test_read_metadata_prefers_db": 5.037, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestReadMetadata::test_read_metadata_returns_empty_when_nowhere": 17.57, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestUniqueConstraint::test_duplicate_user_name_rejected": 7.602, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestUpdates::test_update_stats_can_clear_separator": 0.005, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestUpdates::test_update_stats_missing_row_is_silent": 9.483, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestUpdates::test_update_stats_refreshes_cached_counters": 11.253, + "src/backend/tests/unit/base/knowledge_bases/test_knowledge_base_service.py::TestUpdates::test_update_status": 13.669, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchBackendVectorFieldDefault::test_build_vector_store_honours_backend_config_override": 0.033, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchBackendVectorFieldDefault::test_build_vector_store_uses_vector_field_by_default": 0.032, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchBackendVectorFieldDefault::test_default_vector_field_is_vector_field": 0.049, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchIterDocumentsEmbeddings::test_iter_documents_excludes_both_fields_for_legacy_config": 1.924, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchIterDocumentsEmbeddings::test_iter_documents_excludes_real_vector_field_when_not_requested": 0.039, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchIterDocumentsEmbeddings::test_iter_documents_falls_back_when_config_names_unwritten_field": 0.038, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchIterDocumentsEmbeddings::test_iter_documents_prefers_configured_field_when_present": 0.033, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchIterDocumentsEmbeddings::test_iter_documents_reads_embeddings_from_vector_field": 0.03, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchSimilaritySearchFilterHandling::test_filter_empty_dict_is_dropped_from_call": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchSimilaritySearchFilterHandling::test_filter_none_is_dropped_from_call": 0.042, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchSimilaritySearchFilterHandling::test_filter_truthy_is_forwarded": 1.562, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::TestOpenSearchSimilaritySearchFilterHandling::test_with_scores_routes_to_score_method_and_drops_none_filter": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::test_vector_field_resolution_table[-vector_field]": 0.035, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::test_vector_field_resolution_table[None-vector_field]": 0.043, + "src/backend/tests/unit/base/knowledge_bases/test_opensearch_backend.py::test_vector_field_resolution_table[custom_vec-custom_vec]": 0.045, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestChromaTestConnection::test_returns_failure_for_unwritable_path": 0.007, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestChromaTestConnection::test_returns_ok_for_writable_path": 0.629, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestDefaultTestConnection::test_returns_failure_when_build_raises": 0.044, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestDefaultTestConnection::test_returns_ok_when_build_succeeds": 0.039, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestOpenSearchTestConnection::test_returns_auth_message_on_authentication_exception": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestOpenSearchTestConnection::test_returns_authorization_message_on_authorization_exception": 0.039, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestOpenSearchTestConnection::test_returns_connection_message_on_connection_error": 0.038, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestOpenSearchTestConnection::test_returns_failure_when_url_secret_missing": 0.04, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestOpenSearchTestConnection::test_returns_ok_when_cluster_info_succeeds": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_test_connection.py::TestOpenSearchTestConnection::test_returns_ssl_message_on_ssl_error": 0.038, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendDirectInstantiation::test_build_vector_store_raises[astra-AstraBackend]": 0.048, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendDirectInstantiation::test_build_vector_store_raises[mongodb-MongoDBBackend]": 0.039, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendDirectInstantiation::test_build_vector_store_raises[postgres-PostgresBackend]": 0.08, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendsNotRegistered::test_create_backend_raises[astra-cls]": 0.047, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendsNotRegistered::test_create_backend_raises[mongodb-cls]": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendsNotRegistered::test_create_backend_raises[postgres-cls]": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendsNotRegistered::test_not_in_registry[astra-cls]": 0.041, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendsNotRegistered::test_not_in_registry[mongodb-cls]": 0.044, + "src/backend/tests/unit/base/knowledge_bases/test_vector_store_backends.py::TestStubbedBackendsNotRegistered::test_not_in_registry[postgres-cls]": 0.076, + "src/backend/tests/unit/base/load/test_load.py::test_run_flow_from_json_params": 0.042, + "src/backend/tests/unit/base/load/test_load.py::test_run_flow_with_fake_env": 0.017, + "src/backend/tests/unit/base/load/test_load.py::test_run_flow_with_fake_env_tweaks": 0.009, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestMCPStreamableHttpClientSSLConfiguration::test_client_initialization_defaults": 0.05, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestMCPStreamableHttpClientSSLConfiguration::test_connection_params_store_verify_ssl_false": 0.03, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestMCPStreamableHttpClientSSLConfiguration::test_connection_params_store_verify_ssl_true": 0.031, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestMCPStreamableHttpClientSSLConfiguration::test_url_validation_function": 0.048, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientBehavior::test_client_with_all_options": 0.055, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientBehavior::test_client_with_auth_and_ssl": 0.052, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientBehavior::test_client_with_timeout_and_ssl": 0.051, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_create_client_with_auth": 0.035, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_create_client_with_custom_headers": 0.045, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_create_client_with_custom_timeout": 0.05, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_create_client_with_default_ssl_verification": 0.034, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_create_client_with_ssl_verification_disabled": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_create_client_with_ssl_verification_enabled": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactory::test_verify_ssl_parameter_types": 0.035, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactoryIntegration::test_client_can_be_used_in_context_manager": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactoryIntegration::test_client_with_ssl_disabled_can_be_created": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLClientFactoryIntegration::test_multiple_clients_with_different_ssl_settings": 0.035, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLConfigurationConsistency::test_mixed_ssl_configuration": 0.022, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLConfigurationConsistency::test_ssl_false_configuration_consistency": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLConfigurationConsistency::test_ssl_true_configuration_consistency": 0.023, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLErrorScenarios::test_invalid_url_detected_by_validator": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLErrorScenarios::test_valid_urls_pass_validation": 0.031, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLParameterPropagation::test_default_verify_ssl_value": 0.047, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLParameterPropagation::test_verify_ssl_false_in_connection_params": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLParameterPropagation::test_verify_ssl_true_in_connection_params": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLUsageScenarios::test_client_configuration_for_different_environments": 0.047, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLUsageScenarios::test_development_scenario_with_self_signed_certificate": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLUsageScenarios::test_localhost_development_scenario": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_ssl.py::TestSSLUsageScenarios::test_production_scenario_with_valid_certificate": 0.035, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutBehavior::test_mcp_sse_client_receives_timeout": 0.547, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutBehavior::test_multiple_clients_independent_timeouts": 0.544, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutBehavior::test_multiple_tool_calls_independent_timeout_overrides": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutBehavior::test_none_timeout_preserves_existing_client_timeout": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutBehavior::test_timeout_error_is_caught_and_retried": 0.006, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutBehavior::test_zero_timeout_uses_global_default": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_stdio_client_custom_timeout": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_stdio_client_default_timeout": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_stdio_run_tool_timeout_override": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_stdio_run_tool_uses_client_timeout": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_streamable_http_client_custom_timeout": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_streamable_http_client_default_timeout": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_streamable_http_run_tool_timeout_override": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_streamable_http_run_tool_uses_client_timeout": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_update_tools_passes_timeout_to_http_client": 1.044, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutConfiguration::test_update_tools_passes_timeout_to_stdio_client": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutSettingsValidation::test_global_setting_accepts_positive_float": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutSettingsValidation::test_global_setting_validation_rejects_negative": 0.525, + "src/backend/tests/unit/base/mcp/test_mcp_timeout_configuration.py::TestMCPTimeoutSettingsValidation::test_global_setting_validation_rejects_zero": 0.546, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_convert_image_block_to_image_url_format": 0.127, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_default_mime_type_to_image_png_when_missing": 1.603, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_handle_mixed_text_and_image_blocks": 0.048, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_handle_multiple_image_blocks": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_handle_unknown_block_type_without_model_dump": 0.048, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_join_multiple_text_blocks_with_newline": 0.046, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_preserve_all_blocks_in_mixed_image_and_resource_result": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_return_empty_string_for_empty_content": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_return_empty_string_for_missing_content_attr": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_return_empty_string_for_none_result": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_return_plain_string_for_single_text_block": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestConvertMcpResult::test_should_serialise_resource_only_result_as_text_block": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_camel_to_snake_basic": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_camel_to_snake_edge_cases": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_convert_field_names_camel_to_snake": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_convert_field_names_empty_input": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_convert_field_names_exact_match": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_convert_field_names_mixed_case": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_convert_field_names_no_match": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_field_conversion_in_tool_validation": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_field_conversion_preserves_values": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_json_schema_alias_functionality": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestFieldNameConversion::test_tool_empty_arguments_error_handling": 0.036, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_process_headers_with_request_variables_dict": 0.044, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_process_headers_with_request_variables_list": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_process_headers_without_request_variables": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_basic": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_case_sensitive_matching": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_empty_headers": 0.045, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_no_variables": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_non_string_values": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_partial_match": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestGlobalVariableResolution::test_resolve_global_variables_special_characters": 0.045, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestHeaderValidation::test_validate_headers_empty_input": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestHeaderValidation::test_validate_headers_injection_attempts": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestHeaderValidation::test_validate_headers_invalid_names": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestHeaderValidation::test_validate_headers_non_string_values": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestHeaderValidation::test_validate_headers_sanitize_values": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestHeaderValidation::test_validate_headers_valid_input": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_cleanup_does_not_wipe_cross_server_handoff": 0.498, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_cleanup_idle_vs_get_session_are_serialized": 0.509, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_concurrent_cleanup_same_session_is_idempotent": 0.004, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_concurrent_cleanup_session_and_get_session_safe": 0.004, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_concurrent_get_session_same_server_reuses_one_session": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_server_lock_and_counter_reclaimed_when_unused": 0.006, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_server_switch_detection": 0.509, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_session_caching": 0.515, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_session_cleanup": 0.511, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSessionManager::test_session_ids_are_monotonic_not_len_based": 0.511, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_client_initialization": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_connect_to_server_with_headers": 0.048, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_headers_passed_to_session_manager": 0.544, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_run_tool_with_retry_on_connection_error": 0.009, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_validate_url_invalid_format": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_validate_url_valid": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPSseClientUnit::test_validate_url_with_404_response": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStdioClientWithEverythingServer::test_connect_to_everything_server": 0.854, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStdioClientWithEverythingServer::test_list_all_tools": 0.046, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStdioClientWithEverythingServer::test_run_echo_tool": 0.044, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStdioClientWithEverythingServer::test_session_reuse": 0.721, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStreamableHttpClientWithDeepWikiServer::test_ask_question_tool": 0.009, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStreamableHttpClientWithDeepWikiServer::test_connect_to_deepwiki_server": 0.005, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStreamableHttpClientWithDeepWikiServer::test_run_wiki_structure_tool": 0.008, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStreamableHttpClientWithDeepWikiServer::test_url_validation": 0.045, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_arun_integration_with_validation_error": 0.036, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_arun_passes_config_and_kwargs": 0.037, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_arun_with_dict_input": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_arun_with_none_input": 0.038, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_arun_with_string_input_json": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_arun_with_string_input_non_json": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_camel_to_snake": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_empty_input": 0.045, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_exact_match": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_flattened_input_produces_nested": 0.046, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_mixed_fields": 0.034, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_preserves_value_types": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_convert_parameters_unknown_fields": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_run_integration_with_validation_error": 0.037, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_run_passes_config_and_kwargs": 0.037, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_run_with_dict_input": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_run_with_none_input": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_run_with_string_input_json": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredTool::test_run_with_string_input_non_json": 0.038, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredToolToolCallId::test_image_content_converted_in_tool_message": 0.524, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredToolToolCallId::test_no_tool_call_id_returns_raw_result": 0.035, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredToolToolCallId::test_tool_call_id_is_preserved_for_callbacks": 0.54, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredToolToolCallId::test_tool_message_artifact_holds_raw_call_tool_result": 0.036, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPStructuredToolToolCallId::test_with_tool_call_id_returns_tool_message": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_additional_properties_typed_schema_still_preserves_extras": 0.038, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_array_of_objects_extras_are_preserved": 0.038, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_create_input_schema_empty_properties_no_params": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_create_input_schema_from_json_schema": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_create_input_schema_generic_object_maps_to_dict": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_create_input_schema_required_filters_non_strings": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_create_input_schema_type_array_integer_null": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_create_input_schema_type_array_string_null": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_deeply_nested_dict_round_trip_preserves_all_levels": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_get_flow_snake_case_mocked": 0.038, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_get_unique_name": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_is_valid_key_value_item": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_nested_dict_preservation_issue_9881": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_nested_dict_preservation_with_declared_properties_issue_10975": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_nested_object_with_none_or_empty_does_not_crash": 0.924, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_object_with_additional_properties_false_still_drops_extras": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_sanitize_mcp_name": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_top_level_extras_preserved_when_root_does_not_forbid": 0.037, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_top_level_strict_mode_when_root_forbids_additional_properties": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_validate_connection_params": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestMCPUtilityFunctions::test_validate_node_installation": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_already_correct_types_unchanged": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_bool_expected_int_raises": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_bool_expected_invalid_str_raises": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_bool_rejected_when_int_expected": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_conversion_failure_propagates_error": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_dict_expected_json_parses_to_list_raises": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_dict_expected_non_str_value_raises": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_extra_keys_preserved_for_pydantic_validation": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_float_expected_invalid_str_raises": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_float_expected_list_or_dict_raises": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_float_to_int_when_int_expected": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_int_expected_list_or_dict_raises": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_int_expected_non_integer_float_raises": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_invalid_json_for_dict_raises_clear_error": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_invalid_json_for_list_raises_clear_error": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_langflow_data_to_dict_when_dict_expected": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_list_expected_json_parses_to_dict_raises": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_list_expected_non_str_value_raises": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_nested_model_already_dict_unchanged": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_optional_dict_none_unchanged": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_optional_field_none_unchanged": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_optional_list_none_unchanged": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_optional_str_none_unchanged": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_required_dict_none_maps_to_empty": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_required_list_none_maps_to_empty": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_required_str_none_maps_to_empty": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_bool_false_variants": 0.044, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_bool_when_bool_expected": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_dict_when_dict_expected": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_dict_when_nested_model_expected": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_dict_when_optional_dict_expected": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_float_when_float_expected": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_int_when_int_expected": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_str_to_list_when_optional_list_expected": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestNormalizeArgumentsForMcp::test_try_convert_value_none_raises": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_basic": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_both_leading_and_trailing": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_edge_cases": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_empty_string": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_leading_underscores": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_multiple_consecutive_underscores": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_only_underscores": 0.053, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_single_word": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_trailing_underscores": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestSnakeToCamelConversion::test_snake_to_camel_with_api_field_names": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHTTPHeaderIntegration::test_headers_processing": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHTTPHeaderIntegration::test_streamable_http_client_header_storage": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHttpTransportPolicy::test_classify_transient_includes_connection_and_taskgroup_hints": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHttpTransportPolicy::test_sse_fallback_after_404": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHttpTransportPolicy::test_streamable_404_triggers_sse": 0.005, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHttpTransportPolicy::test_streamable_success_sse_not_invoked": 0.511, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHttpTransportPolicy::test_transient_streamable_failure_no_sse_fallback": 0.006, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStreamableHttpTransportPolicy::test_validate_connectivity_mcp_session_terminated_returns_false": 0.005, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_handle_deeply_nested_none": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_handle_empty_structures": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_handle_list_of_primitives_with_none": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_preserve_falsy_non_none_values": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_remove_none_from_flat_dict": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_remove_none_from_nested_objects_in_arrays": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestStripNoneRecursive::test_should_return_primitives_unchanged": 0.03, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_create_tool_coroutine_with_camel_case_fields": 0.043, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_create_tool_func_with_camel_case_fields": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_tool_coroutine_field_conversion_end_to_end": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_tool_coroutine_mixed_args_and_conversion": 0.038, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_tool_coroutine_positional_args_no_conversion": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_tool_coroutine_validation_error_with_conversion": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestToolExecutionWithFieldConversion::test_tool_func_field_conversion_sync": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsPerToolResilience::test_one_bad_tool_does_not_drop_the_other_tools_issue_11229": 0.032, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsPerToolResilience::test_resilience_under_many_mixed_tools": 3.277, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_does_not_mutate_original_config": 0.05, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_headers_appended_when_all_args_are_flags": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_headers_appended_when_last_token_is_flag_value": 0.037, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_headers_injected_with_existing_headers_flag": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_headers_injected_without_existing_headers_flag": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_headers_inserted_before_last_positional_with_multiple_positionals": 0.041, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_headers_inserted_before_positional_with_flag_value_pairs": 0.04, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_multiple_headers_each_get_own_flag": 4.241, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_multiword_command_with_args": 0.039, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_multiword_command_with_empty_args": 0.042, + "src/backend/tests/unit/base/mcp/test_mcp_util.py::TestUpdateToolsStdioHeaders::test_stdio_no_headers_leaves_args_unchanged": 0.041, "src/backend/tests/unit/base/models/test_model_constants.py::test_provider_names": 0.024663168034749106, + "src/backend/tests/unit/base/models/test_model_utils.py::TestFetchLiveWatsonxModelsRespectsStaticToolCalling::test_live_fetch_defaults_unknown_models_to_tool_calling_true": 0.041, + "src/backend/tests/unit/base/models/test_model_utils.py::TestFetchLiveWatsonxModelsRespectsStaticToolCalling::test_live_fetch_preserves_static_tool_calling_false": 0.043, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_resolve_deployment_name_for_real_azure_chat_openai": 0.029, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_resolve_model_id_for_real_chat_watsonx": 0.041, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_resolve_model_name_for_real_chat_openai": 0.051, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_return_custom_display_name_when_caller_overrides_default": 0.04, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_return_deployment_name_when_model_name_is_none_azure_shape": 0.04, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_return_display_name_when_all_known_attributes_are_none": 0.041, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_return_display_name_when_object_has_no_known_attributes": 0.042, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_return_first_set_attribute_in_priority_order": 0.042, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_return_model_id_when_model_is_none_watsonx_shape": 0.041, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_skip_empty_string_attribute_and_return_next_truthy_one": 0.041, + "src/backend/tests/unit/base/models/test_model_utils.py::TestGetModelName::test_should_skip_other_falsy_values_and_return_next_truthy_one": 0.041, + "src/backend/tests/unit/base/models/test_provider_variable_value.py::TestGetProviderVariableValue::test_returns_none_for_none_user_id": 0.042, + "src/backend/tests/unit/base/models/test_provider_variable_value.py::TestGetProviderVariableValue::test_returns_none_when_variable_service_raises_value_error": 0.041, + "src/backend/tests/unit/base/models/test_provider_variable_value.py::TestGetProviderVariableValue::test_returns_value_when_variable_found": 0.039, + "src/backend/tests/unit/base/test_preload.py::test_get_owned_temp_dirs_master_owns_dirs": 0.044, + "src/backend/tests/unit/base/test_preload.py::test_get_owned_temp_dirs_not_preloaded": 0.042, + "src/backend/tests/unit/base/test_preload.py::test_get_owned_temp_dirs_worker_owns_nothing": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_is_master_false_by_default": 0.042, + "src/backend/tests/unit/base/test_preload.py::test_is_master_false_in_worker_process": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_is_master_true_in_master_process": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_is_preloaded_false_by_default": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_is_preloaded_true_after_preload": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_mark_step_complete_enforces_prerequisite_order": 0.04, + "src/backend/tests/unit/base/test_preload.py::test_mark_step_complete_succeeds_when_prerequisites_met": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_preload_master_calls_gc_freeze": 0.047, + "src/backend/tests/unit/base/test_preload.py::test_preload_master_idempotent": 0.048, + "src/backend/tests/unit/base/test_preload.py::test_preload_master_no_flag_on_failure": 0.049, + "src/backend/tests/unit/base/test_preload.py::test_preload_master_resets_state_on_failure": 0.047, + "src/backend/tests/unit/base/test_preload.py::test_preload_master_resets_state_when_gc_freeze_fails": 0.046, + "src/backend/tests/unit/base/test_preload.py::test_preload_master_sets_state_on_success": 0.005, + "src/backend/tests/unit/base/test_preload.py::test_reset_cleanup_calls_temp_directories": 1.403, + "src/backend/tests/unit/base/test_preload.py::test_reset_clears_all_fields": 0.041, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_agentic_experience_enabled": 1.524, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_agentic_partial_failure_tracked_separately": 1.649, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_best_effort_step_failure_continues": 2.002, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_closes_external_cache_service": 1.74, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_critical_step_failure_propagates": 0.039, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_disposes_db_engine": 0.048, + "src/backend/tests/unit/base/test_preload.py::test_run_master_preload_sets_completion_flags_on_success": 0.043, + "src/backend/tests/unit/base/test_server.py::TestGunicornEnvArgs::test_env_args_applied": 0.039, + "src/backend/tests/unit/base/test_server.py::TestGunicornEnvArgs::test_env_does_not_override_worker_class": 0.039, + "src/backend/tests/unit/base/test_server.py::TestGunicornEnvArgs::test_no_env_var_uses_defaults": 0.041, + "src/backend/tests/unit/base/test_server.py::TestGunicornEnvArgs::test_programmatic_options_override_env": 0.037, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_always_runs_gc": 0.045, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_handles_gc_collect_exception": 0.047, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_handles_psutil_import_error": 0.039, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_no_tcp_warning_for_listen_only_connections": 0.044, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_no_thread_warning_for_benign_threads": 0.006, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_no_thread_warning_when_only_main_thread": 0.005, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_for_non_listen_tcp_connections[CLOSE_WAIT]": 0.04, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_for_non_listen_tcp_connections[CLOSING]": 0.009, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_for_non_listen_tcp_connections[ESTABLISHED]": 0.039, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_for_non_listen_tcp_connections[SYN_SENT]": 0.049, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_for_non_listen_tcp_connections[TIME_WAIT]": 0.041, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_for_non_main_threads": 0.008, + "src/backend/tests/unit/base/test_server.py::test_pre_fork_warns_when_psutil_raises": 0.049, "src/backend/tests/unit/base/tools/test_component_tool.py::test_component_tool": 0.04467487393412739, - "src/backend/tests/unit/base/tools/test_component_toolkit.py::test_component_tool": 0.0019873329729307443, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolAsyncEventEmission::test_async_emits_build_end_event": 0.117, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolAsyncEventEmission::test_async_no_event_emission_without_event_manager": 0.405, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolAsyncExceptionHandling::test_async_build_end_emitted_on_exception": 0.01, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolAsyncExceptionHandling::test_sync_tool_in_executor_delivers_events": 0.051, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolEventEmission::test_build_start_and_end_events_are_emitted": 0.038, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolEventEmission::test_emits_build_events_with_correct_structure": 0.038, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolEventEmission::test_event_includes_logs_when_component_calls_log": 0.036, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolEventEmission::test_no_event_emission_without_event_manager": 0.04, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolEventEmission::test_no_log_events_when_component_does_not_call_log": 0.039, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolExceptionHandling::test_build_end_emitted_on_exception": 0.347, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::TestComponentToolExceptionHandling::test_build_start_emitted_before_exception": 0.007, + "src/backend/tests/unit/base/tools/test_component_toolkit.py::test_component_tool": 0.039, "src/backend/tests/unit/base/tools/test_component_toolkit.py::test_component_tool_with_api_key": 3.2793682489718776, "src/backend/tests/unit/base/tools/test_component_toolkit.py::test_sql_component_to_toolkit": 7.634652540989919, - "src/backend/tests/unit/base/tools/test_create_schema.py::test_create_schema": 0.002514541003620252, - "src/backend/tests/unit/base/tools/test_toolmodemixin.py::test_component_inputs_toolkit": 0.013006500987103209, + "src/backend/tests/unit/base/tools/test_component_toolkit_multiple_outputs.py::test_should_create_tools_with_prefixed_names_when_component_has_multiple_outputs": 0.041, + "src/backend/tests/unit/base/tools/test_create_schema.py::test_create_schema": 0.039, + "src/backend/tests/unit/base/tools/test_dataframe_tool_serialization.py::test_dataframe_tool_result_format": 0.025, + "src/backend/tests/unit/base/tools/test_dataframe_tool_serialization.py::test_dataframe_tool_serialization": 0.036, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_build_flow_cache_key_with_flow_id": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_build_flow_cache_key_without_flow_id_raises_error": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_build_flow_cache_key_without_user_id_raises_error": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_flow_cache_call_raises_error_for_unknown_action": 0.049, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_flow_cache_call_returns_none_when_cache_disabled": 0.043, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_flow_cache_call_returns_none_when_cache_service_unavailable": 0.045, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_get_cached_flow_returns_none_on_cache_miss": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_is_cached_flow_up_to_date_returns_false_for_older_cache": 0.04, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_is_cached_flow_up_to_date_returns_false_when_cached_timestamp_missing": 0.037, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_is_cached_flow_up_to_date_returns_false_when_updated_at_missing": 0.039, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_is_cached_flow_up_to_date_returns_true_for_newer_cache": 0.038, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_is_cached_flow_up_to_date_returns_true_for_same_timestamp": 0.038, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_parse_timestamp_parses_iso_format": 0.044, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_parse_timestamp_parses_iso_with_offset": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_parse_timestamp_returns_none_for_invalid_format": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_parse_timestamp_returns_none_for_none": 0.04, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowCaching::test_set_cached_flow_stores_graph_data": 0.04, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_flow_returns_empty_data_when_none": 0.043, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_flow_with_id": 0.044, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_flow_with_name": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_graph_blocks_custom_components_when_disabled": 0.04, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_graph_deletes_stale_cache_and_refetches": 0.034, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_graph_fetches_and_caches_when_not_cached": 0.036, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_graph_raises_error_without_id_or_name": 0.04, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentFlowRetrieval::test_get_graph_uses_cache_when_available_and_up_to_date": 0.038, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInitialization::test_init_creates_cache_dispatcher": 0.042, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInitialization::test_init_creates_cache_service": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInitialization::test_init_sets_add_tool_output_flag": 0.049, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInitialization::test_init_sets_last_run_outputs_to_none": 0.045, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_build_inputs_from_ioputs": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_build_inputs_from_ioputs_handles_data_object": 0.037, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_delete_fields_with_dict": 0.042, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_delete_fields_with_list": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_extract_ioputs_from_keyed_values": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_format_flow_outputs_creates_output_objects": 0.038, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_format_flow_outputs_skips_vertices_with_successors": 0.039, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_get_ioput_name_creates_unique_name": 0.045, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_get_ioput_name_raises_error_without_ioput_name": 0.041, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_get_ioput_name_raises_error_without_vertex_id": 0.044, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_get_new_fields_exposes_message_handle_for_chat_input_value": 0.045, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_resolve_exposed_input_types_preserves_existing_input_types": 0.042, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_resolve_exposed_input_types_restores_message_for_empty_text_field": 0.051, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_resolve_exposed_input_types_restores_message_when_missing": 0.043, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_resolve_exposed_input_types_skips_non_text_fields": 0.043, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentInputOutputHandling::test_update_input_types_sets_empty_list_for_none": 0.04, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentOutputMethods::test_resolve_flow_output_finds_correct_output": 0.124, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentToolGeneration::test_get_required_data_returns_description_and_fields": 0.035, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentTweakData::test_build_flow_tweak_data_merges_tool_tweaks": 0.049, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentTweaks::test_process_tweaks_on_graph": 0.044, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentUpdateOutputs::test_update_outputs_ignored_fields": 0.045, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentUpdateOutputs::test_update_outputs_with_flow_name_selected": 0.115, + "src/backend/tests/unit/base/tools/test_run_flow.py::TestRunFlowBaseComponentUpdateOutputs::test_update_outputs_with_tool_mode_false": 0.077, + "src/backend/tests/unit/base/tools/test_toolmodemixin.py::test_component_inputs_toolkit": 0.035, + "src/backend/tests/unit/base/tools/test_toolmodemixin.py::test_table_input_preserves_list_dict": 0.043, "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_all_versions_have_a_file_name_defined": 0.0010075410536956042, "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_component_versions[1.0.19]": 0.0006282929971348494, "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_component_versions[1.1.0]": 0.0005540830316022038, "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_component_versions[1.1.1]": 0.0007710419886279851, - "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_decorator_applied": 0.001958625012775883, + "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_decorator_applied": 0.038, "src/backend/tests/unit/base/tools/test_vector_store_decorator.py::TestVectorStoreDecorator::test_latest_version": 0.010553333966527134, "src/backend/tests/unit/components/agents/test_agent_component.py::TestAgentComponent::test_agent_component_initialization": 0.003768415976082906, "src/backend/tests/unit/components/agents/test_agent_component.py::TestAgentComponent::test_agent_has_dual_outputs": 0.0037760420236736536, @@ -255,6 +3575,45 @@ "src/backend/tests/unit/components/agents/test_agent_events.py::test_tool_start_event": 0.005058793001808226, "src/backend/tests/unit/components/agents/test_agent_events.py::test_unknown_event": 0.0009467510099057108, "src/backend/tests/unit/components/agents/test_tool_calling_agent.py::test_tool_calling_agent_component": 3.95495145797031, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_handle_missing_provider_fields_gracefully": 0.087, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_hide_all_provider_fields_when_openai_selected": 0.041, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_return_unchanged_when_model_value_is_empty": 0.041, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_return_unchanged_when_model_value_is_not_list": 0.041, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_show_ollama_fields_when_ollama_selected": 0.04, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_show_watsonx_fields_when_watsonx_selected": 0.04, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestUpdateProviderFieldsVisibility::test_should_use_field_value_when_field_name_is_model": 0.085, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_model_is_empty_list": 0.039, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_model_is_none": 0.04, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_model_is_not_list": 0.124, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_model_name_is_empty_string": 0.045, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_model_name_missing": 0.085, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_provider_is_empty_string": 0.043, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_raise_when_provider_missing": 0.041, + "src/backend/tests/unit/components/bundles/agentics/test_model_config.py::TestValidateModelSelection::test_should_return_model_and_provider_when_valid_selection": 0.039, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_basic_setup": 0.083, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_build_model_exception_handling": 0.036, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_build_model_integration": 0.045, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_build_model_invalid_model_selection": 0.039, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_build_model_success": 0.037, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_build_model_with_json_mode": 0.039, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_build_model_with_streaming": 0.034, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_component_input_requirements": 0.039, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_component_input_types": 0.039, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_component_inputs_structure": 0.039, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_get_models_integration": 0.045, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_get_models_json_decode_error": 0.04, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_component.py::TestCometAPIComponent::test_get_models_success": 0.035, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_cometapi_models_not_empty": 0.041, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_model_names_alias": 0.041, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_models_are_strings": 0.04, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_no_duplicate_models": 0.041, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_should_not_expose_fictional_gpt53_ids_in_cometapi_models": 0.049, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_specific_model_in_list[claude-3-5-haiku-latest]": 0.041, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_specific_model_in_list[deepseek-chat]": 0.044, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_specific_model_in_list[gemini-2.5-flash]": 0.048, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_specific_model_in_list[gpt-4o-mini]": 0.049, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_specific_model_in_list[grok-3]": 0.052, + "src/backend/tests/unit/components/bundles/cometapi/test_cometapi_constants.py::TestCometAPIConstants::test_specific_models_present": 0.041, "src/backend/tests/unit/components/bundles/composio/test_base.py::TestComposioBase::test_all_versions_have_a_file_name_defined": 0.0013641250261571258, "src/backend/tests/unit/components/bundles/composio/test_base.py::TestComposioBase::test_build_action_maps": 0.0011071659973822534, "src/backend/tests/unit/components/bundles/composio/test_base.py::TestComposioBase::test_build_wrapper_no_api_key": 0.0019804590265266597, @@ -265,6 +3624,15 @@ "src/backend/tests/unit/components/bundles/composio/test_base.py::TestComposioBase::test_get_action_fields": 0.0007218750251922756, "src/backend/tests/unit/components/bundles/composio/test_base.py::TestComposioBase::test_latest_version": 0.008931207994464785, "src/backend/tests/unit/components/bundles/composio/test_base.py::TestComposioBase::test_show_hide_fields": 0.0006626679969485849, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestComposioCloudValidation::test_composio_api_disabled_in_astra_cloud": 0.044, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestComposioCloudValidation::test_composio_base_execute_disabled_in_astra_cloud": 0.041, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_data_coerced_to_dict_for_object_field": 0.04, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_message_coerced_to_text_for_str_field": 0.034, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_message_coercion_happens_before_json_parse": 0.028, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_message_with_empty_text_is_skipped": 0.035, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_multiple_message_fields_all_coerced": 0.032, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_none_field_is_skipped": 0.034, + "src/backend/tests/unit/components/bundles/composio/test_composio_components.py::TestExecuteActionRichTypeCoercion::test_plain_string_passed_through_unchanged": 0.044, "src/backend/tests/unit/components/bundles/composio/test_github.py::TestGitHubComponent::test_all_versions_have_a_file_name_defined": 0.000590665964409709, "src/backend/tests/unit/components/bundles/composio/test_github.py::TestGitHubComponent::test_as_dataframe": 0.009676958026830107, "src/backend/tests/unit/components/bundles/composio/test_github.py::TestGitHubComponent::test_component_versions[1.0.19]": 0.0005587080086115748, @@ -311,6 +3679,23 @@ "src/backend/tests/unit/components/bundles/composio/test_outlook.py::TestOutlookComponent::test_init": 0.0016895410080906004, "src/backend/tests/unit/components/bundles/composio/test_outlook.py::TestOutlookComponent::test_latest_version": 0.00544029101729393, "src/backend/tests/unit/components/bundles/composio/test_outlook.py::TestOutlookComponent::test_update_build_config": 0.0016177069919649512, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestNoOpOnAlreadyTypedSchemas::test_file_helper_uploads_unchanged_on_fully_typed_schema": 0.1, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestNoOpOnAlreadyTypedSchemas::test_sanitize_is_no_op_on_fully_typed_schema": 0.128, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_file_helper_methods_patched": 0.042, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_file_helper_uploads_accepts_positional_args": 0.039, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_file_helper_uploads_no_keyerror_on_untyped_property": 0.089, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_provider_subclass_instantiable": 0.042, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_pydantic_builder_no_keyerror_on_untyped_property": 0.098, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_pydantic_builder_patched": 0.085, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSafeLangchainProviderRegression::test_substitute_file_uploads_no_longer_keyerrors_after_sanitize": 0.041, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_anyof_property_gets_default_type": 0.04, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_array_inferred_from_items": 0.041, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_defs_walked": 0.041, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_existing_types_preserved": 0.041, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_nested_object_inferred_from_properties": 0.04, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_non_dict_input_no_op": 0.042, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_object_with_typeless_property_gets_string_type": 0.041, + "src/backend/tests/unit/components/bundles/composio/test_safe_provider.py::TestSanitizeSchema::test_ref_only_property_gets_default_type": 0.041, "src/backend/tests/unit/components/bundles/composio/test_slack.py::TestSlackComponent::test_all_versions_have_a_file_name_defined": 0.00047204099246300757, "src/backend/tests/unit/components/bundles/composio/test_slack.py::TestSlackComponent::test_as_dataframe": 0.003204000007826835, "src/backend/tests/unit/components/bundles/composio/test_slack.py::TestSlackComponent::test_component_versions[1.0.19]": 0.00048258400056511164, @@ -323,58 +3708,74 @@ "src/backend/tests/unit/components/bundles/composio/test_slack.py::TestSlackComponent::test_latest_version": 0.004491709027206525, "src/backend/tests/unit/components/bundles/composio/test_slack.py::TestSlackComponent::test_update_build_config": 0.0014909160090610385, "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_all_versions_have_a_file_name_defined": 0.0010013749997597188, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_complex_query_result": 0.0044400839833542705, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_complex_query_result": 0.032, "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_component_versions[1.0.19]": 0.0009715839987620711, "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_component_versions[1.1.0]": 0.0009319579985458404, "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_component_versions[1.1.1]": 0.0009336670045740902, "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_empty_query_raises[ \\n\\t ]": 0.0018787499866448343, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_empty_query_raises[]": 0.0023359160113614053, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_execute_sql_invalid_query": 0.0020419160136952996, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_execute_sql_success": 0.003112083999440074, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_invalid_service_account_json": 0.00275295801111497, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_empty_query_raises[]": 0.074, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_execute_sql_invalid_query": 0.049, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_execute_sql_success": 0.032, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_invalid_service_account_json": 0.048, "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_latest_version": 0.003404540999326855, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_missing_project_id_in_credentials": 0.0014151670038700104, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_missing_service_account_file": 0.0012511250097304583, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_multiple_statements": 0.002837667998392135, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_parameters": 0.0027423329884186387, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_quotes": 0.005764999950770289, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_special_characters": 0.0029064160480629653, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_sql_code_block": 0.0025010009994730353, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_whitespace": 0.003081998962443322, - "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_refresh_error_handling": 0.0016127090202644467, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_missing_project_id_in_credentials": 0.046, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_missing_service_account_file": 0.042, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_multiple_statements": 0.12, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_parameters": 0.057, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_quotes": 0.011, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_special_characters": 0.079, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_sql_code_block": 0.043, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_query_with_whitespace": 0.036, + "src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py::TestBigQueryExecutorComponent::test_refresh_error_handling": 0.051, "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_all_versions_have_a_file_name_defined": 0.00048070898628793657, "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_component_versions[1.0.19]": 0.0005491250194609165, "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_component_versions[1.1.0]": 0.0022520839993376285, "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_component_versions[1.1.1]": 0.0004988750151824206, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_evaluator_not_found": 0.0015255410107783973, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_http_error": 0.008881082001607865, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_no_api_key": 0.0016356660053133965, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_no_evaluators": 0.0011819580104202032, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_success": 0.009251374955056235, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_timeout_handling": 0.008078957034740597, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_with_contexts_parsing": 0.008182374993339181, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_with_tracing": 0.008384373970329762, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_get_dynamic_inputs": 0.0010729159694164991, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_get_dynamic_inputs_error_handling": 0.0008575830142945051, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_get_dynamic_inputs_with_boolean_setting": 0.0009198319748975337, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_evaluator_not_found": 0.039, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_http_error": 0.032, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_no_api_key": 0.042, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_no_evaluators": 0.055, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_success": 0.03, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_timeout_handling": 0.032, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_with_contexts_parsing": 0.033, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_evaluate_with_tracing": 0.037, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_get_dynamic_inputs": 0.042, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_get_dynamic_inputs_error_handling": 0.044, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_get_dynamic_inputs_with_boolean_setting": 0.054, "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_latest_version": 0.00373708299594, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_set_evaluators_empty_response": 0.0012653759913519025, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_set_evaluators_success": 0.00145575002534315, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_update_build_config_basic": 0.0017147080216091126, - "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_update_build_config_with_evaluator_selection": 0.0013980419607833028, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_set_evaluators_empty_response": 0.039, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_set_evaluators_success": 0.039, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_update_build_config_basic": 0.041, + "src/backend/tests/unit/components/bundles/langwatch/test_langwatch_component.py::TestLangWatchComponent::test_update_build_config_with_evaluator_selection": 0.039, + "src/backend/tests/unit/components/bundles/mem0/test_mem0_component.py::TestMem0CloudValidation::test_build_mem0_disabled_in_astra_cloud": 0.076, + "src/backend/tests/unit/components/bundles/mem0/test_mem0_component.py::TestMem0CloudValidation::test_build_mem0_works_when_not_in_cloud": 0.038, + "src/backend/tests/unit/components/bundles/mem0/test_mem0_component.py::TestMem0CloudValidation::test_build_search_results_uses_mem0_2_filters_for_get_all": 0.086, + "src/backend/tests/unit/components/bundles/mem0/test_mem0_component.py::TestMem0CloudValidation::test_build_search_results_uses_mem0_2_filters_for_search": 0.082, + "src/backend/tests/unit/components/bundles/twelvelabs/test_twelvelabs_components.py::TestTwelveLabsCloudValidation::test_split_video_process_disabled_in_astra_cloud": 0.08, + "src/backend/tests/unit/components/bundles/twelvelabs/test_twelvelabs_components.py::TestTwelveLabsCloudValidation::test_video_file_process_disabled_in_astra_cloud": 0.082, "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_all_versions_have_a_file_name_defined": 0.000492625025799498, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_basic_setup": 0.0015408750041387975, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_basic_setup": 0.041, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_chunking_behavior": 0.092, "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_component_versions[1.0.19]": 0.0004934180178679526, "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_component_versions[1.1.0]": 0.0004676240496337414, "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_component_versions[1.1.1]": 0.00046129198744893074, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_empty_transcript_handling": 0.0011142909934278578, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_get_data_output_success": 0.001195126009406522, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_get_dataframe_output_success": 0.0016434179851785302, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_get_message_output_success": 0.0010021249763667583, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_empty_transcript_handling": 0.033, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_extract_video_id_embed_url": 0.047, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_extract_video_id_invalid_url": 0.041, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_extract_video_id_short_url": 0.048, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_extract_video_id_watch_url": 0.049, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_extract_video_id_with_params": 0.041, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_general_exception_handling": 0.085, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_get_data_output_success": 0.041, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_get_dataframe_output_success": 0.035, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_get_message_output_success": 0.04, "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_latest_version": 0.0027228749822825193, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_no_transcript_found_error": 0.0011340409982949495, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_transcript_disabled_error": 0.0012877909757662565, - "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_translation_setting": 0.0006595839513465762, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_no_transcript_found_error": 0.093, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_transcript_disabled_error": 0.036, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_translation_parameter": 0.041, + "src/backend/tests/unit/components/bundles/youtube/test_youtube_transcript_component.py::TestYouTubeTranscriptsComponent::test_translation_setting": 0.043, + "src/backend/tests/unit/components/codeagents/test_codeagents_imports.py::test_codeagents_bundle_exposed_via_components_package": 0.133, + "src/backend/tests/unit/components/codeagents/test_codeagents_imports.py::test_codeagents_components_lazy_import": 0.056, "src/backend/tests/unit/components/data/test_api_request_component.py::TestAPIRequestComponent::test_add_query_params": 0.0010754170070867985, "src/backend/tests/unit/components/data/test_api_request_component.py::TestAPIRequestComponent::test_all_versions_have_a_file_name_defined": 0.00045074999798089266, "src/backend/tests/unit/components/data/test_api_request_component.py::TestAPIRequestComponent::test_component_versions[1.0.19]": 0.0004679590347222984, @@ -498,6 +3899,174 @@ "src/backend/tests/unit/components/data/test_web_search.py::TestWebSearchComponent::test_invalid_url_handling": 0.0008121670107357204, "src/backend/tests/unit/components/data/test_web_search.py::TestWebSearchComponent::test_latest_version": 0.002719084033742547, "src/backend/tests/unit/components/data/test_web_search.py::TestWebSearchComponent::test_successful_web_search": 22.156292709027184, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_add_query_params": 0.042, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_error_handling": 0.031, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_get_request_does_not_send_body": 0.065, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_invalid_urls": 0.06, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_api_request": 0.009, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_request_binary_response": 0.051, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_request_save_to_file": 0.026, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_request_success": 0.051, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_request_timeout": 0.036, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_request_with_metadata": 0.039, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_make_request_with_redirects": 0.024, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_parse_curl": 0.049, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_process_body": 0.055, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_process_headers": 0.042, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_response_info": 0.055, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestComponent::test_update_build_config": 0.054, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_chained_public_redirects_are_followed": 0.031, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_method_for_redirect_semantics": 0.055, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_scheme_change_is_blocked": 0.055, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_hostname_resolving_internal_is_blocked": 0.039, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_address_is_blocked[http://0.0.0.0:8080/admin-unspecified]": 0.04, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_address_is_blocked[http://10.0.0.5/internal-rfc1918-10]": 0.034, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_address_is_blocked[http://127.0.0.1:9999/secret-loopback]": 0.185, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_address_is_blocked[http://169.254.169.254/latest/meta-data/-link-local-metadata]": 0.04, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_address_is_blocked[http://172.16.0.9/internal-rfc1918-172]": 0.041, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_address_is_blocked[http://192.168.0.10/admin-rfc1918-192]": 0.037, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_redirect_to_internal_allowed_when_protection_disabled": 0.032, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_sensitive_headers_dropped_on_cross_host_redirect": 0.019, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestRedirectSSRFProtection::test_too_many_redirects_raises": 0.019, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_dns_pinning_is_used_when_protection_enabled": 0.039, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_follow_redirects_disabled_by_default": 0.055, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_follow_redirects_security_warning": 0.042, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_invalid_url_raises_error": 0.058, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_normal_client_used_when_protection_disabled": 0.044, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_allowlist_cidr_range": 0.04, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_allowlist_hostname": 0.043, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_allowlist_ip_address": 0.041, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_allowlist_multiple_entries": 0.044, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_allows_public_urls": 0.023, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_cloud_metadata_endpoint": 0.051, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_link_local_169_254": 0.053, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_localhost_0_0_0_0": 0.033, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_localhost_127_0_0_1": 0.05, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_private_network_10_0": 0.067, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_private_network_172_16": 0.022, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_blocks_private_network_192_168": 0.022, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_ssrf_protection_disabled_allows_all_urls": 0.042, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_url_normalization_adds_https": 0.025, + "src/backend/tests/unit/components/data_source/test_api_request_component.py::TestAPIRequestSSRFProtection::test_url_normalization_preserves_http": 0.03, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestAPIRequestDNSRebindingEdgeCases::test_api_request_blocks_ipv4_mapped_ipv6_localhost": 0.129, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestAPIRequestDNSRebindingEdgeCases::test_api_request_blocks_ipv4_mapped_ipv6_metadata": 0.122, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestAPIRequestDNSRebindingEdgeCases::test_api_request_blocks_mixed_safe_unsafe_dns_answers": 0.086, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_applies_to_redirect_hops": 0.289, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_blocks_private_ip_resolution": 0.053, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_disabled_when_protection_disabled": 0.043, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_preserves_hostname_in_header": 0.041, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_prevents_rebinding_attack": 0.045, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_with_allowlisted_host": 0.237, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_with_direct_ip_address": 0.046, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_with_ipv6": 0.041, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestDNSRebindingProtection::test_dns_pinning_with_multiple_ips_fallback": 0.237, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_blocks_aws_metadata_on_first_query": 0.052, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_blocks_ipv4_mapped_ipv6_localhost": 0.013, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_blocks_ipv4_mapped_ipv6_private_network": 0.016, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_blocks_localhost_on_first_query": 0.009, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_blocks_mixed_safe_unsafe_dns_answers": 0.092, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_prevents_dns_rebinding_attack": 0.257, + "src/backend/tests/unit/components/data_source/test_dns_rebinding.py::TestURLComponentDNSRebindingProtection::test_url_component_revalidates_discovered_links": 0.269, + "src/backend/tests/unit/components/data_source/test_news_search.py::TestNewsSearchComponent::test_empty_news_results": 0.078, + "src/backend/tests/unit/components/data_source/test_news_search.py::TestNewsSearchComponent::test_news_search_error": 0.046, + "src/backend/tests/unit/components/data_source/test_news_search.py::TestNewsSearchComponent::test_successful_news_search": 0.137, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderComponent::test_empty_rss_feed": 0.038, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderComponent::test_rss_fetch_error": 0.041, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderComponent::test_rss_fetch_with_missing_fields": 0.04, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderComponent::test_successful_rss_fetch": 0.037, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderSSRFProtection::test_allows_public_feed": 0.041, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderSSRFProtection::test_blocks_cloud_metadata_endpoint": 0.123, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderSSRFProtection::test_blocks_localhost": 0.042, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderSSRFProtection::test_blocks_private_network": 0.045, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderSSRFProtection::test_blocks_redirect_to_metadata": 0.04, + "src/backend/tests/unit/components/data_source/test_rss.py::TestRSSReaderSSRFProtection::test_protection_disabled_allows_internal": 0.044, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_components_work_in_local_mode": 0.051, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_csv_agent_s3_file_handling": 0.111, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_csv_to_data_fileinput_local_only": 0.04, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_csv_to_data_path_local": 0.04, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_csv_to_data_path_s3_key": 0.037, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_file_component_get_local_file_for_docling_local": 0.034, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_file_component_get_local_file_for_docling_s3": 0.1, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_file_component_s3_path_handling": 0.02, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_json_agent_s3_file_handling": 0.042, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_json_to_data_fileinput_local_only": 0.082, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_json_to_data_path_local": 0.088, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_json_to_data_path_s3_key": 0.087, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_s3_concurrent_operations": 0.005, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_s3_error_handling": 0.043, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_s3_file_download_and_processing": 0.012, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_s3_metadata_handling": 0.016, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_s3_path_parsing": 0.084, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_s3_streaming_operations": 0.04, + "src/backend/tests/unit/components/data_source/test_s3_components.py::TestS3CompatibleComponents::test_save_file_component_s3_upload": 0.036, + "src/backend/tests/unit/components/data_source/test_sql_executor.py::TestSQLComponent::test_query_error_with_add_error": 0.041, + "src/backend/tests/unit/components/data_source/test_sql_executor.py::TestSQLComponent::test_run_sql_query": 0.032, + "src/backend/tests/unit/components/data_source/test_sql_executor.py::TestSQLComponent::test_successful_query_with_columns": 0.033, + "src/backend/tests/unit/components/data_source/test_sql_executor.py::TestSQLComponent::test_successful_query_without_columns": 0.03, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_component_initialization": 0.041, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_component_outputs": 0.04, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_get_schema_info": 0.04, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_load_table_data_empty": 0.042, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_load_table_data_error_handling": 0.04, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_load_table_data_none": 0.04, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_load_table_data_with_data_objects": 0.04, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_load_table_data_with_dict_rows": 0.043, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_load_table_data_with_mixed_types": 0.041, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoComponent::test_table_schema_configuration": 0.04, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoIntegration::test_column_schema_with_load_from_db_false": 0.043, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoIntegration::test_column_schema_with_load_from_db_true": 0.042, + "src/backend/tests/unit/components/data_source/test_table_loader_component.py::TestTableSchemaDemoIntegration::test_table_component_schema_serialization": 0.042, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_component_initialization": 0.04, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_component_outputs": 0.04, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_get_schema_info": 0.04, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_load_table_data_empty": 0.046, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_load_table_data_error_handling": 0.04, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_load_table_data_none": 0.041, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_load_table_data_with_data_objects": 0.039, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_load_table_data_with_dict_rows": 0.384, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_load_table_data_with_mixed_types": 0.041, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoComponent::test_table_schema_configuration": 0.042, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoIntegration::test_column_schema_with_load_from_db_false": 0.528, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoIntegration::test_column_schema_with_load_from_db_true": 0.538, + "src/backend/tests/unit/components/data_source/test_table_schema_demo_component.py::TestTableSchemaDemoIntegration::test_table_component_schema_serialization": 0.09, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_basic_functionality": 0.038, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_ensure_url": 0.038, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_error_handling_empty_urls": 0.006, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_error_handling_no_documents": 0.007, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_html_format": 0.037, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_markdown_format": 0.015, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_missing_metadata": 0.244, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_multiple_urls": 0.088, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponent::test_url_component_text_format": 0.104, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponentSSRFProtection::test_ensure_url_allows_public_ip": 0.125, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponentSSRFProtection::test_ensure_url_blocks_localhost": 0.044, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponentSSRFProtection::test_ensure_url_blocks_metadata_endpoint": 0.081, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponentSSRFProtection::test_ensure_url_blocks_private_ip": 0.075, + "src/backend/tests/unit/components/data_source/test_url_component.py::TestURLComponentSSRFProtection::test_ssrf_protection_in_fetch_content": 0.048, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_clean_html": 0.041, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_empty_query_error": 0.04, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_ensure_url": 0.041, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_invalid_url_handling": 0.04, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_news_search_with_location": 0.038, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_news_search_no_params": 0.036, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_news_search_with_query": 0.039, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_news_search_with_topic": 0.043, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_rss_read_empty_response": 0.041, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_rss_read_invalid_xml": 0.038, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_rss_read_no_url": 0.044, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_rss_read_success": 0.039, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_search_fallback": 0.039, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_search_news_mode": 0.04, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_search_rss_mode": 0.038, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_search_web_mode": 0.037, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_web_search_no_results": 0.046, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_web_search_request_error": 0.041, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_perform_web_search_success": 0.038, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_sanitize_query": 0.042, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_update_build_config_news_mode": 0.045, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_update_build_config_rss_mode": 0.045, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_update_build_config_web_mode": 0.043, + "src/backend/tests/unit/components/data_source/test_web_search.py::TestWebSearchComponent::test_validate_url": 0.043, "src/backend/tests/unit/components/embeddings/test_embedding_model_component.py::TestEmbeddingModelComponent::test_all_versions_have_a_file_name_defined": 8.159916476000035, "src/backend/tests/unit/components/embeddings/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_openai": 10.576514679999946, "src/backend/tests/unit/components/embeddings/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_openai_missing_api_key": 8.120289870000079, @@ -507,10 +4076,576 @@ "src/backend/tests/unit/components/embeddings/test_embedding_model_component.py::TestEmbeddingModelComponent::test_component_versions[1.1.1]": 8.112025460000268, "src/backend/tests/unit/components/embeddings/test_embedding_model_component.py::TestEmbeddingModelComponent::test_latest_version": 8.215820538000116, "src/backend/tests/unit/components/embeddings/test_embedding_model_component.py::TestEmbeddingModelComponent::test_update_build_config_openai": 8.282516385000008, - "src/backend/tests/unit/components/git/test_git_component.py::test_check_content_pattern": 0.0030239579791668802, - "src/backend/tests/unit/components/git/test_git_component.py::test_check_file_patterns": 0.0035422499931883067, - "src/backend/tests/unit/components/git/test_git_component.py::test_combined_filter": 0.0033488319895695895, - "src/backend/tests/unit/components/git/test_git_component.py::test_is_binary": 0.006222750002052635, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAttributeDelegation::test_getattr_custom_method": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAttributeDelegation::test_getattr_delegates_to_embeddings": 0.04, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAttributeDelegation::test_getattr_nonexistent_attribute": 0.04, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAvailableModels::test_available_models_dict_access": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAvailableModels::test_available_models_different_dimensions": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAvailableModels::test_available_models_instances": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsAvailableModels::test_primary_vs_available_models": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsCallable::test_call_non_callable_embeddings": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsCallable::test_call_with_callable_embeddings": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsEmbedMethods::test_aembed_documents": 0.038, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsEmbedMethods::test_aembed_query": 0.04, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsEmbedMethods::test_embed_documents": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsEmbedMethods::test_embed_query": 0.04, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsInitialization::test_inherits_from_embeddings": 0.04, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsInitialization::test_init_with_available_models": 0.039, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsInitialization::test_init_with_none_available_models": 0.042, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsInitialization::test_init_without_available_models": 0.042, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsIntegration::test_async_multi_model_embedding_generation": 0.04, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsIntegration::test_document_embedding_with_available_models": 0.083, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsIntegration::test_empty_available_models_dict": 1.829, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsIntegration::test_multi_model_embedding_generation": 0.043, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsIntegration::test_single_model_in_available_models": 0.136, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsRepr::test_repr_with_models": 0.041, + "src/backend/tests/unit/components/embeddings/test_embeddings_with_models.py::TestEmbeddingsWithModelsRepr::test_repr_without_models": 0.084, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_basic": 0.041, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_connection_error": 0.039, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_no_transform_outside_container": 0.044, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_strips_v1_suffix_and_logs_warning": 0.045, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_strips_v1_trailing_slash": 0.051, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_transforms_127_0_0_1_in_container": 0.051, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_transforms_localhost_in_docker_container": 0.048, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_transforms_localhost_in_podman_container": 0.014, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_with_api_key": 0.043, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_build_embeddings_without_api_key_no_client_kwargs": 0.04, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_component_constants": 0.163, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_component_inputs": 0.15, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_component_metadata": 0.044, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_component_outputs": 0.084, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_all_models_non_embedding": 0.039, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_empty_model_list": 0.042, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_failure": 0.042, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_missing_capabilities_key": 0.039, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_post_request_failure": 0.034, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_success_filters_embedding_capability": 0.04, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_url_normalization_trailing_slash": 0.044, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_url_normalization_v1_trailing_slash": 0.038, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_with_api_key_passes_headers": 0.041, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_with_v1_suffix_stripped": 0.046, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_get_model_without_api_key_no_headers": 0.041, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_headers_with_api_key": 0.042, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_headers_with_empty_api_key": 0.042, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_headers_with_whitespace_api_key": 0.044, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_headers_without_api_key": 0.043, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_failure": 0.041, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_success": 0.041, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_with_api_key_passes_headers": 0.185, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_with_empty_url": 0.096, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_with_none_url": 0.038, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_with_v1_suffix": 0.042, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_is_valid_ollama_url_without_api_key_no_headers": 0.034, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_update_build_config_base_url_field": 0.039, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_update_build_config_empty_options_when_url_invalid": 0.04, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_update_build_config_model_name_field": 0.033, + "src/backend/tests/unit/components/embeddings/test_ollama_embeddings_component.py::TestOllamaEmbeddingsComponent::test_update_build_config_when_ollama_not_running": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_as_dataframe": 0.008, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_component_build_with_multithreading": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_invalid_type": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_with_depth": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_with_hidden_files": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_with_multithreading": 0.05, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_with_types[file_types0-1]": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_with_types[file_types1-1]": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_with_types[file_types2-2]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_directory_component.py::TestDirectoryComponent::test_directory_without_mocks": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentCloudEnvironment::test_advanced_mode_disabled_in_cloud": 0.046, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentCloudEnvironment::test_advanced_mode_toggle_disabled_in_cloud": 0.048, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentCloudEnvironment::test_pipeline_change_disabled_in_cloud": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_advanced_mode_not_available_for_csv": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_dynamic_outputs_have_tool_mode_enabled": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_file_path_str_input_exists_for_tool_mode": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_file_path_str_takes_priority_over_path": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_process_docling_subprocess_success": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_read_file_using_file_path_str": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_read_file_using_path_when_file_path_str_not_provided": 0.036, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_advanced_mode_disabled": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_advanced_mode_enabled_single_pdf": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_empty_path": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_multiple_files": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_non_path_field": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_single_csv_file": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentDynamicOutputs::test_update_outputs_single_json_file": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentFrontendMetadata::test_file_types_are_serialized_for_frontend": 0.03, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentStorageLocation::test_storage_location_defaults_to_local": 0.048, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentStorageLocation::test_storage_location_is_advanced": 0.048, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_add_tool_output_is_enabled": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_description_property_returns_dynamic_description": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_file_path_str_input_has_tool_mode_true": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filename_with_comma": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filename_with_multiple_dots": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filename_with_numbers": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filename_with_spaces": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filename_with_special_characters": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filename_with_unicode": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_filters_empty_paths": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_very_long_filename": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_with_empty_list": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_with_multiple_files": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_with_single_file": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tool_description_without_files": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tools_description_includes_filenames": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tools_metadata": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tools_returns_tool_without_parameters": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_get_tools_works_with_no_files": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_google_drive_temp_file_cleanup_on_download_failure": 0.036, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_output_has_tool_mode_true": 0.046, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_s3_temp_file_cleanup_on_download_failure": 0.034, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_tool_execution_handles_empty_file_list": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_tool_execution_handles_missing_file": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component.py::TestFileComponentToolMode::test_tool_execution_reads_uploaded_file": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDataFrameEmptyHandling::test_dataframe_with_empty_dict_is_empty": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDataFrameEmptyHandling::test_dataframe_with_empty_text_is_not_empty": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDataFrameEmptyHandling::test_dataframe_with_placeholder_data_is_not_empty": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingEmptyTextExtraction::test_load_files_dataframe_with_empty_text_image": 0.051, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingEmptyTextExtraction::test_load_files_markdown_with_empty_text_image": 0.033, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingEmptyTextExtraction::test_process_docling_empty_doc_rows_returns_placeholder": 0.046, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingEmptyTextExtraction::test_process_files_handles_empty_doc_rows": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingSubprocessErrors::test_docling_conversion_failure": 0.034, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingSubprocessErrors::test_docling_invalid_json_output": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestDoclingSubprocessErrors::test_docling_subprocess_crash": 0.033, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestFileNotFoundHandling::test_missing_file_raises_clear_error": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestFileNotFoundHandling::test_missing_file_silent_mode": 0.022, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_jpeg_saved_as_png_fails": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_non_image_file_passes": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_png_saved_as_jpg_fails": 14.252, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_process_files_rejects_mismatched_image": 20.29, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_process_files_silent_mode_skips_mismatched_image": 6.894, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_unrecognized_content_fails": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_valid_bmp_file": 14.398, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_valid_gif_file": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_valid_jpeg_file": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_valid_png_file": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageContentTypeValidation::test_valid_webp_file": 15.579, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_are_docling_compatible[bmp]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_are_docling_compatible[jpeg]": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_are_docling_compatible[jpg]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_are_docling_compatible[png]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_are_docling_compatible[tiff]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_are_docling_compatible[webp]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_require_advanced_mode[bmp]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_require_advanced_mode[jpeg]": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_require_advanced_mode[jpg]": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_require_advanced_mode[png]": 0.045, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_require_advanced_mode[tiff]": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestImageFileTypes::test_image_extensions_require_advanced_mode[webp]": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestLoadFilesHelperValidation::test_load_files_helper_empty_dataframe_raises_error": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestLoadFilesHelperValidation::test_load_files_helper_with_error_and_text": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestLoadFilesHelperValidation::test_load_files_helper_with_error_column": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestProcessFilesEdgeCases::test_process_files_docling_only_extension_without_advanced_mode": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestProcessFilesEdgeCases::test_process_files_empty_list_raises_error": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestStoragePathResolution::test_is_storage_path_format": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_file_component_image_processing.py::TestStoragePathResolution::test_validate_and_resolve_paths_uses_storage_service": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_column_metadata": 13.18, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_embedding_metadata": 11.081, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_embedding_metadata_without_api_key": 9.025, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_kb_info_no_metadata_file_raises_error": 8.85, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_kb_info_old_format_unrecognized_model": 0.636, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_kb_info_success": 12.9, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_kb_info_with_message_input": 12.714, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_build_kb_info_with_new_format_metadata": 1.431, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_convert_df_to_data_objects": 9.08, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_convert_df_to_data_objects_allow_duplicates": 12.36, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_convert_df_to_data_objects_no_duplicates": 12.897, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_convert_df_to_data_objects_with_array_cells": 2.465, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_get_knowledge_bases": 14.598, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_is_valid_collection_name": 11.322, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_new_knowledge_dialog_uses_provider_credentials": 8.381, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_scalar_notna_with_lists": 10.437, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_scalar_notna_with_numpy_arrays": 2.891, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_scalar_notna_with_scalar_values": 11.598, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_update_build_config_invalid_kb_name": 10.858, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_update_build_config_new_kb": 1.343, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_update_build_config_new_kb_persists_backend_selection": 11.218, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_update_metadata_metrics_empty_collection": 12.568, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_update_metadata_metrics_no_metadata_file": 12.308, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_update_metadata_metrics_persists_chunk_stats": 21.069, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_validate_column_config_invalid_column": 8.494, + "src/backend/tests/unit/components/files_and_knowledge/test_ingestion.py::TestKnowledgeIngestionComponent::test_validate_column_config_valid": 11.413, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestComponentSurface::test_create_kb_dialog_label_is_user_facing": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestComponentSurface::test_display_name_matches_starter_projects": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromDataFrame::test_extracts_from_mimetype_column": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromDataFrame::test_extracts_pdf_from_file_path_column": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromDataFrame::test_handles_missing_columns": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromDataFrame::test_handles_nan_rows_safely": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromDataFrame::test_ignores_non_extension_dotted_values": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extension_from_mimetype_string": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extension_from_path_string": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extension_returns_none_for_garbage": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extracts_from_data_object": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extracts_from_list_of_messages": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extracts_from_message_data_dict": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_extracts_from_plain_dict": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_returns_empty_for_none": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestExtractSourceTypesFromInput::test_returns_empty_for_text_only_message": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestKnowledgeComponentShape::test_default_keys_are_always_present": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestKnowledgeComponentShape::test_default_mode_is_ingest": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestKnowledgeComponentShape::test_mode_config_partition_covers_only_known_fields": 0.052, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestKnowledgeComponentShape::test_mode_input_exists_with_expected_options": 0.046, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestLegacySubclassesPinMode::test_ingestion_subclass_pins_ingest_mode": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestLegacySubclassesPinMode::test_retrieval_module_reexports_filter_helpers": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestLegacySubclassesPinMode::test_retrieval_subclass_pins_retrieve_mode": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestLegacySubclassesPinMode::test_subclasses_inherit_merged_inputs": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenInputVisibility::test_switching_to_ingest_hides_retrieve_fields": 0.035, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenInputVisibility::test_switching_to_retrieve_hides_ingest_fields": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenInputVisibility::test_unknown_mode_falls_back_to_ingest_visibility": 0.034, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenOutputSwap::test_class_level_declares_both_outputs_for_runtime_dispatch": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenOutputSwap::test_ingest_mode_replaces_output_with_ingest_result": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenOutputSwap::test_non_mode_field_change_leaves_outputs_untouched": 0.037, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestModeDrivenOutputSwap::test_retrieve_mode_replaces_output_with_retrieve_result": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestOutputHandleTypesMatchStarterEdges::test_ingest_output_type_is_json_only": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestOutputHandleTypesMatchStarterEdges::test_retrieve_output_type_is_table_only": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestOutputMethodModeDispatch::test_build_kb_info_delegates_to_retrieve_when_mode_is_retrieve": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestOutputMethodModeDispatch::test_is_retrieve_mode_matches_canonical_and_legacy_labels": 0.045, + "src/backend/tests/unit/components/files_and_knowledge/test_knowledge.py::TestOutputMethodModeDispatch::test_retrieve_data_delegates_to_ingest_when_mode_is_ingest": 0.039, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestBuildWhereClause::test_no_session_id_returns_none": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestBuildWhereClause::test_session_filter_falsy_value_disables_toggle": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestBuildWhereClause::test_session_filter_off_returns_none": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestBuildWhereClause::test_session_filter_on_returns_session_predicate": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestBuildWhereClause::test_session_filter_truthy_string_does_not_disable_toggle": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestCoerceUuid::test_invalid_returns_none": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestCoerceUuid::test_none_returns_none": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestCoerceUuid::test_string_coerced": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestCoerceUuid::test_unhashable_returns_none": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestCoerceUuid::test_uuid_passthrough": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestDistanceToSimilarity::test_flips_sign": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestLoadKbMetadata::test_decrypt_failure_sets_none": 0.038, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestLoadKbMetadata::test_decrypt_success": 0.03, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestLoadKbMetadata::test_invalid_json_returns_empty": 0.052, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestLoadKbMetadata::test_missing_file_returns_empty": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestLoadKbMetadata::test_no_api_key_skips_decrypt": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalBehavior::test_empty_search_query_returns_empty_dataframe_without_embedding": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalBehavior::test_include_metadata_false_drops_metadata_keys": 10.142, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalBehavior::test_include_metadata_true_merges_metadata": 12.85, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalBehavior::test_numpy_metadata_values_are_normalized": 4.082, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalBehavior::test_similarity_search_no_filter_when_disabled": 25.516, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalBehavior::test_similarity_search_uses_session_filter_when_enabled": 22.123, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_kb_path_traversal_raises": 0.049, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_mb_not_attached_to_flow_raises": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_missing_flow_id_raises": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_missing_metadata_raises": 0.045, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_missing_session_id_allowed_when_filter_disabled": 0.035, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_missing_session_id_raises_when_filter_enabled": 0.046, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_no_memory_base_selected_raises": 0.045, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestMemoryBaseRetrievalInvariants::test_owner_not_found_raises": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestRootPathCache::test_reset_cache_picks_up_new_setting": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestRootPathCache::test_unset_directory_raises": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToPythonScalar::test_arbitrary_object_passes_through": 0.053, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToPythonScalar::test_numpy_bool_becomes_python_bool": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToPythonScalar::test_numpy_float64_becomes_python_float": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToPythonScalar::test_numpy_int64_becomes_python_int": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToPythonScalar::test_python_scalar_passes_through": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToolSurface::test_description_mentions_cross_session": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToolSurface::test_filter_by_session_input_info_documents_off_state": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestToolSurface::test_output_info_advertises_cross_session": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestUpdateBuildConfig::test_missing_flow_id_clears_options": 0.043, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestUpdateBuildConfig::test_options_populated_and_stale_value_cleared": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_memory_retrieval.py::TestUpdateBuildConfig::test_other_field_returns_unchanged": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestEmbeddingMatchKey::test_falls_back_to_content_without_id": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestEmbeddingMatchKey::test_handles_missing_metadata": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestEmbeddingMatchKey::test_id_and_content_key_spaces_do_not_collide": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestEmbeddingMatchKey::test_prefers_id_when_present": 0.04, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_get_kb_metadata_corrupt_json_returns_empty": 12.456, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_get_kb_metadata_happy_path": 0.272, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_get_kb_metadata_missing_file_returns_empty": 13.687, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_get_knowledge_bases_db_first_hides_stale_disk_dirs": 1.011, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_get_knowledge_bases_skips_memory_base_associated_kbs": 19.552, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_get_knowledge_bases_utility": 11.588, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_include_embeddings_disabled_omits_embeddings": 9.318, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_include_embeddings_populates_for_upload_style_kb": 0.004, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_include_embeddings_populates_with_id_metadata": 12.075, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_accepts_list_shape": 11.743, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_falls_back_to_catalog_lookup": 12.621, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_hydrates_missing_embedding_class_from_catalog": 11.96, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_preserves_existing_metadata_over_catalog": 11.951, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_raises_on_empty_metadata": 10.581, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_raises_when_legacy_model_unavailable": 11.317, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_resolve_model_selection_uses_new_format": 11.914, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_missing_metadata_raises": 0.125, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_missing_user_id_raises": 13.475, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_missing_user_record_raises": 11.958, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_no_query_skips_scores": 12.062, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_passes_model_selection_to_unified_models": 12.946, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_routes_query_with_scores": 12.456, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_retrieve_data_tears_down_backend_on_error": 0.004, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_update_build_config_populates_options": 12.382, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestKnowledgeBaseComponent::test_update_build_config_resets_stale_selection": 11.922, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_chunk_match_array_value": 0.082, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_chunk_match_empty_filter_passes_through": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_chunk_match_missing_metadata_is_false": 0.044, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_chunk_match_requires_every_key": 0.084, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_parse_normalizes_scalar_to_list": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_parse_preserves_array_values": 0.041, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_parse_returns_empty_when_unset": 0.042, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_parse_swallows_invalid_json": 0.084, + "src/backend/tests/unit/components/files_and_knowledge/test_retrieval.py::TestMetadataFilterHelpers::test_parse_swallows_non_dict": 0.043, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_argument_overrides_attribute": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_case_insensitive_extension": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_csv_content": 0.048, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_empty_file_path_returns_empty": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_file_not_found_raises": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_json_content": 0.033, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_malformed_json_not_in_map": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_no_argument_no_attribute_returns_empty": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_no_files_available_raises": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_returns_dataframe_with_file_path_in_columns": 0.038, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_returns_existing_dataframe": 0.042, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_tsv_content": 0.038, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_unsupported_extension_raises": 0.043, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_as_dataframe_with_explicit_argument": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_caching": 0.043, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_data_only": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_dataframe_only": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_duplicate_paths_last_wins": 0.044, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_empty_input": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_mixed_with_and_without_paths": 0.042, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_build_file_map_unsupported_types_skipped": 0.042, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_file_maps_cached_across_calls": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_argument_overrides_attribute": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_basic": 0.045, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_data_without_file_path": 0.045, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_dataframe_without_source_path": 0.036, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_empty_path_returns_empty": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_file_not_found": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_message_without_file_path": 0.044, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_mixed_data_and_dataframe": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_mixed_message_data_dataframe": 0.048, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_no_argument_no_attribute_returns_empty": 0.044, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_unsupported_input_type": 0.045, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_with_dataframe_input": 0.037, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_with_explicit_argument": 0.042, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_retrieve_content_with_message_input": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_serialization_empty_dataframe_is_empty_list": 0.043, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_serialization_of_dataframe_result": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_serialization_of_message_result": 0.048, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_serialization_preserves_data_types": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_tool_invocation_pattern": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverComponent::test_tool_invocation_with_deepcopy": 0.051, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_no_persistent_dir_works_as_before": 0.09, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_persistent_adds_new_files": 0.116, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_persistent_auto_sync_does_not_wipe_on_empty_input": 0.043, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_persistent_auto_sync_removes_stale_entries": 0.082, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_persistent_handles_corrupted_json": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_persistent_save_and_load_roundtrip": 0.076, + "src/backend/tests/unit/components/files_ingestion/test_file_content_retriever.py::TestFileContentRetrieverPersistence::test_persistent_skips_existing_paths": 0.047, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_all_items_without_paths": 0.046, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_basic_success": 0.069, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_data_without_file_path": 1.065, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_dataframe_without_source_path": 0.04, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_duplicate_file_paths": 0.357, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_empty_file_data": 0.043, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_empty_json_array": 0.044, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_exception_propagation": 0.012, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_invalid_json_response": 0.113, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_llm_serialization_failure": 0.175, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_missing_file_path_key_in_output": 0.057, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_missing_text_key_in_output": 0.094, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_mixed_data_and_dataframe": 0.039, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_partial_success_raises": 0.052, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_path_normalization": 0.041, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_result_data_structure": 0.081, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_subprocess_failure": 0.046, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_subprocess_timeout": 0.338, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_unsupported_input_type": 0.121, + "src/backend/tests/unit/components/files_ingestion/test_file_description_generator.py::TestFileDescriptionGeneratorComponent::test_generate_descriptions_with_dataframe_input": 0.04, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_case_insensitive_operations": 0.081, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_component_initialization": 0.043, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello-Hello-equals-False-True]": 0.043, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello-Hello-equals-True-False]": 0.25, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello-hello-equals-True-True]": 0.123, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello-invalid[regex-regex-True-False]": 0.123, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello-world-equals-False-False]": 0.203, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello123-Hello\\\\d+-regex-False-False]": 0.164, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello123-Hello\\\\d+-regex-True-False]": 0.123, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition[hello123-hello\\\\d+-regex-True-True]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_evaluate_condition_unknown_operator": 0.042, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_false_response_blank_case_message_falls_back_to_input_text": 0.039, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_false_response_condition_false": 0.04, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_false_response_condition_true": 0.04, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_false_response_preserves_override_with_content_blocks": 0.081, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_inputs_configuration": 0.035, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_iterate_and_stop_once_already_updated": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_iterate_and_stop_once_initial_call": 0.04, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_iterate_and_stop_once_max_iterations_reached": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_numeric_comparison_edge_cases": 0.204, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_outputs_configuration": 0.04, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_pre_run_setup": 0.206, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_regex_error_handling": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_true_response_blank_case_message_falls_back_to_input_text": 0.04, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_true_response_condition_false": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_true_response_condition_true": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_true_response_preserves_override_with_files": 0.121, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_true_response_string_case_message_override": 0.086, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_update_build_config_non_operator_field": 0.163, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_update_build_config_non_regex_operator": 0.041, + "src/backend/tests/unit/components/flow_controls/test_conditional_router.py::TestConditionalRouterComponent::test_update_build_config_regex_operator": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_compare_values[hello-hello-equals-True]": 0.081, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_compare_values[hello-world-equals-False]": 0.081, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_compare_values_boolean_validator": 0.04, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_compare_values_unknown_operator": 0.043, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_component_initialization": 0.042, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_inputs_configuration": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_none_value_handling": 21.316, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_numeric_value_handling": 20.873, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_outputs_configuration": 0.122, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[-False]": 0.04, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[0-False0]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[0-False1]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[1-True0]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[1-True1]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[False-False0]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[False-False1]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[TRUE-True]": 0.046, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[True-True0]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[True-True1]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[false-False]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[hello-False]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[no-False]": 0.037, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[off-False]": 0.04, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[on-True]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[true-True]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[value16-False]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[value17-True]": 0.043, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[y-True]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_parse_boolean[yes-True]": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_empty_list": 10.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_list_input_invalid_items": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_list_input_mixed_results": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_list_input_no_matches": 16.75, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_single_invalid_input": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_single_valid_input_false": 0.042, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_data_single_valid_input_true": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_single_data_boolean_validator": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_single_data_comparison_false": 0.04, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_process_single_data_comparison_true": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_update_build_config_boolean_validator": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_update_build_config_non_boolean_validator": 7.939, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_update_build_config_non_operator_field": 0.042, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_validate_input_invalid_type": 0.041, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_validate_input_missing_key": 0.042, + "src/backend/tests/unit/components/flow_controls/test_data_conditional_router.py::TestDataConditionalRouterComponent::test_validate_input_valid_data": 0.041, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_build_tool_empty_flow_name": 6.734, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_build_tool_flow_not_found": 12.924, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_build_tool_no_flow_name": 11.227, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_component_inheritance": 13.16, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_component_initialization": 9.463, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_component_legacy_status": 5.899, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_field_order_configuration": 10.126, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_get_flow_empty_list": 2.82, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_get_flow_found": 11.815, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_get_flow_names": 11.568, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_get_flow_names_empty_list": 12.071, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_get_flow_names_handles_missing_name_field": 0.088, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_get_flow_not_found": 10.979, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_inputs_configuration": 11.737, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_outputs_configuration": 11.372, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_update_build_config_flow_name": 0.028, + "src/backend/tests/unit/components/flow_controls/test_flow_tool.py::TestFlowToolComponent::test_update_build_config_other_field": 2.118, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_component_beta_status": 0.039, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_component_inheritance": 0.042, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_component_initialization": 0.042, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_context_key_input_details": 0.04, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_empty_string_context_key": 0.043, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_inputs_configuration": 0.042, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_empty_context": 0.041, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_empty_data_objects[context_value0]": 10.154, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_empty_data_objects[context_value1]": 9.932, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_empty_data_objects[context_value2]": 5.992, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_key_does_not_exist": 0.04, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_key_exists": 0.041, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_method_signature": 0.042, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_multiple_context_keys": 0.042, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_none_context": 0.041, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_with_dash_key": 0.041, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_with_dict_data": 10.446, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_with_text_data": 0.041, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_listen_for_data_with_underscore_key": 0.039, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_output_method_mapping": 0.043, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_outputs_configuration": 0.042, + "src/backend/tests/unit/components/flow_controls/test_listen.py::TestListenComponent::test_whitespace_context_key": 12.902, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_component_has_subgraph_methods": 0.042, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_done_output_passes_event_manager": 0.039, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_event_manager_passed_to_subgraph": 0.037, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_extract_loop_output_with_empty_results": 0.042, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_start_vertex_without_vertex": 0.042, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_vertices_complex_loop": 0.04, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_vertices_no_end_vertex": 0.04, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_vertices_no_outgoing_edges": 0.04, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_vertices_simple_loop": 0.04, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_vertices_with_cycle": 0.039, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_get_loop_body_vertices_without_vertex": 0.043, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_loop_component_initialization": 0.04, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_validate_data_with_dataframe": 0.039, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_validate_data_with_invalid_input": 0.046, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_validate_data_with_list": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentSubgraphExecution::test_validate_data_with_single_data": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentWithAPI::test_build_flow_loop": 6.266, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentWithAPI::test_latest_version": 12.033, + "src/backend/tests/unit/components/flow_controls/test_loop.py::TestLoopComponentWithAPI::test_run_flow_loop": 7.209, + "src/backend/tests/unit/components/flow_controls/test_loop.py::test_loop_flow": 0.006, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_all_frozen_states_for_loop": 0.042, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_custom_loop_component_name_detected": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_frozen_loop_should_build": 0.039, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_frozen_non_loop_should_not_build": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_loop_component_detected_by_display_name": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_loop_component_detected_by_is_loop": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_non_frozen_loop_should_build": 0.042, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_non_frozen_non_loop_should_build": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestBuildVertexLoopException::test_non_loop_component_not_detected": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestEdgeCasesForLoopDetection::test_component_named_loop_but_is_loop_false": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestEdgeCasesForLoopDetection::test_empty_string_display_name": 0.046, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestEdgeCasesForLoopDetection::test_loop_with_unusual_display_name": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestEdgeCasesForLoopDetection::test_none_values_handled": 0.085, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestFrozenLoopScenarios::test_frozen_loop_first_execution_should_build": 0.13, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestFrozenLoopScenarios::test_frozen_loop_subsequent_iteration_should_build": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestFrozenLoopScenarios::test_frozen_non_loop_should_use_cache": 0.086, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestFrozenLoopScenarios::test_multiple_loop_components_all_detected": 0.087, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestLoopComponentOutputsConfig::test_loop_component_done_output_no_loop": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestLoopComponentOutputsConfig::test_loop_component_has_allows_loop_output": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestLoopEvaluateStopLoop::test_evaluate_stop_loop_logic": 0.043, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexBuildLoopException::test_all_frozen_built_states_for_vertex_build": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexBuildLoopException::test_frozen_built_loop_should_continue_build": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexBuildLoopException::test_frozen_built_non_loop_should_return_cached": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexBuildLoopException::test_frozen_not_built_loop_should_not_return_cached": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexBuildLoopException::test_not_frozen_loop_should_not_return_cached": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexIsLoopProperty::test_is_loop_handles_missing_allows_loop_key": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexIsLoopProperty::test_is_loop_returns_false_for_empty_outputs": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexIsLoopProperty::test_is_loop_returns_false_for_regular_component": 0.041, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexIsLoopProperty::test_is_loop_returns_true_for_loop_component": 0.042, + "src/backend/tests/unit/components/flow_controls/test_loop_freeze.py::TestVertexIsLoopProperty::test_is_loop_with_multiple_loop_outputs": 0.041, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_append_input_configuration": 0.04, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_component_beta_status": 0.043, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_component_inheritance": 0.039, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_component_initialization": 0.04, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_context_key_input_configuration": 0.041, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_input_value_input_configuration": 0.04, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_inputs_configuration": 0.042, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_notify_components_is_async": 0.081, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_notify_components_method_exists": 0.082, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_notify_components_no_vertex_raises_error": 0.044, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_output_method_mapping": 0.12, + "src/backend/tests/unit/components/flow_controls/test_notify_component.py::TestNotifyComponent::test_outputs_configuration": 0.082, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_component_inheritance": 0.041, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_component_initialization": 0.04, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_component_legacy_status": 0.042, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_ignored_message_truly_ignored": 0.042, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_inputs_configuration": 0.038, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_message_attributes_preservation": 0.04, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_output_method_mapping": 0.042, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_outputs_configuration": 0.044, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_basic_functionality": 0.039, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_different_message_types": 0.042, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_method_signature": 0.041, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_multiple_calls": 0.043, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_no_side_effects": 0.041, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_status_assignment": 0.041, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_with_ignored_message": 0.041, + "src/backend/tests/unit/components/flow_controls/test_pass_message.py::TestPassMessageComponent::test_pass_message_with_none_input": 19.873, + "src/backend/tests/unit/components/git/test_git_component.py::test_check_content_pattern": 3.817, + "src/backend/tests/unit/components/git/test_git_component.py::test_check_file_patterns": 8.629, + "src/backend/tests/unit/components/git/test_git_component.py::test_combined_filter": 27.274, + "src/backend/tests/unit/components/git/test_git_component.py::test_is_binary": 11.751, "src/backend/tests/unit/components/helpers/test_batch_run_component.py::TestBatchRunComponent::test_add_metadata_failure": 0.004369750999785538, "src/backend/tests/unit/components/helpers/test_batch_run_component.py::TestBatchRunComponent::test_add_metadata_success": 0.004423803999998199, "src/backend/tests/unit/components/helpers/test_batch_run_component.py::TestBatchRunComponent::test_all_versions_have_a_file_name_defined": 0.001901240999586662, @@ -553,14 +4688,14 @@ "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.0.17]": 4.332370791060384, "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.0.18]": 3.6762167080305517, "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.0.19]": 2.2135795410140418, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.1.0]": 2.246968833031133, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.1.1]": 2.218763584009139, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.1.0]": 0.001, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_component_versions[1.1.1]": 0.001, "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_latest_version": 1.9452624170226045, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response": 1.9526873330178205, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response_ai_sender": 1.970057792001171, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response_with_files": 3.12873616599245, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response_without_session": 1.9774919159826823, - "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_storage_disabled": 1.968287416966632, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response": 8.86, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response_ai_sender": 0.072, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response_with_files": 1.581, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_response_without_session": 12.978, + "src/backend/tests/unit/components/inputs/test_input_components.py::TestChatInput::test_message_storage_disabled": 0.021, "src/backend/tests/unit/components/inputs/test_input_components.py::TestTextInputComponent::test_all_versions_have_a_file_name_defined": 0.0025716660311445594, "src/backend/tests/unit/components/inputs/test_input_components.py::TestTextInputComponent::test_component_versions[1.0.17]": 0.26945149997482076, "src/backend/tests/unit/components/inputs/test_input_components.py::TestTextInputComponent::test_component_versions[1.0.18]": 0.28087970800697803, @@ -597,57 +4732,274 @@ "src/backend/tests/unit/components/languagemodels/test_baidu_qianfan.py::test_qianfan_different_models[XuanYuan-70B-Chat-4bit]": 0.0006859590066596866, "src/backend/tests/unit/components/languagemodels/test_baidu_qianfan.py::test_qianfan_different_models[Yi-34B-Chat]": 0.00032133300555869937, "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_all_versions_have_a_file_name_defined": 0.0005714159924536943, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model": 0.0019048750109504908, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_integration": 0.013954625988844782, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_missing_base_url": 0.0013083330122753978, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_data_output_with_dict": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_data_output_with_list_multiple_items": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_data_output_with_list_single_item": 0.047, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_data_output_with_primitive": 0.043, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_dataframe_output_with_empty_list": 0.04, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_dataframe_output_with_invalid_list": 0.038, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_dataframe_output_with_list_of_dicts": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_dataframe_output_with_primitive": 0.035, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_dataframe_output_with_single_dict": 0.038, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model": 0.04, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_cloud_with_v1_suffix_stripped": 0.04, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_integration": 0.029, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_local_no_headers": 0.05, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_missing_base_url": 0.046, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_no_transform_outside_container": 0.04, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_strips_v1_suffix_and_logs_warning": 0.028, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_strips_v1_trailing_slash": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_structured_output_toggle_behavior": 0.076, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_transforms_127_0_0_1_in_container": 0.053, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_transforms_localhost_in_docker_container": 0.035, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_transforms_localhost_in_podman_container": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_cloud_api_and_headers": 0.046, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_cloud_api_no_headers": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_complex_json_schema": 0.043, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_json_format_string": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_json_schema_dict": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_mirostat_2_enabled": 0.046, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_mirostat_enabled": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_pydantic_model_json_schema": 0.04, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_structured_output_disabled": 0.045, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_structured_output_enabled_dict_format": 0.077, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_structured_output_enabled_no_format": 0.038, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_build_model_with_structured_output_enabled_string_format": 0.039, "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_component_versions[1.0.19]": 0.0005165419715922326, "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_component_versions[1.1.0]": 0.000494084000820294, "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_component_versions[1.1.1]": 0.00047579201054759324, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_failure": 0.006945083994651213, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_success": 0.010135083022760227, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_base_url_cloud_no_transform": 0.046, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_failure": 0.034, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_local_no_headers": 0.028, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_missing_capabilities_with_tool_model": 0.03, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_missing_capabilities_without_tool_model": 0.037, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_mixed_capabilities_response": 0.037, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_success": 0.037, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_with_cloud_and_headers": 0.03, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_get_models_with_v1_suffix": 0.033, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_headers_with_cloud_url_and_api_key": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_headers_with_cloud_url_no_api_key": 0.05, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_headers_with_local_url_no_api_key": 0.05, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_is_valid_ollama_url_local_no_headers": 0.034, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_is_valid_ollama_url_with_cloud_and_headers": 0.034, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_is_valid_ollama_url_with_v1_suffix": 0.043, "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_latest_version": 0.004662041959818453, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_keep_alive": 0.0012813759967684746, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_mirostat_disabled": 0.001101000001654029, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_mirostat_enabled": 0.0010358320432715118, - "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_model_name": 0.03060733401798643, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_build_model[0.5-100]": 0.0011963750002905726, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_build_model[1.0-500]": 0.0009675409819465131, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_build_model[1.5-1000]": 0.0009197920153383166, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_error_handling": 0.0011858330108225346, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_get_models": 0.0009361669945064932, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_initialization": 0.0007854590367060155, - "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_template": 0.01080862499657087, - "src/backend/tests/unit/components/languagemodels/test_huggingface.py::test_huggingface_inputs": 0.0008037930529098958, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_parse_json_response_empty_response": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_parse_json_response_invalid_json": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_parse_json_response_valid_dict": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_parse_json_response_valid_list": 0.038, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_keep_alive": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_mirostat_disabled": 0.042, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_mirostat_enabled": 0.041, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_model_name": 0.053, + "src/backend/tests/unit/components/languagemodels/test_chatollama_component.py::TestChatOllamaComponent::test_update_build_config_no_error_when_ollama_not_running": 0.038, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_build_model[0.5-100]": 0.04, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_build_model[1.0-500]": 0.04, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_build_model[1.5-1000]": 0.04, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_error_handling": 0.083, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_get_models": 0.046, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_initialization": 0.042, + "src/backend/tests/unit/components/languagemodels/test_deepseek.py::test_deepseek_template": 0.05, + "src/backend/tests/unit/components/languagemodels/test_huggingface.py::test_huggingface_inputs": 0.125, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_build_model": 0.04, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_build_model_max_tokens_zero": 0.04, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_build_model_secret_str_api_key": 0.037, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_get_exception_message_auth_error": 0.084, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_get_exception_message_bad_request": 0.082, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_get_exception_message_no_openai_import": 0.083, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_get_exception_message_not_found": 0.083, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_get_exception_message_unknown_exception": 0.084, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_initialization": 0.041, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_inputs": 0.045, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_temperature_range_max_is_one": 0.044, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_validate_proxy_connection_auth_failure": 0.039, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_validate_proxy_connection_connect_error": 0.041, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_validate_proxy_connection_empty_models_list": 0.04, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_validate_proxy_connection_model_not_found": 0.04, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_validate_proxy_connection_success": 0.039, + "src/backend/tests/unit/components/languagemodels/test_litellm_proxy.py::TestLiteLLMProxyComponent::test_validate_proxy_connection_timeout": 0.04, "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_all_versions_have_a_file_name_defined": 0.0004984999832231551, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model": 0.002025251043960452, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_integration": 0.01272716699168086, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_integration_reasoning": 0.0013502920046448708, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_max_tokens_zero": 0.0017601660219952464, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_no_api_key": 0.0016860420000739396, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_reasoning_model": 0.0023898330109659582, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_with_json_mode": 0.001903833996038884, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model": 0.042, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_integration": 0.084, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_integration_reasoning": 0.158, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_max_tokens_zero": 0.043, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_no_api_key": 0.041, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_reasoning_model": 0.08, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_build_model_with_json_mode": 0.04, "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_component_versions[1.0.19]": 0.0004895839956589043, "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_component_versions[1.1.0]": 0.00047758303117007017, "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_component_versions[1.1.1]": 0.00044966701534576714, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_get_exception_message_bad_request_error": 0.0010025420051533729, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_get_exception_message_no_openai_import": 0.0021924999891780317, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_get_exception_message_other_exception": 0.0009440830035600811, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_get_exception_message_bad_request_error": 0.078, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_get_exception_message_no_openai_import": 0.039, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_get_exception_message_other_exception": 0.039, "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_latest_version": 0.003186875954270363, - "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_update_build_config_reasoning_model": 0.0008847920107655227, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_should_not_expose_fictional_gpt53_ids_in_openai_model_name_options": 0.055, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_should_return_helpful_message_when_openai_returns_model_not_found": 0.124, + "src/backend/tests/unit/components/languagemodels/test_openai_model.py::TestOpenAIModelComponent::test_update_build_config_reasoning_model": 0.053, + "src/backend/tests/unit/components/languagemodels/test_perplexity.py::TestPerplexityComponent::test_build_model": 0.122, + "src/backend/tests/unit/components/languagemodels/test_perplexity.py::TestPerplexityComponent::test_build_model_applies_defaults": 0.069, + "src/backend/tests/unit/components/languagemodels/test_perplexity.py::TestPerplexityComponent::test_initialization": 0.041, + "src/backend/tests/unit/components/languagemodels/test_perplexity.py::TestPerplexityComponent::test_inputs": 0.042, + "src/backend/tests/unit/components/languagemodels/test_perplexity.py::TestPerplexityComponent::test_template": 0.073, "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_all_versions_have_a_file_name_defined": 0.00048558300477452576, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_build_model": 0.0011021259997505695, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_build_model_error": 0.0012242929951753467, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_build_model": 0.086, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_build_model_error": 0.04, "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_component_versions[1.0.19]": 0.00046616699546575546, "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_component_versions[1.1.0]": 0.00044408300891518593, "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_component_versions[1.1.1]": 0.0004647089808713645, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_get_models": 0.0009869580098893493, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_get_models_no_api_key": 0.0007053340086713433, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_initialization": 0.0007046660175547004, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_inputs": 0.0007589170127175748, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_json_mode": 0.0015162500203587115, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_get_models": 0.04, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_get_models_no_api_key": 0.186, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_initialization": 0.044, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_inputs": 0.042, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_json_mode": 0.083, "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_latest_version": 0.0026592499925754964, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_template": 0.01161912499810569, - "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_update_build_config": 0.8106150010135025, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_template": 0.011, + "src/backend/tests/unit/components/languagemodels/test_xai.py::TestXAIComponent::test_update_build_config": 0.094, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_add_metadata_failure": 0.044, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_add_metadata_success": 0.043, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_batch_run_error_with_metadata": 0.047, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_batch_run_error_without_metadata": 0.04, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_batch_run_without_metadata": 0.035, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_create_base_row": 0.041, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_empty_dataframe": 0.046, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_invalid_column_name": 0.081, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_metadata_disabled": 0.128, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_non_string_column_conversion": 0.04, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_operational_error_with_metadata": 0.034, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_operational_error_without_metadata": 0.043, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_successful_batch_run_with_system_message": 0.033, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_update_build_config_hides_watsonx_fields_when_openai_selected": 0.035, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_update_build_config_shows_watsonx_fields_when_watsonx_selected": 0.078, + "src/backend/tests/unit/components/llm_operations/test_batch_run_component.py::TestBatchRunComponent::test_with_config_failure_handling": 0.075, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_custom_guardrail_ignored_when_empty": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_custom_guardrail_is_included_when_enabled": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_empty_input_raises_error": 0.043, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_extract_text_from_message_object": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_extract_text_from_none": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_extract_text_from_string": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_fail_fast_stops_on_first_failure": 0.028, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_fail_message_returns_empty_on_success": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_fail_message_returns_justification_on_failure": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_get_fixed_justification_returns_correct_message": 0.871, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_detects_act_as_as_weak_signal": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_detects_forget_instructions": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_detects_ignore_instructions": 0.039, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_detects_jailbreak_keyword": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_detects_system_prompt_as_weak_signal": 0.039, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_legitimate_act_as_usage": 0.042, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_legitimate_bypass_usage": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_multiple_weak_signals_accumulate": 0.045, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_passes_normal_input": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_heuristic_score_capped_at_one": 0.038, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_input_sanitizes_delimiter_injection": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_integration_clean_input_passes": 0.088, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_integration_custom_guardrail": 0.132, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_integration_jailbreak_detection": 0.165, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_integration_pii_detection": 0.17, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_integration_tokens_detection": 0.088, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_llm_api_error_detected": 0.052, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_llm_empty_response_raises_error": 0.851, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_no_guardrails_enabled_raises_error": 0.043, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_no_llm_configured_fails_validation": 0.901, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_no_outputs_are_hidden_by_default": 0.044, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_outputs_expose_message_and_data_paths": 0.043, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_parse_ambiguous_response_defaults_to_pass": 0.039, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_parse_no_response": 0.041, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_parse_yes_response": 0.042, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_pass_message_returns_empty_on_failure": 0.039, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_pass_message_returns_raw_text_on_success": 0.038, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_pre_run_setup_resets_state": 2.999, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_result_data_returns_fail_payload_on_failure": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_result_data_returns_pass_payload_on_success": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_validation_caches_result": 0.04, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_validation_fails_when_llm_detects_violation": 0.042, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_validation_passes_with_clean_input": 0.039, + "src/backend/tests/unit/components/llm_operations/test_guardrails_component.py::TestGuardrailsComponent::test_whitespace_only_input_raises_error": 0.042, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestBuildDataPrompt::test_should_include_full_data_when_data_is_small": 0.041, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestBuildDataPrompt::test_should_truncate_data_when_data_is_large": 0.167, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestBuildTextPrompt::test_should_include_full_text_when_text_is_small": 0.08, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestBuildTextPrompt::test_should_truncate_text_when_text_is_large": 0.039, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestComplexDataStructure::test_should_handle_nested_data_when_structure_is_complex": 0.076, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToData::test_should_convert_to_string_when_result_is_other_type": 0.123, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToData::test_should_wrap_dict_when_result_is_dict": 0.411, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToData::test_should_wrap_list_in_results_key_when_result_is_list": 0.042, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToDataframe::test_should_create_dataframe_when_result_is_list_of_dicts": 0.13, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToDataframe::test_should_create_single_row_when_result_is_dict": 0.081, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToDataframe::test_should_wrap_values_when_result_is_list_of_non_dicts": 0.04, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToMessage::test_should_format_json_when_result_is_dict": 0.09, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToMessage::test_should_join_items_when_result_is_list": 0.175, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestConvertResultToMessage::test_should_return_message_when_result_is_string": 0.18, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractMessageText::test_should_join_texts_when_input_is_list_of_messages": 0.081, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractMessageText::test_should_return_empty_string_when_message_text_is_none": 0.124, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractMessageText::test_should_return_single_text_when_list_has_one_message": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractMessageText::test_should_return_text_when_input_is_single_message": 0.128, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractStructuredData::test_should_combine_data_when_input_is_list_of_data": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractStructuredData::test_should_return_dict_when_input_is_single_data": 0.163, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractStructuredData::test_should_return_empty_dict_when_no_data_extracted": 0.205, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractStructuredData::test_should_return_records_when_input_is_dataframe": 0.039, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestExtractStructuredData::test_should_unwrap_single_dict_when_list_has_one_item": 0.248, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetDataStructure::test_should_return_dict_structure_when_input_is_dict": 0.041, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetDataStructure::test_should_return_empty_list_when_input_is_empty_list": 0.041, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetDataStructure::test_should_return_list_structure_when_input_is_list": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetDataStructure::test_should_return_nested_structure_when_input_is_nested": 0.164, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetDataStructure::test_should_return_type_name_when_input_is_primitive": 0.042, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetInputTypeName::test_should_return_data_when_input_is_data": 0.126, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetInputTypeName::test_should_return_dataframe_when_input_is_dataframe": 0.166, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetInputTypeName::test_should_return_message_when_input_is_list_of_messages": 0.042, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetInputTypeName::test_should_return_message_when_input_is_single_message": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestGetInputTypeName::test_should_return_unknown_when_input_is_empty_list": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestIsMessageInput::test_should_return_false_when_input_is_data": 0.042, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestIsMessageInput::test_should_return_false_when_input_is_empty_list": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestIsMessageInput::test_should_return_true_when_input_is_list_of_messages": 0.041, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestIsMessageInput::test_should_return_true_when_input_is_single_message": 0.082, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestLargeDataset::test_should_filter_large_dataset_when_data_exceeds_max_size": 0.078, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestProcessAsDataIntegration::test_should_raise_error_when_lambda_not_found_in_response": 0.133, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestProcessAsDataIntegration::test_should_return_filtered_data_when_lambda_is_valid": 0.239, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestProcessAsDataframeIntegration::test_should_return_dataframe_when_lambda_returns_list_of_dicts": 0.085, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestProcessAsMessageIntegration::test_should_join_multiple_messages_when_input_is_list_of_messages": 0.146, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestProcessAsMessageIntegration::test_should_transform_message_when_input_is_message": 0.193, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestValidateLambda::test_should_return_false_when_colon_missing": 0.04, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestValidateLambda::test_should_return_false_when_lambda_keyword_missing": 0.041, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestValidateLambda::test_should_return_true_when_lambda_has_whitespace": 0.08, + "src/backend/tests/unit/components/llm_operations/test_lambda_filter.py::TestValidateLambda::test_should_return_true_when_lambda_is_valid": 0.121, + "src/backend/tests/unit/components/llm_operations/test_llm_conditional_router.py::TestSmartRouterComponent::test_categorization_caching": 0.099, + "src/backend/tests/unit/components/llm_operations/test_llm_conditional_router.py::TestSmartRouterComponent::test_else_output": 0.143, + "src/backend/tests/unit/components/llm_operations/test_llm_conditional_router.py::TestSmartRouterComponent::test_negative_output": 0.083, + "src/backend/tests/unit/components/llm_operations/test_llm_conditional_router.py::TestSmartRouterComponent::test_neutral_output_no_match": 0.042, + "src/backend/tests/unit/components/llm_operations/test_llm_conditional_router.py::TestSmartRouterComponent::test_positive_output": 0.04, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_dataframe_fails_when_base_returns_non_list": 0.019, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_dataframe_fails_when_empty_output": 0.027, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_dataframe_returns_dataframe_with_multiple_data": 0.022, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_dataframe_returns_dataframe_with_single_data": 0.009, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_output_data_object_properties": 0.019, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_output_fails_when_base_returns_non_list": 0.039, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_output_returns_data_with_dict": 0.04, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_output_returns_data_with_single_item": 0.033, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_build_structured_output_returns_multiple_objects": 0.051, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_correctly_builds_output_model": 0.059, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_empty_output_schema": 0.81, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_fallback_both_methods_fail_raises_value_error": 0.061, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_fallback_error_message_includes_both_errors": 0.038, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_fallback_to_langchain_on_trustcall_generic_exception": 0.042, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_handles_multiple_outputs": 0.749, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_invalid_output_schema_type": 0.06, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_langchain_fallback_processes_basemodel_response": 0.036, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_langchain_fallback_processes_dict_response": 0.043, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_large_input_value": 1.38, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_multiple_patterns_with_duplicates_and_variations": 1.796, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_nested_output_schema": 1.018, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_raises_value_error_for_unsupported_language_model": 0.037, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_structured_output_handles_empty_responses_array": 0.034, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_structured_output_returns_dict_when_no_objects_key": 0.051, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_structured_output_returns_direct_response_when_not_dict": 0.042, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_successful_structured_output_generation_with_patch_with_config": 0.022, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_trustcall_success_no_fallback_attempted": 0.02, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_with_real_nvidia_model_simple_schema": 0.069, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_with_real_openai_model_complex_schema": 0.038, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_with_real_openai_model_multiple_patterns": 0.022, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_with_real_openai_model_nested_schema": 0.022, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_with_real_openai_model_simple_schema": 0.038, + "src/backend/tests/unit/components/llm_operations/test_structured_output_component.py::TestStructuredOutputComponent::test_with_real_openai_model_simple_schema_fail": 0.003, "src/backend/tests/unit/components/logic/test_loop.py::TestLoopComponentWithAPI::test_all_versions_have_a_file_name_defined": 1.953069500013953, "src/backend/tests/unit/components/logic/test_loop.py::TestLoopComponentWithAPI::test_build_flow_loop": 2.7657917499891482, "src/backend/tests/unit/components/logic/test_loop.py::TestLoopComponentWithAPI::test_component_versions[1.0.19]": 1.9741800840129144, @@ -656,6 +5008,33 @@ "src/backend/tests/unit/components/logic/test_loop.py::TestLoopComponentWithAPI::test_latest_version": 1.9571893329848535, "src/backend/tests/unit/components/logic/test_loop.py::TestLoopComponentWithAPI::test_run_flow_loop": 3.073773209034698, "src/backend/tests/unit/components/logic/test_loop.py::test_loop_flow": 1.617342416982865, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_check_and_update_stale_flow_does_nothing_when_current": 0.327, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_check_and_update_stale_flow_updates_when_stale": 0.044, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_get_selected_flow_meta_returns_metadata_field": 0.04, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_get_selected_flow_meta_returns_none_when_missing": 0.045, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_get_selected_flow_meta_returns_none_when_no_metadata": 0.044, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_load_graph_and_update_cfg_handles_datetime_object": 0.036, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_load_graph_and_update_cfg_loads_graph_and_updates_config": 0.039, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_should_update_stale_flow_returns_false_when_flow_is_current": 0.043, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_should_update_stale_flow_returns_false_when_no_metadata_updated_at": 0.041, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_should_update_stale_flow_returns_false_when_no_updated_at_in_flow": 0.041, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentHelperMethods::test_should_update_stale_flow_returns_true_when_flow_is_stale": 0.044, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentInitialization::test_component_has_correct_metadata": 0.041, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentInitialization::test_flow_tweak_data_is_isolated_per_instance": 0.039, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentInitialization::test_tool_added_flow_tweak_input_does_not_mutate_class_inputs": 0.039, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_run_flow_runtime_uses_selected_metadata_updated_at": 0.04, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_adds_missing_keys": 0.041, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_checks_stale_flow_during_refresh": 0.045, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_derives_flow_id_from_metadata": 0.041, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_does_not_refresh_without_conditions": 0.044, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_handles_error_gracefully": 0.009, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_handles_flow_id_selected_field": 0.042, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_refreshes_flow_list_with_none_value": 0.043, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_refreshes_with_is_refresh_flag": 0.043, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_returns_unchanged_for_other_fields": 0.045, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_updates_graph_on_flow_selection": 0.038, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_uses_existing_flow_id_when_no_metadata": 0.052, + "src/backend/tests/unit/components/logic/test_run_flow_component.py::TestRunFlowComponentUpdateBuildConfig::test_update_build_config_uses_get_selected_flow_meta": 0.035, "src/backend/tests/unit/components/models/test_ChatOllama_component.py::test_build_model": 0.0020211669616401196, "src/backend/tests/unit/components/models/test_ChatOllama_component.py::test_get_model_failure": 0.0068002091138623655, "src/backend/tests/unit/components/models/test_ChatOllama_component.py::test_get_model_success": 0.015780292043928057, @@ -752,17 +5131,498 @@ "src/backend/tests/unit/components/models/test_xai.py::TestXAIComponent::test_latest_version": 0.006742511999846101, "src/backend/tests/unit/components/models/test_xai.py::TestXAIComponent::test_template": 0.025210852999862254, "src/backend/tests/unit/components/models/test_xai.py::TestXAIComponent::test_update_build_config": 0.4465963840000313, + "src/backend/tests/unit/components/models_and_agents/policies/test_guarded_tool.py::test_guarded_tool_parse_input_string": 0.037, + "src/backend/tests/unit/components/models_and_agents/policies/test_guarded_tool.py::test_guarded_tool_parse_input_toolcall": 0.037, + "src/backend/tests/unit/components/models_and_agents/policies/test_guarded_tool.py::test_guarded_tool_policy_violation": 0.037, + "src/backend/tests/unit/components/models_and_agents/policies/test_guarded_tool.py::test_guarded_tool_run_not_implemented": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_guarded_tool.py::test_guarded_tool_successful_execution": 0.027, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestContentExtraction::test_extract_content_list": 0.043, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestContentExtraction::test_extract_content_mixed_list": 0.044, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestContentExtraction::test_extract_content_none": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestContentExtraction::test_extract_content_number": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestContentExtraction::test_extract_content_string": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestContentExtraction::test_extract_content_tuple": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_api_failure": 0.044, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_continuation_includes_previous_messages": 0.044, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_empty_response": 0.039, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_invalid_messages": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_max_continuations_exceeded": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_multiple_messages": 0.043, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_preserves_message_order": 0.045, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_simple_message": 0.039, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_with_max_tokens_reached": 0.039, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_with_none_content": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestGenerate::test_generate_with_tuple_content": 0.049, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestInitialization::test_init_preserves_existing_max_tokens": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestInitialization::test_init_sets_max_tokens": 0.039, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestInitialization::test_init_without_max_tokens_attribute": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestMessageValidation::test_validate_messages_item_not_dict": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestMessageValidation::test_validate_messages_missing_content": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestMessageValidation::test_validate_messages_missing_role": 0.039, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestMessageValidation::test_validate_messages_not_list": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestMessageValidation::test_validate_messages_valid": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestRoleConversion::test_convert_role_assistant_to_ai": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestRoleConversion::test_convert_role_system_to_system": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestRoleConversion::test_convert_role_unknown_defaults_to_system": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_llm_wrapper.py::TestRoleConversion::test_convert_role_user_to_human": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_cache_mode_corrupted_cache": 0.038, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_cache_mode_directory_not_found": 0.04, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_cache_mode_file_not_found": 0.035, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_cache_mode_success": 0.037, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_generate_mode_validation_errors": 0.037, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_in_recommended_models": 0.039, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_inenabled_returns_original_tools": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_to_snake_case": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_verify_cached_guards_error_messages": 0.037, + "src/backend/tests/unit/components/models_and_agents/policies/test_policies_component.py::test_work_dir_property": 0.047, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_primitive_type_conversion": 0.051, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_unknown_tool": 0.103, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_basemodel_in_value_dict": 0.082, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_basemodel_result": 0.043, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_basemodel_return_type": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_bool_return_type": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_call_tool_result": 0.038, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_complex_arguments": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_dict_result": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_empty_arguments": 0.094, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_float_return_type": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_int_return_type": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_str_return_type": 0.041, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_tool_message_artifact": 0.137, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_invoke_with_value_dict": 0.042, + "src/backend/tests/unit/components/models_and_agents/policies/test_tool_invoker.py::test_tool_invoker_multiple_tools": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_agent_filters_empty_chat_history_messages": 0.051, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_agent_handles_multimodal_message_input": 0.054, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_agent_max_tokens_with_provider_specific_field_name": 0.028, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_agent_passes_max_tokens_to_get_llm": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_agent_passes_none_max_tokens_when_not_set": 0.034, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_agent_receives_string_input_from_message_object": 0.043, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_get_agent_requirements_accepts_connected_model_instance": 0.036, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_get_agent_requirements_passes_watsonx_params": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_get_agent_requirements_supports_legacy_agent_llm_model_name": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_get_tool_description_backward_compat_shim": 9.912, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_get_tools_does_not_call_removed_api": 18.161, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_max_tokens_input_field_present": 0.058, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_accept_add_calculator_tool_in_default_keys": 0.034, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_append_calculator_tool_when_add_calculator_toggle_is_true": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_default_stream_input_value_to_true_when_agent_loaded": 0.051, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_expose_stream_input_when_agent_component_is_loaded": 0.027, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_expose_structured_response_output_when_class_loaded": 0.053, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_force_stream_true_to_get_llm_even_when_toggle_is_false": 0.045, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_have_placeholders_in_default_system_prompt": 0.066, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_inject_dynamic_values_into_system_prompt_when_message_response_runs": 0.024, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_keep_description_in_sync_when_agent_used_as_tool": 9.752, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_leave_literal_braces_untouched_when_prompt_has_no_known_placeholders": 0.06, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_not_append_calculator_tool_when_add_calculator_toggle_is_false": 0.03, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_not_emit_chat_message_when_json_response_uses_fallback": 0.034, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_not_mutate_format_instructions_when_json_response_runs": 0.048, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_pass_stream_value_to_get_llm_when_stream_input_is_enabled": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_propagate_description_change_when_agent_used_as_tool": 9.038, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_register_calculator_tool_only_once_when_external_calculator_connected_and_toggle_enabled": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_replace_current_date_and_model_name_when_both_placeholders_present": 0.052, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_restore_send_message_when_run_agent_raises_in_fallback": 0.054, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_should_return_empty_when_prompt_is_empty": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_update_build_config_does_not_require_deprecated_agent_description": 0.019, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_update_build_config_hides_watsonx_fields_for_other_providers": 0.024, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_update_build_config_shows_watsonx_fields": 0.028, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_watsonx_fields_hidden_by_default": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_agent_component.py::TestAgentComponent::test_watsonx_input_fields_present": 0.046, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_agent_streaming_no_text_accumulation": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_agent_streaming_preserves_message_id": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_agent_streaming_skips_empty_chunks": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_agent_streaming_without_event_manager": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_chain_end_event": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_chain_start_event": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_chain_stream_event": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_all_non_text_items": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_anthropic_style": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_backward_compatibility_scenarios": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_chatbedrockconverse_compatibility": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_chatbedrockconverse_index_only": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_chatbedrockconverse_index_with_extra_data": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_complex_chatbedrockconverse_response": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_edge_case_empty_text": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_edge_case_none_values": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_empty_list": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_empty_string": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_mixed_strings_and_dicts": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_multiple_items_mixed": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_multiple_strings": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_partial_json": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_realistic_streaming_scenario": 0.045, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_single_dict_multiple_keys_no_text": 0.043, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_single_dict_no_text_key": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_single_dict_with_text": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_single_string_in_list": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_string_input": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_extract_output_text_tool_use_type": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_end_empty_data": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_end_no_output": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_end_with_empty_return_values": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_end_with_output": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_start_no_input": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_start_with_input": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_stream_no_output": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_chain_stream_with_output": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_tool_end": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_tool_error": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_handle_on_tool_start": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_multiple_events": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_tool_end_event": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_tool_error_event": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_tool_start_event": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_events.py::test_unknown_event": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_case_sensitivity": 9.294, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_complex_graph": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_empty_sender_name": 0.043, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_first_match": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_found": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_graph_none": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_integration_fallback": 19.317, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_integration_with_agent": 9.686, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_missing_sender_name": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_no_chat_output": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_no_graph": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_no_vertices": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_none_sender_name": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_vertex_missing_data": 0.082, + "src/backend/tests/unit/components/models_and_agents/test_agent_utils.py::TestGetChatOutputSenderName::test_get_chat_output_sender_name_vertex_missing_raw_params": 9.265, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentComponentFramework::test_component_instantiation": 0.034, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentComponentFramework::test_component_tool_pipeline_configuration": 0.035, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentConfiguration::test_configure_tool_pipeline_both_disabled": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentConfiguration::test_configure_tool_pipeline_both_enabled": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentConfiguration::test_configure_tool_pipeline_reflection_only": 0.043, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentConfiguration::test_configure_tool_pipeline_validation_only": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKAgentRunnableType::test_should_return_lc_runnable_not_compiled_state_graph_when_creating_agent_runnable": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKBaseToolLogic::test_altk_base_tool_can_be_instantiated_with_valid_agent": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestALTKBaseToolLogic::test_execute_tool_logic_isolated": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationCombinations::test_response_processing_threshold_configuration": 0.087, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationCombinations::test_wrapper_count_for_configurations[False-False-0]": 0.126, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationCombinations::test_wrapper_count_for_configurations[False-True-1]": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationCombinations::test_wrapper_count_for_configurations[True-False-1]": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationCombinations::test_wrapper_count_for_configurations[True-True-2]": 0.078, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationValidation::test_agent_with_invalid_llm_type": 0.046, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationValidation::test_tool_pipeline_with_unavailable_wrappers": 0.051, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConfigurationValidation::test_wrapper_configuration_persistence": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_agent_configuration_integration": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_build_conversation_context": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_build_conversation_context_with_data_list": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_build_conversation_context_with_data_type": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_error_handling_in_tool_execution": 0.082, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_get_user_query_fallback_to_str": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextBuilding::test_get_user_query_with_get_text_method": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextOrdering::test_conversation_context_chronological_order": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextOrdering::test_message_to_dict_conversion_preserves_order": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextOrdering::test_multi_turn_conversation_context_order_bug": 0.031, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextOrdering::test_sparc_tool_wrapper_context_order": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestConversationContextOrdering::test_update_context_fixes_reversed_order": 0.046, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_altk_agent_handles_inconsistent_message_content": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_altk_base_tool_llm_extraction_edge_cases": 0.045, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_base_tool_wrapper_initialize_method": 0.047, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_chat_history_edge_cases": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_data_message_content_format_inconsistency": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_data_with_missing_required_keys": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_get_user_query_edge_cases": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_normalize_message_content_function": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_tool_pipeline_multiple_processing": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestEdgeCasesAndErrorHandling::test_tool_pipeline_with_wrapper_exception": 0.045, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestHelperFunctions::test_get_parent_agent_inputs": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestHelperFunctions::test_set_advanced_true": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolExecutionOrder::test_pipeline_manager_processes_in_reverse_order": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolExecutionOrder::test_wrapper_configuration_order": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolPipelineManager::test_add_wrapper": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolPipelineManager::test_clear_removes_all_wrappers": 0.045, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolPipelineManager::test_configure_wrappers_replaces_existing": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolPipelineManager::test_pipeline_manager_initialization": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestToolPipelineManager::test_process_tools_applies_wrappers_in_reverse_order": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestWrapperLogic::test_code_generation_component_mock_behavior": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestWrapperLogic::test_post_tool_processing_wrapper_configuration": 0.052, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestWrapperLogic::test_pre_tool_validation_wrapper_converts_tools": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_logic.py::TestWrapperLogic::test_sparc_component_mock_behavior": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_tool_conversion.py::test_basic_tool_conversion": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_tool_conversion.py::test_complex_schema_conversion": 0.032, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_tool_conversion.py::test_error_handling": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_tool_conversion.py::test_multiple_tools_conversion": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_tool_conversion.py::test_no_param_tool_conversion": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_altk_agent_tool_conversion.py::test_tool_with_list_parameter": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_conversation_context_ordering.py::TestALTKAgentContextOrdering::test_conversation_context_chronological_order": 0.104, + "src/backend/tests/unit/components/models_and_agents/test_conversation_context_ordering.py::TestALTKAgentContextOrdering::test_conversation_context_empty_history": 0.146, + "src/backend/tests/unit/components/models_and_agents/test_conversation_context_ordering.py::TestALTKAgentContextOrdering::test_conversation_context_multi_turn_regression": 0.095, + "src/backend/tests/unit/components/models_and_agents/test_conversation_context_ordering.py::TestALTKAgentContextOrdering::test_conversation_context_no_current_input": 0.054, + "src/backend/tests/unit/components/models_and_agents/test_conversation_context_ordering.py::TestALTKAgentContextOrdering::test_conversation_context_single_turn": 0.125, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_advanced_fields_configuration": 18.463, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_browser_configuration": 9.594, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_build_config_update": 11.574, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_cuga_component_initialization": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_decomposition_strategy_field": 0.03, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_frontend_node_structure": 10.158, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_memory_inputs_advanced_setting": 0.053, + "src/backend/tests/unit/components/models_and_agents/test_cuga_agent.py::TestCugaComponent::test_new_input_fields_present": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_google": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_invalid_model_format": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_openai": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_openai_missing_api_key": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_passes_all_optional_params": 0.038, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_passes_watsonx_params": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_embedding_model_component.py::TestEmbeddingModelComponent::test_build_embeddings_unknown_embedding_class": 0.037, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgent::test_bind_tools_called_with_auto": 0.043, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgent::test_bind_tools_called_with_required": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgent::test_creates_agent_with_valid_inputs": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgent::test_custom_forced_iterations": 0.046, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgent::test_empty_tools_list": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgent::test_raises_error_without_bind_tools": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgentDynamicInvoke::test_placeholder_detection_triggers_corrective_message": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgentDynamicInvoke::test_uses_auto_after_forced_iterations": 0.039, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestCreateGraniteAgentDynamicInvoke::test_uses_required_for_first_iteration": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_args_as_string": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_case_insensitive_detection": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_current_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_extracted_date_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_output_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_previous_value_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_response_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_result_from_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_search_result_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_detects_tool_result_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_empty_tool_calls": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_html_tags_not_detected": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_multiple_tool_calls_first_has_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_multiple_tool_calls_second_has_placeholder": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_nested_args_with_placeholder": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_no_placeholder_returns_false": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_none_tool_calls": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_normal_angle_brackets_not_detected": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_tool_call_without_args": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestDetectPlaceholderInArgs::test_tool_call_without_name": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_create_granite_agent_with_none_tools": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_detect_placeholder_with_special_characters": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_empty_args_dict": 0.085, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_get_enhanced_system_prompt_preserves_base": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_is_granite_model_with_integer_model_id": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_is_granite_with_watsonx_model_id": 0.085, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_placeholder_in_list_value": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestEdgeCases::test_placeholder_in_numeric_value": 0.087, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_empty_base_prompt": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_enhancement_contains_key_instructions": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_enhancement_with_two_tools": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_enhances_prompt_with_multiple_tools": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_no_enhancement_with_empty_tools": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_no_enhancement_with_none_tools": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_no_enhancement_with_single_tool": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestGetEnhancedSystemPrompt::test_tool_names_listed": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_case_insensitive": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_empty_model_id": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_fallback_to_model_name": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_mixed_case": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_no_attributes": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_none_model_id": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_not_granite": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_openai": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_partial_match": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_with_model_id_granite": 0.042, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsGraniteModel::test_is_granite_model_with_model_name_granite": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_case_insensitive_class_name": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_case_insensitive_module_name": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_detects_by_module_langchain_ibm": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_detects_by_module_watsonx": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_detects_chatwatsonx_class": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_detects_llama_on_watsonx": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_detects_mistral_on_watsonx": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_detects_watsonx_in_class_name": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_returns_false_for_anthropic": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_returns_false_for_openai": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestIsWatsonxModel::test_works_with_real_mock_structure": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_pattern_extracts_full_placeholder": 0.044, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_pattern_finds_multiple_placeholders": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[-False]": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[<123>-False]": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[<>-False]": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[-True]": 0.041, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[-True]": 0.04, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[-False]": 0.082, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[-False]": 0.082, + "src/backend/tests/unit/components/models_and_agents/test_ibm_granite_handler.py::TestPlaceholderPattern::test_placeholder_pattern_matching[