Merge branch 'dev' into uiImprovements
This commit is contained in:
commit
e2c8dfab2f
21 changed files with 598 additions and 564 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
from langflow.interface.loading import load_flow_from_json
|
|
||||||
from langflow.cache import cache_manager
|
from langflow.cache import cache_manager
|
||||||
|
from langflow.interface.loading import load_flow_from_json
|
||||||
|
|
||||||
__all__ = ["load_flow_from_json", "cache_manager"]
|
__all__ = ["load_flow_from_json", "cache_manager"]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from langchain.callbacks.base import AsyncCallbackHandler
|
from langchain.callbacks.base import AsyncCallbackHandler
|
||||||
|
|
||||||
from langflow.api.schemas import ChatResponse
|
from langflow.api.schemas import ChatResponse
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import Dict, List
|
|
||||||
from collections import defaultdict
|
|
||||||
from fastapi import WebSocket
|
|
||||||
import json
|
import json
|
||||||
|
from collections import defaultdict
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
from fastapi import WebSocket
|
||||||
|
|
||||||
from langflow.api.schemas import ChatMessage, ChatResponse, FileResponse
|
from langflow.api.schemas import ChatMessage, ChatResponse, FileResponse
|
||||||
|
from langflow.cache import cache_manager
|
||||||
from langflow.cache.manager import Subject
|
from langflow.cache.manager import Subject
|
||||||
from langflow.interface.run import (
|
from langflow.interface.run import (
|
||||||
get_result_and_steps,
|
get_result_and_steps,
|
||||||
|
|
@ -11,7 +14,6 @@ from langflow.interface.run import (
|
||||||
)
|
)
|
||||||
from langflow.interface.utils import pil_to_base64, try_setting_streaming_options
|
from langflow.interface.utils import pil_to_base64, try_setting_streaming_options
|
||||||
from langflow.utils.logger import logger
|
from langflow.utils.logger import logger
|
||||||
from langflow.cache import cache_manager
|
|
||||||
|
|
||||||
|
|
||||||
class ChatHistory(Subject):
|
class ChatHistory(Subject):
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Any, Union
|
from typing import Any, Union
|
||||||
|
|
||||||
from pydantic import BaseModel, validator
|
from pydantic import BaseModel, validator
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
2
src/backend/langflow/cache/base.py
vendored
2
src/backend/langflow/cache/base.py
vendored
|
|
@ -2,13 +2,13 @@ import base64
|
||||||
import contextlib
|
import contextlib
|
||||||
import functools
|
import functools
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
import dill # type: ignore
|
import dill # type: ignore
|
||||||
|
|
||||||
CACHE: Dict[str, Any] = {}
|
CACHE: Dict[str, Any] = {}
|
||||||
|
|
|
||||||
3
src/backend/langflow/cache/manager.py
vendored
3
src/backend/langflow/cache/manager.py
vendored
|
|
@ -1,7 +1,8 @@
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from typing import Any, Awaitable, Callable, List, Optional
|
from typing import Any, Awaitable, Callable, List, Optional
|
||||||
from PIL import Image
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
class Subject:
|
class Subject:
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ from langchain.agents.agent_toolkits.vectorstore.prompt import (
|
||||||
)
|
)
|
||||||
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
|
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
|
||||||
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS as SQL_FORMAT_INSTRUCTIONS
|
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS as SQL_FORMAT_INSTRUCTIONS
|
||||||
|
from langchain.base_language import BaseLanguageModel
|
||||||
from langchain.llms.base import BaseLLM
|
from langchain.llms.base import BaseLLM
|
||||||
from langchain.memory.chat_memory import BaseChatMemory
|
from langchain.memory.chat_memory import BaseChatMemory
|
||||||
from langchain.base_language import BaseLanguageModel
|
|
||||||
from langchain.sql_database import SQLDatabase
|
from langchain.sql_database import SQLDatabase
|
||||||
from langchain.tools.python.tool import PythonAstREPLTool
|
from langchain.tools.python.tool import PythonAstREPLTool
|
||||||
from langchain.tools.sql_database.prompt import QUERY_CHECKER
|
from langchain.tools.sql_database.prompt import QUERY_CHECKER
|
||||||
|
|
@ -51,7 +51,7 @@ class JsonAgent(AgentExecutor):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_toolkit_and_llm(cls, toolkit: JsonToolkit, llm: BaseLanguageModel):
|
def from_toolkit_and_llm(cls, toolkit: JsonToolkit, llm: BaseLanguageModel):
|
||||||
tools = toolkit.get_tools()
|
tools = toolkit.get_tools()
|
||||||
tool_names = [tool.name for tool in tools]
|
tool_names = {tool.name for tool in tools}
|
||||||
prompt = ZeroShotAgent.create_prompt(
|
prompt = ZeroShotAgent.create_prompt(
|
||||||
tools,
|
tools,
|
||||||
prefix=JSON_PREFIX,
|
prefix=JSON_PREFIX,
|
||||||
|
|
@ -109,7 +109,7 @@ class CSVAgent(AgentExecutor):
|
||||||
llm=llm,
|
llm=llm,
|
||||||
prompt=partial_prompt,
|
prompt=partial_prompt,
|
||||||
)
|
)
|
||||||
tool_names = [tool.name for tool in tools]
|
tool_names = {tool.name for tool in tools}
|
||||||
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
||||||
|
|
||||||
return cls.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
|
return cls.from_agent_and_tools(agent=agent, tools=tools, verbose=True)
|
||||||
|
|
@ -146,7 +146,7 @@ class VectorStoreAgent(AgentExecutor):
|
||||||
llm=llm,
|
llm=llm,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
)
|
)
|
||||||
tool_names = [tool.name for tool in tools]
|
tool_names = {tool.name for tool in tools}
|
||||||
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
||||||
return AgentExecutor.from_agent_and_tools(
|
return AgentExecutor.from_agent_and_tools(
|
||||||
agent=agent, tools=tools, verbose=True
|
agent=agent, tools=tools, verbose=True
|
||||||
|
|
@ -212,7 +212,7 @@ class SQLAgent(AgentExecutor):
|
||||||
llm=llm,
|
llm=llm,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
)
|
)
|
||||||
tool_names = [tool.name for tool in tools] # type: ignore
|
tool_names = {tool.name for tool in tools} # type: ignore
|
||||||
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
||||||
return AgentExecutor.from_agent_and_tools(
|
return AgentExecutor.from_agent_and_tools(
|
||||||
agent=agent,
|
agent=agent,
|
||||||
|
|
@ -255,7 +255,7 @@ class VectorStoreRouterAgent(AgentExecutor):
|
||||||
llm=llm,
|
llm=llm,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
)
|
)
|
||||||
tool_names = [tool.name for tool in tools]
|
tool_names = {tool.name for tool in tools}
|
||||||
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names, **kwargs)
|
||||||
return AgentExecutor.from_agent_and_tools(
|
return AgentExecutor.from_agent_and_tools(
|
||||||
agent=agent, tools=tools, verbose=True
|
agent=agent, tools=tools, verbose=True
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class MalfoyAgent(AgentExecutor):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_toolkit_and_llm(cls, toolkit: JsonToolkit, llm: BaseLanguageModel):
|
def from_toolkit_and_llm(cls, toolkit: JsonToolkit, llm: BaseLanguageModel):
|
||||||
tools = toolkit.get_tools()
|
tools = toolkit.get_tools()
|
||||||
tool_names = [tool.name for tool in tools]
|
tool_names = {tool.name for tool in tools}
|
||||||
prompt = ZeroShotAgent.create_prompt(
|
prompt = ZeroShotAgent.create_prompt(
|
||||||
tools,
|
tools,
|
||||||
prefix=JSON_PREFIX,
|
prefix=JSON_PREFIX,
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from langchain.callbacks.base import BaseCallbackManager
|
||||||
from langchain.chains.loading import load_chain_from_config
|
from langchain.chains.loading import load_chain_from_config
|
||||||
from langchain.llms.base import BaseLLM
|
from langchain.llms.base import BaseLLM
|
||||||
from langchain.llms.loading import load_llm_from_config
|
from langchain.llms.loading import load_llm_from_config
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from langflow.interface.agents.custom import CUSTOM_AGENTS
|
from langflow.interface.agents.custom import CUSTOM_AGENTS
|
||||||
from langflow.interface.importing.utils import import_by_type
|
from langflow.interface.importing.utils import import_by_type
|
||||||
|
|
@ -25,7 +26,6 @@ from langflow.interface.toolkits.base import toolkits_creator
|
||||||
from langflow.interface.types import get_type_list
|
from langflow.interface.types import get_type_list
|
||||||
from langflow.interface.utils import load_file_into_dict
|
from langflow.interface.utils import load_file_into_dict
|
||||||
from langflow.utils import util, validate
|
from langflow.utils import util, validate
|
||||||
from pydantic import ValidationError
|
|
||||||
|
|
||||||
|
|
||||||
def instantiate_class(node_type: str, base_type: str, params: Dict) -> Any:
|
def instantiate_class(node_type: str, base_type: str, params: Dict) -> Any:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import io
|
import io
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from chromadb.errors import NotEnoughElementsException # type: ignore
|
from chromadb.errors import NotEnoughElementsException # type: ignore
|
||||||
|
|
||||||
from langflow.cache.base import compute_dict_hash, load_cache, memoize_dict
|
from langflow.cache.base import compute_dict_hash, load_cache, memoize_dict
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
import base64
|
import base64
|
||||||
from io import BytesIO
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from PIL.Image import Image
|
from io import BytesIO
|
||||||
|
|
||||||
|
import yaml
|
||||||
from langchain.callbacks.manager import AsyncCallbackManager
|
from langchain.callbacks.manager import AsyncCallbackManager
|
||||||
from langchain.chat_models import AzureChatOpenAI, ChatOpenAI
|
from langchain.chat_models import AzureChatOpenAI, ChatOpenAI
|
||||||
from langchain.llms import AzureOpenAI, OpenAI
|
from langchain.llms import AzureOpenAI, OpenAI
|
||||||
from langflow.api.callback import StreamingLLMCallbackHandler
|
from PIL.Image import Image
|
||||||
|
|
||||||
import yaml
|
from langflow.api.callback import StreamingLLMCallbackHandler
|
||||||
|
|
||||||
|
|
||||||
def load_file_into_dict(file_path: str) -> dict:
|
def load_file_into_dict(file_path: str) -> dict:
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
from langflow.api.chat import router as chat_router
|
||||||
from langflow.api.endpoints import router as endpoints_router
|
from langflow.api.endpoints import router as endpoints_router
|
||||||
from langflow.api.validate import router as validate_router
|
from langflow.api.validate import router as validate_router
|
||||||
from langflow.api.chat import router as chat_router
|
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
|
|
|
||||||
|
|
@ -162,14 +162,23 @@ class FrontendNode(BaseModel):
|
||||||
_type = _type.replace("Optional[", "")[:-1]
|
_type = _type.replace("Optional[", "")[:-1]
|
||||||
|
|
||||||
# Check for list type
|
# Check for list type
|
||||||
if "List" in _type:
|
if "List" in _type or "Sequence" in _type:
|
||||||
_type = _type.replace("List[", "")[:-1]
|
_type = _type.replace("List[", "")
|
||||||
|
_type = _type.replace("Sequence[", "")[:-1]
|
||||||
field.is_list = True
|
field.is_list = True
|
||||||
|
|
||||||
# Replace 'Mapping' with 'dict'
|
# Replace 'Mapping' with 'dict'
|
||||||
if "Mapping" in _type:
|
if "Mapping" in _type:
|
||||||
_type = _type.replace("Mapping", "dict")
|
_type = _type.replace("Mapping", "dict")
|
||||||
|
|
||||||
|
# {'type': 'Union[float, Tuple[float, float], NoneType]'} != {'type': 'float'}
|
||||||
|
if "Union" in _type:
|
||||||
|
_type = _type.replace("Union[", "")[:-1]
|
||||||
|
_type = _type.split(",")[0]
|
||||||
|
_type = _type.replace("]", "").replace("[", "")
|
||||||
|
|
||||||
|
field.field_type = _type
|
||||||
|
|
||||||
# Change type from str to Tool
|
# Change type from str to Tool
|
||||||
field.field_type = "Tool" if key in {"allowed_tools"} else field.field_type
|
field.field_type = "Tool" if key in {"allowed_tools"} else field.field_type
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
from functools import wraps
|
|
||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
|
from functools import wraps
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from docstring_parser import parse # type: ignore
|
from docstring_parser import parse # type: ignore
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import {
|
||||||
} from "react";
|
} from "react";
|
||||||
import { FlowType } from "../types/flow";
|
import { FlowType } from "../types/flow";
|
||||||
import { LangFlowState, TabsContextType } from "../types/tabs";
|
import { LangFlowState, TabsContextType } from "../types/tabs";
|
||||||
import { normalCaseToSnakeCase, updateObject } from "../utils";
|
import { normalCaseToSnakeCase, updateObject, updateTemplate } from "../utils";
|
||||||
import { alertContext } from "./alertContext";
|
import { alertContext } from "./alertContext";
|
||||||
import { typesContext } from "./typesContext";
|
import { typesContext } from "./typesContext";
|
||||||
import { TemplateVariableType } from "../types/api";
|
import { APITemplateType, TemplateVariableType } from "../types/api";
|
||||||
const { v4: uuidv4 } = require("uuid");
|
const { v4: uuidv4 } = require("uuid");
|
||||||
|
|
||||||
const TabsContextInitialValue: TabsContextType = {
|
const TabsContextInitialValue: TabsContextType = {
|
||||||
|
|
@ -64,12 +64,12 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
cookieObject.flows.forEach((flow) => {
|
cookieObject.flows.forEach((flow) => {
|
||||||
flow.data.nodes.forEach((node) => {
|
flow.data.nodes.forEach((node) => {
|
||||||
if (Object.keys(templates[node.data.type]["template"]).length > 0) {
|
if (Object.keys(templates[node.data.type]["template"]).length > 0) {
|
||||||
node.data.node.template = updateObject(
|
node.data.node.template = updateTemplate(
|
||||||
templates[node.data.type][
|
templates[node.data.type][
|
||||||
"template"
|
"template"
|
||||||
] as unknown as TemplateVariableType,
|
] as unknown as APITemplateType,
|
||||||
|
|
||||||
node.data.node.template as TemplateVariableType
|
node.data.node.template as APITemplateType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -127,16 +127,6 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
file.text().then((text) => {
|
file.text().then((text) => {
|
||||||
// parse the text into a JSON object
|
// parse the text into a JSON object
|
||||||
let flow: FlowType = JSON.parse(text);
|
let flow: FlowType = JSON.parse(text);
|
||||||
flow.data.nodes.forEach((node) => {
|
|
||||||
if (Object.keys(templates[node.data.type]["template"]).length > 0) {
|
|
||||||
node.data.node.template = updateObject(
|
|
||||||
templates[node.data.type][
|
|
||||||
"template"
|
|
||||||
] as unknown as TemplateVariableType,
|
|
||||||
node.data.node.template as TemplateVariableType
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addFlow(flow);
|
addFlow(flow);
|
||||||
});
|
});
|
||||||
|
|
@ -176,6 +166,16 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
||||||
const data = flow?.data ? flow.data : null;
|
const data = flow?.data ? flow.data : null;
|
||||||
const description = flow?.description ? flow.description : "";
|
const description = flow?.description ? flow.description : "";
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
data.nodes.forEach((node) => {
|
||||||
|
if (Object.keys(templates[node.data.type]["template"]).length > 0) {
|
||||||
|
node.data.node.template = updateTemplate(
|
||||||
|
templates[node.data.type]["template"] as unknown as APITemplateType,
|
||||||
|
node.data.node.template as APITemplateType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
// Create a new flow with a default name if no flow is provided.
|
// Create a new flow with a default name if no flow is provided.
|
||||||
let newFlow: FlowType = {
|
let newFlow: FlowType = {
|
||||||
description,
|
description,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import {
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
import { Connection, Edge, Node, ReactFlowInstance } from "reactflow";
|
import { Connection, Edge, Node, ReactFlowInstance } from "reactflow";
|
||||||
import { FlowType } from "./types/flow";
|
import { FlowType } from "./types/flow";
|
||||||
|
import { APITemplateType, TemplateVariableType } from "./types/api";
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
export function classNames(...classes: Array<string>) {
|
export function classNames(...classes: Array<string>) {
|
||||||
|
|
@ -437,3 +438,19 @@ export function debounce(func, wait) {
|
||||||
timeout = setTimeout(() => func.apply(context, args), wait);
|
timeout = setTimeout(() => func.apply(context, args), wait);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateTemplate(
|
||||||
|
reference: APITemplateType,
|
||||||
|
objectToUpdate: APITemplateType
|
||||||
|
): APITemplateType {
|
||||||
|
let clonedObject:APITemplateType = _.cloneDeep(reference);
|
||||||
|
|
||||||
|
// Loop through each key in the reference object
|
||||||
|
for (const key in clonedObject) {
|
||||||
|
// If the key is not in the object to update, add it
|
||||||
|
if (objectToUpdate[key] && objectToUpdate[key].value) {
|
||||||
|
clonedObject[key].value = objectToUpdate[key].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clonedObject;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import AsyncGenerator
|
from typing import AsyncGenerator
|
||||||
from httpx import AsyncClient
|
|
||||||
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
from httpx import AsyncClient
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure():
|
def pytest_configure():
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ def test_zero_shot_agent(client: TestClient):
|
||||||
"type": "Tool",
|
"type": "Tool",
|
||||||
"list": True,
|
"list": True,
|
||||||
"advanced": False,
|
"advanced": False,
|
||||||
|
"value": [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import pytest
|
|
||||||
from PIL import Image
|
|
||||||
import pandas as pd
|
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import pytest
|
||||||
from langflow.cache.manager import CacheManager
|
from langflow.cache.manager import CacheManager
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ def test_openai(client: TestClient):
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
"password": False,
|
"password": False,
|
||||||
"name": "request_timeout",
|
"name": "request_timeout",
|
||||||
"type": "Union[float, Tuple[float, float], NoneType]",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
"advanced": False,
|
"advanced": False,
|
||||||
}
|
}
|
||||||
|
|
@ -418,10 +418,9 @@ def test_chat_open_ai(client: TestClient):
|
||||||
"placeholder": "",
|
"placeholder": "",
|
||||||
"show": False,
|
"show": False,
|
||||||
"multiline": False,
|
"multiline": False,
|
||||||
"value": 60,
|
|
||||||
"password": False,
|
"password": False,
|
||||||
"name": "request_timeout",
|
"name": "request_timeout",
|
||||||
"type": "int",
|
"type": "float",
|
||||||
"list": False,
|
"list": False,
|
||||||
"advanced": False,
|
"advanced": False,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import json
|
import json
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue