Fixes flows without input_keys not being runnable (#727)
This commit is contained in:
commit
3f531a1157
8 changed files with 113 additions and 83 deletions
|
|
@ -155,7 +155,7 @@ async def stream_build(flow_id: str):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
input_keys_response = {
|
input_keys_response = {
|
||||||
"input_keys": {},
|
"input_keys": None,
|
||||||
"memory_keys": [],
|
"memory_keys": [],
|
||||||
"handle_keys": [],
|
"handle_keys": [],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ class ChatManager:
|
||||||
self, client_id: str, payload: Dict, langchain_object: Any
|
self, client_id: str, payload: Dict, langchain_object: Any
|
||||||
):
|
):
|
||||||
# Process the graph data and chat message
|
# Process the graph data and chat message
|
||||||
chat_inputs = payload.pop("inputs", "")
|
chat_inputs = payload.pop("inputs", {})
|
||||||
chat_inputs = ChatMessage(message=chat_inputs)
|
chat_inputs = ChatMessage(message=chat_inputs)
|
||||||
self.chat_history.add_message(client_id, chat_inputs)
|
self.chat_history.add_message(client_id, chat_inputs)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ async def process_graph(
|
||||||
|
|
||||||
# Generate result and thought
|
# Generate result and thought
|
||||||
try:
|
try:
|
||||||
if not chat_inputs.message:
|
if chat_inputs.message is None:
|
||||||
logger.debug("No message provided")
|
logger.debug("No message provided")
|
||||||
raise ValueError("No message provided")
|
chat_inputs.message = {}
|
||||||
|
|
||||||
logger.debug("Generating result and thought")
|
logger.debug("Generating result and thought")
|
||||||
result, intermediate_steps = await get_result_and_steps(
|
result, intermediate_steps = await get_result_and_steps(
|
||||||
|
|
|
||||||
|
|
@ -171,11 +171,7 @@ def initialize_pinecone(class_object: Type[Pinecone], params: dict):
|
||||||
def initialize_chroma(class_object: Type[Chroma], params: dict):
|
def initialize_chroma(class_object: Type[Chroma], params: dict):
|
||||||
"""Initialize a ChromaDB object from the params"""
|
"""Initialize a ChromaDB object from the params"""
|
||||||
if ( # type: ignore
|
if ( # type: ignore
|
||||||
"chroma_server_host" in params
|
"chroma_server_host" in params or "chroma_server_http_port" in params
|
||||||
or "chroma_server_http_port" in params
|
|
||||||
or "chroma_server_ssl_enabled" in params
|
|
||||||
or "chroma_server_grpc_port" in params
|
|
||||||
or "chroma_server_cors_allow_origins" in params
|
|
||||||
):
|
):
|
||||||
import chromadb # type: ignore
|
import chromadb # type: ignore
|
||||||
|
|
||||||
|
|
@ -186,6 +182,14 @@ def initialize_chroma(class_object: Type[Chroma], params: dict):
|
||||||
}
|
}
|
||||||
chroma_settings = chromadb.config.Settings(**settings_params)
|
chroma_settings = chromadb.config.Settings(**settings_params)
|
||||||
params["client_settings"] = chroma_settings
|
params["client_settings"] = chroma_settings
|
||||||
|
else:
|
||||||
|
# remove all chroma_server_ keys from params
|
||||||
|
params = {
|
||||||
|
key: value
|
||||||
|
for key, value in params.items()
|
||||||
|
if not key.startswith("chroma_server_")
|
||||||
|
}
|
||||||
|
|
||||||
persist = params.pop("persist", False)
|
persist = params.pop("persist", False)
|
||||||
if not docs_in_params(params):
|
if not docs_in_params(params):
|
||||||
params.pop("documents", None)
|
params.pop("documents", None)
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,15 @@ export default function BuildTrigger({
|
||||||
const parsedData = JSON.parse(event.data);
|
const parsedData = JSON.parse(event.data);
|
||||||
// if the event is the end of the stream, close the connection
|
// if the event is the end of the stream, close the connection
|
||||||
if (parsedData.end_of_stream) {
|
if (parsedData.end_of_stream) {
|
||||||
|
// Close the connection and finish
|
||||||
|
finished = true;
|
||||||
eventSource.close();
|
eventSource.close();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else if (parsedData.log) {
|
} else if (parsedData.log) {
|
||||||
// If the event is a log, log it
|
// If the event is a log, log it
|
||||||
setSuccessData({ title: parsedData.log });
|
setSuccessData({ title: parsedData.log });
|
||||||
} else if (parsedData.input_keys) {
|
} else if (parsedData.input_keys !== undefined) {
|
||||||
setTabsState((old) => {
|
setTabsState((old) => {
|
||||||
return {
|
return {
|
||||||
...old,
|
...old,
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,7 @@ export default function Chat({ flow }: ChatType) {
|
||||||
tabsState &&
|
tabsState &&
|
||||||
tabsState[flow.id] &&
|
tabsState[flow.id] &&
|
||||||
tabsState[flow.id].formKeysData &&
|
tabsState[flow.id].formKeysData &&
|
||||||
tabsState[flow.id].formKeysData.input_keys &&
|
tabsState[flow.id].formKeysData.input_keys !== null
|
||||||
Object.keys(tabsState[flow.id].formKeysData.input_keys).length > 0
|
|
||||||
) {
|
) {
|
||||||
setCanOpen(true);
|
setCanOpen(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,17 @@ export default function FormModal({
|
||||||
const id = useRef(flow.id);
|
const id = useRef(flow.id);
|
||||||
const tabsStateFlowId = tabsState[flow.id];
|
const tabsStateFlowId = tabsState[flow.id];
|
||||||
const tabsStateFlowIdFormKeysData = tabsStateFlowId.formKeysData;
|
const tabsStateFlowIdFormKeysData = tabsStateFlowId.formKeysData;
|
||||||
const [chatKey, setChatKey] = useState(
|
const [chatKey, setChatKey] = useState(() => {
|
||||||
Object.keys(tabsState[flow.id].formKeysData.input_keys).find(
|
if (tabsState[flow.id]?.formKeysData?.input_keys) {
|
||||||
(k) =>
|
return Object.keys(tabsState[flow.id].formKeysData.input_keys).find(
|
||||||
!tabsState[flow.id].formKeysData.handle_keys.some((j) => j === k) &&
|
(k) =>
|
||||||
tabsState[flow.id].formKeysData.input_keys[k] === ""
|
!tabsState[flow.id].formKeysData.handle_keys.some((j) => j === k) &&
|
||||||
)
|
tabsState[flow.id].formKeysData.input_keys[k] === ""
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
// TODO: return a sensible default
|
||||||
|
return "";
|
||||||
|
});
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (messagesRef.current) {
|
if (messagesRef.current) {
|
||||||
messagesRef.current.scrollTop = messagesRef.current.scrollHeight;
|
messagesRef.current.scrollTop = messagesRef.current.scrollHeight;
|
||||||
|
|
@ -419,68 +422,70 @@ export default function FormModal({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{Object.keys(tabsState[id.current].formKeysData.input_keys).map(
|
{tabsState[id.current]?.formKeysData?.input_keys
|
||||||
(i, k) => (
|
? Object.keys(
|
||||||
<div className="file-component-accordion-div" key={k}>
|
tabsState[id.current].formKeysData.input_keys
|
||||||
<AccordionComponent
|
).map((i, k) => (
|
||||||
trigger={
|
<div className="file-component-accordion-div" key={k}>
|
||||||
<div className="file-component-badge-div">
|
<AccordionComponent
|
||||||
<Badge variant="gray" size="md">
|
trigger={
|
||||||
{i}
|
<div className="file-component-badge-div">
|
||||||
</Badge>
|
<Badge variant="gray" size="md">
|
||||||
|
{i}
|
||||||
|
</Badge>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className="-mb-1"
|
className="-mb-1"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ToggleShadComponent
|
||||||
|
enabled={chatKey === i}
|
||||||
|
setEnabled={(value) =>
|
||||||
|
handleOnCheckedChange(value, i)
|
||||||
|
}
|
||||||
|
size="small"
|
||||||
|
disabled={tabsState[
|
||||||
|
id.current
|
||||||
|
].formKeysData.handle_keys.some((t) => t === i)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
key={k}
|
||||||
|
keyValue={i}
|
||||||
|
>
|
||||||
|
<div className="file-component-tab-column">
|
||||||
|
{tabsState[id.current].formKeysData.handle_keys.some(
|
||||||
|
(t) => t === i
|
||||||
|
) && (
|
||||||
|
<div className="font-normal text-muted-foreground ">
|
||||||
|
Source: Component
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<Textarea
|
||||||
|
className="custom-scroll"
|
||||||
|
value={
|
||||||
|
tabsState[id.current].formKeysData.input_keys[i]
|
||||||
|
}
|
||||||
|
onChange={(e) => {
|
||||||
|
setTabsState((old) => {
|
||||||
|
let newTabsState = _.cloneDeep(old);
|
||||||
|
newTabsState[
|
||||||
|
id.current
|
||||||
|
].formKeysData.input_keys[i] = e.target.value;
|
||||||
|
return newTabsState;
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
disabled={chatKey === i}
|
||||||
<ToggleShadComponent
|
placeholder="Enter text..."
|
||||||
enabled={chatKey === i}
|
></Textarea>
|
||||||
setEnabled={(value) =>
|
|
||||||
handleOnCheckedChange(value, i)
|
|
||||||
}
|
|
||||||
size="small"
|
|
||||||
disabled={tabsState[
|
|
||||||
id.current
|
|
||||||
].formKeysData.handle_keys.some((t) => t === i)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
</AccordionComponent>
|
||||||
key={k}
|
</div>
|
||||||
keyValue={i}
|
))
|
||||||
>
|
: null}
|
||||||
<div className="file-component-tab-column">
|
|
||||||
{tabsState[id.current].formKeysData.handle_keys.some(
|
|
||||||
(t) => t === i
|
|
||||||
) && (
|
|
||||||
<div className="font-normal text-muted-foreground ">
|
|
||||||
Source: Component
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<Textarea
|
|
||||||
className="custom-scroll"
|
|
||||||
value={
|
|
||||||
tabsState[id.current].formKeysData.input_keys[i]
|
|
||||||
}
|
|
||||||
onChange={(e) => {
|
|
||||||
setTabsState((old) => {
|
|
||||||
let newTabsState = _.cloneDeep(old);
|
|
||||||
newTabsState[id.current].formKeysData.input_keys[
|
|
||||||
i
|
|
||||||
] = e.target.value;
|
|
||||||
return newTabsState;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
disabled={chatKey === i}
|
|
||||||
placeholder="Enter text..."
|
|
||||||
></Textarea>
|
|
||||||
</div>
|
|
||||||
</AccordionComponent>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
{tabsState[id.current].formKeysData.memory_keys.map((i, k) => (
|
{tabsState[id.current].formKeysData.memory_keys.map((i, k) => (
|
||||||
<div className="file-component-accordion-div" key={k}>
|
<div className="file-component-accordion-div" key={k}>
|
||||||
<AccordionComponent
|
<AccordionComponent
|
||||||
|
|
|
||||||
|
|
@ -248,6 +248,27 @@ export function buildTweakObject(tweak) {
|
||||||
return tweakString;
|
return tweakString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get Chat Input Field
|
||||||
|
* @param {FlowType} flow - The current flow.
|
||||||
|
* @param {TabsState} tabsState - The current tabs state.
|
||||||
|
* @returns {string} - The chat input field
|
||||||
|
*/
|
||||||
|
export function getChatInputField(flow: FlowType, tabsState?: TabsState) {
|
||||||
|
let chat_input_field = "text";
|
||||||
|
|
||||||
|
if (
|
||||||
|
tabsState[flow.id] &&
|
||||||
|
tabsState[flow.id].formKeysData &&
|
||||||
|
tabsState[flow.id].formKeysData.input_keys
|
||||||
|
) {
|
||||||
|
chat_input_field = Object.keys(
|
||||||
|
tabsState[flow.id].formKeysData.input_keys
|
||||||
|
)[0];
|
||||||
|
}
|
||||||
|
return chat_input_field;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get the python code for the API
|
* Function to get the python code for the API
|
||||||
* @param {string} flowId - The id of the flow
|
* @param {string} flowId - The id of the flow
|
||||||
|
|
@ -365,6 +386,7 @@ export function getWidgetCode(flow: FlowType, tabsState?: TabsState): string {
|
||||||
const flowId = flow.id;
|
const flowId = flow.id;
|
||||||
const flowName = flow.name;
|
const flowName = flow.name;
|
||||||
const inputs = buildInputs(tabsState, flow.id);
|
const inputs = buildInputs(tabsState, flow.id);
|
||||||
|
let chat_input_field = getChatInputField(flow, tabsState);
|
||||||
|
|
||||||
return `<script src="https://cdn.jsdelivr.net/gh/logspace-ai/langflow-embedded-chat@main/dist/build/static/js/bundle.min.js"></script>
|
return `<script src="https://cdn.jsdelivr.net/gh/logspace-ai/langflow-embedded-chat@main/dist/build/static/js/bundle.min.js"></script>
|
||||||
|
|
||||||
|
|
@ -377,9 +399,7 @@ chat_input_field: Input key that you want the chat to send the user message with
|
||||||
${
|
${
|
||||||
tabsState[flow.id] && tabsState[flow.id].formKeysData
|
tabsState[flow.id] && tabsState[flow.id].formKeysData
|
||||||
? `chat_inputs='${inputs}'
|
? `chat_inputs='${inputs}'
|
||||||
chat_input_field="${
|
chat_input_field="${chat_input_field}"
|
||||||
Object.keys(tabsState[flow.id].formKeysData.input_keys)[0]
|
|
||||||
}"
|
|
||||||
`
|
`
|
||||||
: ""
|
: ""
|
||||||
}host_url="http://localhost:7860"
|
}host_url="http://localhost:7860"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue