Merge remote-tracking branch 'origin/dev' into two_edges

This commit is contained in:
ogabrielluiz 2024-06-11 09:52:41 -03:00
commit 0014d8e50a
16 changed files with 182 additions and 31 deletions

View file

@ -107,7 +107,7 @@ def read_text_file(file_path: str) -> str:
result = chardet.detect(raw_data)
encoding = result["encoding"]
if encoding in ["Windows-1252", "Windows-1254"]:
if encoding in ["Windows-1252", "Windows-1254", "MacRoman"]:
encoding = "utf-8"
with open(file_path, "r", encoding=encoding) as f:

View file

@ -0,0 +1,91 @@
from typing import Any, Dict, List, Callable
import ast
from langchain.agents import Tool
from langchain.tools import StructuredTool
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema.dotdict import dotdict
from langchain.pydantic_v1 import BaseModel, Field
class PythonCodeStructuredTool(CustomComponent):
display_name = "PythonCodeTool"
description = "structuredtool dataclass code to tool"
documentation = "https://python.langchain.com/docs/modules/tools/custom_tools/#structuredtool-dataclass"
icon = "🐍"
field_order = ["name", "description", "tool_code",
"return_direct", "tool_function", "tool_class"]
def build_config(self) -> Dict[str, Any]:
return {
"tool_code": {
"display_name": "Tool Code",
"info": "Enter the dataclass code.",
"placeholder": "def my_function(args):\n pass",
"multiline": True,
"refresh_button": True,
},
"name": {
"display_name": "Tool Name",
"info": "Enter the name of the tool.",
},
"description": {
"display_name": "Description",
"info": "Provide a brief description of what the tool does.",
},
"return_direct": {
"display_name": "Return Directly",
"info": "Should the tool return the function output directly?",
},
"tool_function": {
"display_name": "Tool Function",
"info": "Select the function for additional expressions.",
"options": [],
"refresh_button": True,
},
"tool_class": {
"display_name": "Tool Class",
"info": "Select the class for additional expressions.",
"options": [],
"refresh_button": True,
"required": False,
},
}
def parse_source_name(self, code: str) -> Dict:
parsed_code = ast.parse(code)
class_names = [
node.name for node in parsed_code.body if isinstance(node, ast.ClassDef)]
function_names = [
node.name for node in parsed_code.body if isinstance(node, ast.FunctionDef)]
return {"class": class_names, "function": function_names}
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict:
if field_name == "tool_code" or field_name == "tool_function" or field_name == "tool_class":
try:
names = self.parse_source_name(build_config.tool_code.value)
build_config.tool_class.options = names["class"]
build_config.tool_function.options = names["function"]
except Exception as e:
self.status = f"Failed to extract class names: {str(e)}"
build_config.tool_class.options = ["Failed to parse", str(e)]
build_config.tool_function.options = []
return build_config
async def build(self, tool_code: Code, name: str, description: str, tool_function: List[str], return_direct: bool, tool_class: List[str] = None) -> Tool:
local_namespace = {}
exec(tool_code, globals(), local_namespace)
func = local_namespace[tool_function]
_class = None
if tool_class:
_class = local_namespace[tool_class]
tool = StructuredTool.from_function(
func=func,
args_schema=_class,
name=name,
description=description,
return_direct=return_direct
)
return tool

View file

@ -1,10 +1,6 @@
from datetime import timedelta
from typing import List, Optional, Union
from couchbase.auth import PasswordAuthenticator # type: ignore
from couchbase.cluster import Cluster # type: ignore
from couchbase.options import ClusterOptions # type: ignore
from langchain_community.vectorstores import CouchbaseVectorStore
from langchain_core.retrievers import BaseRetriever
from langflow.custom import CustomComponent
@ -52,6 +48,16 @@ class CouchbaseComponent(CustomComponent):
couchbase_username: str = "",
couchbase_password: str = "",
) -> Union[VectorStore, BaseRetriever]:
try:
from couchbase.auth import PasswordAuthenticator # type: ignore
from couchbase.cluster import Cluster # type: ignore
from couchbase.options import ClusterOptions # type: ignore
from langchain_community.vectorstores import CouchbaseVectorStore
except ImportError as e:
raise ImportError(
"Failed to import Couchbase dependencies. Install it using `pip install langflow[couchbase] --pre`"
) from e
try:
auth = PasswordAuthenticator(couchbase_username, couchbase_password)
options = ClusterOptions(auth)

View file

@ -1275,13 +1275,13 @@ types-requests = ">=2.31.0.2,<3.0.0.0"
[[package]]
name = "langsmith"
version = "0.1.75"
version = "0.1.76"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
optional = false
python-versions = "<4.0,>=3.8.1"
files = [
{file = "langsmith-0.1.75-py3-none-any.whl", hash = "sha256:d08b08dd6b3fa4da170377f95123d77122ef4c52999d10fff4ae08ff70d07aed"},
{file = "langsmith-0.1.75.tar.gz", hash = "sha256:61274e144ea94c297dd78ce03e6dfae18459fe9bd8ab5094d61a0c4816561279"},
{file = "langsmith-0.1.76-py3-none-any.whl", hash = "sha256:4b8cb14f2233d9673ce9e6e3d545359946d9690a2c1457ab01e7459ec97b964e"},
{file = "langsmith-0.1.76.tar.gz", hash = "sha256:5829f997495c0f9a39f91fe0a57e0cb702e8642e6948945f5bb9f46337db7732"},
]
[package.dependencies]

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow-base"
version = "0.0.60"
version = "0.0.61"
description = "A Python package with a built-in web application"
authors = ["Langflow <contact@langflow.org>"]
maintainers = [

View file

@ -2,19 +2,27 @@
* Function to get the python code for the API
* @param {string} flowId - The id of the flow
* @param {boolean} isAuth - If the API is authenticated
* @param {any[]} tweak - The tweaks
* @param {any[]} tweaksBuildedObject - The tweaks
* @param {string} [endpointName] - The optional endpoint name
* @returns {string} - The python code
*/
export default function getPythonApiCode(
flowId: string,
isAuth: boolean,
tweaksBuildedObject,
endpointName?: string
tweaksBuildedObject: any[],
endpointName?: string,
): string {
const tweaksObject = tweaksBuildedObject[0];
const tweaksString = JSON.stringify(tweaksObject, null, 2)
.replace(/true/g, "True")
.replace(/false/g, "False");
let tweaksString = "{}";
if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {
const tweaksObject = tweaksBuildedObject[0];
if (!tweaksObject) {
throw new Error("expected tweaks");
}
tweaksString = JSON.stringify(tweaksObject, null, 2)
.replace(/true/g, "True")
.replace(/false/g, "False");
}
return `import argparse
import json
from argparse import RawTextHelpFormatter

View file

@ -1,17 +1,26 @@
/**
* Function to get the python code for the API
* @param {string} flow - The current flow
* @param {any[]} tweak - The tweaks
* @param {any[]} tweaksBuildedObject - The tweaks
* @returns {string} - The python code
*/
export default function getPythonCode(
flowName: string,
tweaksBuildedObject
tweaksBuildedObject: any[],
): string {
const tweaksObject = tweaksBuildedObject[0];
let tweaksString = "{}";
if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {
const tweaksObject = tweaksBuildedObject[0];
if (!tweaksObject) {
throw new Error("expected tweaks");
}
tweaksString = JSON.stringify(tweaksObject, null, 2)
.replace(/true/g, "True")
.replace(/false/g, "False");
}
return `from langflow.load import run_flow_from_json
TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
TWEAKS = ${tweaksString}
result = run_flow_from_json(flow="${flowName}.json",
input_value="message",