Merge remote-tracking branch 'origin/dev' into fixList
This commit is contained in:
commit
c0a464f8e2
58 changed files with 1164 additions and 777 deletions
2
.github/workflows/typescript_test.yml
vendored
2
.github/workflows/typescript_test.yml
vendored
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
|
||||
- name: Get Playwright version
|
||||
run: echo "PLAYWRIGHT_VERSION=$(jq '.devDependencies["@playwright/test"]' src/frontend/package.json -r)" >> $GITHUB_ENV
|
||||
- name: Cache Playwright binaries
|
||||
- name: Cache Playwright binaries
|
||||
id: playwright-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
|
|
|||
14
scripts/aws/package-lock.json
generated
14
scripts/aws/package-lock.json
generated
|
|
@ -1950,12 +1950,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -2763,9 +2763,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class CustomComponent(BaseComponent):
|
|||
_flows_data: Optional[List[Data]] = None
|
||||
_outputs: List[OutputLog] = []
|
||||
_logs: List[Log] = []
|
||||
_tracing_service: "TracingService"
|
||||
tracing_service: Optional["TracingService"] = None
|
||||
|
||||
def update_state(self, name: str, value: Any):
|
||||
if not self.vertex:
|
||||
|
|
@ -488,14 +488,14 @@ class CustomComponent(BaseComponent):
|
|||
Args:
|
||||
message (LoggableType | list[LoggableType]): The message to log.
|
||||
"""
|
||||
if name is None:
|
||||
name = self.display_name if self.display_name else self.__class__.__name__
|
||||
if hasattr(message, "model_dump") and isinstance(message, BaseModel):
|
||||
message = message.model_dump()
|
||||
if name is None and self.display_name:
|
||||
name = self.display_name
|
||||
else:
|
||||
name = self.__class__.__name__
|
||||
log = Log(message=message, type=get_artifact_type(message), name=name)
|
||||
self._logs.append(log)
|
||||
if self.vertex:
|
||||
self._tracing_service.add_log(trace_name=self.vertex.id, log=log)
|
||||
if self.tracing_service and self.vertex:
|
||||
self.tracing_service.add_log(trace_name=self.vertex.id, log=log)
|
||||
|
||||
def post_code_processing(self, new_build_config: dict, current_build_config: dict):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -18,8 +18,12 @@ def migrate_messages_from_monitor_service_to_database(session: Session) -> bool:
|
|||
from langflow.schema.message import Message
|
||||
from langflow.services.database.models.message import MessageTable
|
||||
|
||||
monitor_service = get_monitor_service()
|
||||
messages_df = monitor_service.get_messages()
|
||||
try:
|
||||
monitor_service = get_monitor_service()
|
||||
messages_df = monitor_service.get_messages()
|
||||
except Exception as e:
|
||||
logger.error(f"Error retrieving messages from monitor service: {e}")
|
||||
return False
|
||||
|
||||
if messages_df.empty:
|
||||
logger.info("No messages to migrate.")
|
||||
|
|
|
|||
33
src/backend/base/langflow/services/tracing/base.py
Normal file
33
src/backend/base/langflow/services/tracing/base.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Dict
|
||||
from uuid import UUID
|
||||
|
||||
|
||||
class BaseTracer(ABC):
|
||||
@abstractmethod
|
||||
def __init__(self, trace_name: str, trace_type: str, project_name: str, trace_id: UUID):
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def ready(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def add_trace(
|
||||
self, trace_name: str, trace_type: str, inputs: Dict[str, Any], metadata: Dict[str, Any] | None = None
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def end_trace(self, trace_name: str, outputs: Dict[str, Any] | None = None, error: str | None = None):
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def end(
|
||||
self,
|
||||
inputs: dict[str, Any],
|
||||
outputs: Dict[str, Any],
|
||||
error: str | None = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
):
|
||||
raise NotImplementedError
|
||||
|
|
@ -12,6 +12,7 @@ from loguru import logger
|
|||
|
||||
from langflow.schema.data import Data
|
||||
from langflow.services.base import Service
|
||||
from langflow.services.tracing.base import BaseTracer
|
||||
from langflow.services.tracing.schema import Log
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -180,7 +181,7 @@ class TracingService(Service):
|
|||
self.outputs_metadata[trace_name] |= output_metadata or {}
|
||||
|
||||
|
||||
class LangSmithTracer:
|
||||
class LangSmithTracer(BaseTracer):
|
||||
def __init__(self, trace_name: str, trace_type: str, project_name: str, trace_id: UUID):
|
||||
from langsmith.run_trees import RunTree
|
||||
|
||||
|
|
@ -292,7 +293,7 @@ class LangSmithTracer:
|
|||
inputs: dict[str, Any],
|
||||
outputs: Dict[str, Any],
|
||||
error: str | None = None,
|
||||
metadata: Optional[dict[str, Any]] = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
):
|
||||
self._run_tree.add_metadata({"inputs": inputs, "metadata": metadata or {}})
|
||||
self._run_tree.end(outputs=outputs, error=error)
|
||||
|
|
|
|||
34
src/backend/base/langflow/services/tracing/utils.py
Normal file
34
src/backend/base/langflow/services/tracing/utils.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from typing import Any, Dict
|
||||
|
||||
from langflow.schema.data import Data
|
||||
|
||||
|
||||
def convert_to_langchain_type(value):
|
||||
from langflow.schema.message import Message
|
||||
|
||||
if isinstance(value, dict):
|
||||
for key, _value in value.copy().items():
|
||||
_value = convert_to_langchain_type(_value)
|
||||
value[key] = _value
|
||||
elif isinstance(value, list):
|
||||
value = [convert_to_langchain_type(v) for v in value]
|
||||
elif isinstance(value, Message):
|
||||
if "prompt" in value:
|
||||
value = value.load_lc_prompt()
|
||||
elif value.sender:
|
||||
value = value.to_lc_message()
|
||||
else:
|
||||
value = value.to_lc_document()
|
||||
elif isinstance(value, Data):
|
||||
if "text" in value.data:
|
||||
value = value.to_lc_document()
|
||||
else:
|
||||
value = value.data
|
||||
return value
|
||||
|
||||
|
||||
def convert_to_langchain_types(io_dict: Dict[str, Any]):
|
||||
converted = {}
|
||||
for key, value in io_dict.items():
|
||||
converted[key] = convert_to_langchain_type(value)
|
||||
return converted
|
||||
|
|
@ -21,6 +21,7 @@ export default function HandleRenderComponent({
|
|||
colors,
|
||||
setFilterEdge,
|
||||
showNode,
|
||||
testIdComplement,
|
||||
}: {
|
||||
left: boolean;
|
||||
nodes: any;
|
||||
|
|
@ -33,6 +34,7 @@ export default function HandleRenderComponent({
|
|||
colors: string[];
|
||||
setFilterEdge: any;
|
||||
showNode: any;
|
||||
testIdComplement?: string;
|
||||
}) {
|
||||
return (
|
||||
<Button
|
||||
|
|
@ -52,7 +54,7 @@ export default function HandleRenderComponent({
|
|||
side={left ? "left" : "right"}
|
||||
>
|
||||
<Handle
|
||||
data-testid={`handle-${title.toLowerCase()}-${
|
||||
data-testid={`handle-${testIdComplement}-${title.toLowerCase()}-${
|
||||
!showNode ? (left ? "target" : "source") : left ? "left" : "right"
|
||||
}`}
|
||||
type={left ? "target" : "source"}
|
||||
|
|
|
|||
|
|
@ -264,6 +264,7 @@ export default function ParameterComponent({
|
|||
colors={colors}
|
||||
setFilterEdge={setFilterEdge}
|
||||
showNode={showNode}
|
||||
testIdComplement={`${data?.type?.toLowerCase()}-noshownode`}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
|
|
@ -390,6 +391,7 @@ export default function ParameterComponent({
|
|||
colors={colors}
|
||||
setFilterEdge={setFilterEdge}
|
||||
showNode={showNode}
|
||||
testIdComplement={`${data?.type?.toLowerCase()}-shownode`}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -863,3 +863,11 @@ export const TITLE_ERROR_UPDATING_COMPONENT =
|
|||
"Error while updating the Component";
|
||||
|
||||
export const EMPTY_INPUT_SEND_MESSAGE = "No input message provided.";
|
||||
|
||||
export const TABS_ORDER = [
|
||||
"run curl",
|
||||
"python api",
|
||||
"js api",
|
||||
"python code",
|
||||
"chat widget html",
|
||||
];
|
||||
|
|
|
|||
|
|
@ -43,10 +43,6 @@ export const FolderForms = ({
|
|||
if (folderToEdit) {
|
||||
setValue("name", folderToEdit.name);
|
||||
setValue("description", folderToEdit.description);
|
||||
console.log(folderToEdit);
|
||||
|
||||
// setSelectedComponents(folderToEdit.components);
|
||||
// setSelectedFlows(folderToEdit.flows);
|
||||
return;
|
||||
}
|
||||
setValue("name", "");
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ export default function ChatView({
|
|||
)
|
||||
.map((output, index) => {
|
||||
try {
|
||||
console.log("output:", output);
|
||||
|
||||
const messageOutput = output.data.message;
|
||||
const hasMessageValue =
|
||||
messageOutput?.message ||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ import { buildContent } from "./utils/build-content";
|
|||
import { buildTweaks } from "./utils/build-tweaks";
|
||||
import { checkCanBuildTweakObject } from "./utils/check-can-build-tweak-object";
|
||||
import { getChangesType } from "./utils/get-changes-types";
|
||||
import getCodesObj from "./utils/get-codes-obj";
|
||||
import { getCurlRunCode, getCurlWebhookCode } from "./utils/get-curl-code";
|
||||
import getJsApiCode from "./utils/get-js-api-code";
|
||||
import { getNodesWithDefaultValue } from "./utils/get-nodes-with-default-value";
|
||||
import getPythonApiCode from "./utils/get-python-api-code";
|
||||
import getPythonCode from "./utils/get-python-code";
|
||||
import getTabsOrder from "./utils/get-tabs-order";
|
||||
import { getValue } from "./utils/get-value";
|
||||
import getWidgetCode from "./utils/get-widget-code";
|
||||
import { createTabsArray } from "./utils/tabs-array";
|
||||
|
|
@ -213,21 +215,26 @@ const ApiModal = forwardRef(
|
|||
);
|
||||
const pythonCode = getPythonCode(flow?.name, cloneTweak);
|
||||
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
|
||||
const isThereTweaks = Object.keys(tweaksCode).length > 0;
|
||||
const codesObj = getCodesObj({
|
||||
runCurlCode,
|
||||
webhookCurlCode,
|
||||
pythonApiCode,
|
||||
jsApiCode,
|
||||
pythonCode,
|
||||
widgetCode,
|
||||
});
|
||||
const tabsOrder = getTabsOrder(includeWebhook, isThereTweaks);
|
||||
if (tabs && tabs?.length > 0) {
|
||||
let i = 0;
|
||||
tabs![i].code = runCurlCode;
|
||||
i++;
|
||||
if (includeWebhook) {
|
||||
tabs![i].code = webhookCurlCode;
|
||||
i++;
|
||||
}
|
||||
tabs![i].code = pythonApiCode;
|
||||
i++;
|
||||
tabs![i].code = jsApiCode;
|
||||
i++;
|
||||
tabs![i].code = pythonCode;
|
||||
i++;
|
||||
tabs![i].code = widgetCode;
|
||||
tabs.forEach((tab, idx) => {
|
||||
const order = tabsOrder[idx];
|
||||
if (order && order.toLowerCase() === tab.name.toLowerCase()) {
|
||||
const codeToFind = codesObj.find(
|
||||
(c) => c.name.toLowerCase() === tab.name.toLowerCase(),
|
||||
);
|
||||
tab.code = codeToFind?.code;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
40
src/frontend/src/modals/apiModal/utils/get-codes-obj.tsx
Normal file
40
src/frontend/src/modals/apiModal/utils/get-codes-obj.tsx
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import {
|
||||
getCodesObjProps,
|
||||
getCodesObjReturn,
|
||||
} from "../../../types/utils/functions";
|
||||
|
||||
export default function getCodesObj({
|
||||
runCurlCode,
|
||||
webhookCurlCode,
|
||||
pythonApiCode,
|
||||
jsApiCode,
|
||||
pythonCode,
|
||||
widgetCode,
|
||||
}: getCodesObjProps): getCodesObjReturn {
|
||||
return [
|
||||
{
|
||||
name: "run curl",
|
||||
code: runCurlCode,
|
||||
},
|
||||
{
|
||||
name: "webhook curl",
|
||||
code: webhookCurlCode,
|
||||
},
|
||||
{
|
||||
name: "python api",
|
||||
code: pythonApiCode,
|
||||
},
|
||||
{
|
||||
name: "js api",
|
||||
code: jsApiCode,
|
||||
},
|
||||
{
|
||||
name: "python code",
|
||||
code: pythonCode,
|
||||
},
|
||||
{
|
||||
name: "chat widget html",
|
||||
code: widgetCode,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ export function getCurlRunCode(
|
|||
flowId: string,
|
||||
isAuth: boolean,
|
||||
tweaksBuildedObject,
|
||||
endpointName?: string,
|
||||
endpointName?: string | null,
|
||||
): string {
|
||||
const tweaksObject = tweaksBuildedObject[0];
|
||||
// show the endpoint name in the curl command if it exists
|
||||
|
|
@ -35,7 +35,11 @@ export function getCurlRunCode(
|
|||
* @param {string} options.endpointName - The name of the webhook endpoint.
|
||||
* @returns {string} The cURL command.
|
||||
*/
|
||||
export function getCurlWebhookCode(flowId, isAuth, endpointName?: string) {
|
||||
export function getCurlWebhookCode(
|
||||
flowId,
|
||||
isAuth,
|
||||
endpointName?: string | null,
|
||||
) {
|
||||
return `curl -X POST \\
|
||||
"${window.location.protocol}//${window.location.host}/api/v1/webhook/${
|
||||
endpointName || flowId
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export default function getJsApiCode(
|
|||
flowId: string,
|
||||
isAuth: boolean,
|
||||
tweaksBuildedObject: any[],
|
||||
endpointName?: string,
|
||||
endpointName?: string | null,
|
||||
): string {
|
||||
let tweaksString = "{}";
|
||||
if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export default function getPythonApiCode(
|
|||
flowId: string,
|
||||
isAuth: boolean,
|
||||
tweaksBuildedObject: any[],
|
||||
endpointName?: string,
|
||||
endpointName?: string | null,
|
||||
): string {
|
||||
let tweaksString = "{}";
|
||||
if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {
|
||||
|
|
|
|||
15
src/frontend/src/modals/apiModal/utils/get-tabs-order.tsx
Normal file
15
src/frontend/src/modals/apiModal/utils/get-tabs-order.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { TABS_ORDER } from "../../../constants/constants";
|
||||
|
||||
export default function getTabsOrder(
|
||||
isThereWH: boolean = false,
|
||||
isThereTweaks: boolean = false,
|
||||
): string[] {
|
||||
const defaultOrder = TABS_ORDER;
|
||||
if (isThereTweaks) {
|
||||
defaultOrder.push("tweaks");
|
||||
}
|
||||
if (isThereWH) {
|
||||
defaultOrder.splice(1, 0, "webhook curl");
|
||||
}
|
||||
return defaultOrder;
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ export function createTabsArray(
|
|||
includeWebhookCurl = false,
|
||||
includeTweaks = false,
|
||||
) {
|
||||
// console.log(includeTweaks)
|
||||
console.log(includeWebhookCurl);
|
||||
const tabs = [
|
||||
{
|
||||
name: "Run cURL",
|
||||
|
|
|
|||
10
src/frontend/src/types/utils/functions.ts
Normal file
10
src/frontend/src/types/utils/functions.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export type getCodesObjProps = {
|
||||
runCurlCode: string;
|
||||
webhookCurlCode: string;
|
||||
pythonApiCode: string;
|
||||
jsApiCode: string;
|
||||
pythonCode: string;
|
||||
widgetCode: string;
|
||||
};
|
||||
|
||||
export type getCodesObjReturn = Array<{ name: string; code: string }>;
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue