mirror of
https://github.com/hanzoai/flow.git
synced 2026-10-17 01:29:18 +00:00
feat(deployments): add environment variable overrides for IBM IAM URLs (wxO) (#12373)
* fix: harden verify_credentials error handling and add dev IAM URL overrides Move authenticator construction inside try/except to catch SDK validation errors directly from the constructor instead of calling validate() twice. Add env var overrides (IBM_IAM_MCSP_DEV_URL_OVERRIDE, IBM_IAM_DEV_URL_OVERRIDE) for non-production wxO environments that use different IAM endpoints. Expand test coverage for constructor failures, 403 responses, and empty/whitespace env var fallback behavior. * improve docs * tighten up docs * fix typo * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) --------- Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
committed by
GitHub
co-authored by
Hanzo Dev
parent
7ff7ba77a0
commit
e0232518b1
@@ -661,7 +661,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -622,7 +622,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -538,7 +538,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1037,7 +1037,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
|
||||
+1
-1
@@ -2273,7 +2273,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -416,7 +416,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1319,7 +1319,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -674,7 +674,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1755,7 +1755,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
|
||||
+1
-1
@@ -456,7 +456,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -1124,7 +1124,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -2084,7 +2084,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
@@ -342,7 +342,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1192,7 +1192,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -545,7 +545,7 @@
|
||||
},
|
||||
{
|
||||
"name": "cryptography",
|
||||
"version": "43.0.3"
|
||||
"version": "46.0.6"
|
||||
},
|
||||
{
|
||||
"name": "langchain_chroma",
|
||||
|
||||
@@ -452,7 +452,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1204,7 +1204,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
@@ -685,7 +685,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -965,7 +965,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1245,7 +1245,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -425,7 +425,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -886,7 +886,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1186,7 +1186,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -1757,7 +1757,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "pandas",
|
||||
|
||||
@@ -512,7 +512,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -812,7 +812,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -2338,7 +2338,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
|
||||
@@ -396,7 +396,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1251,7 +1251,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
+2
-2
@@ -328,7 +328,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -928,7 +928,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
|
||||
@@ -420,7 +420,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1620,7 +1620,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
@@ -1768,7 +1768,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -2823,7 +2823,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
+1
-1
@@ -372,7 +372,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -628,7 +628,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -405,7 +405,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -905,7 +905,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
@@ -571,7 +571,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -952,7 +952,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
+5
-5
@@ -370,7 +370,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -958,7 +958,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -2403,7 +2403,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -2976,7 +2976,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -3791,7 +3791,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -652,7 +652,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -951,7 +951,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -1840,7 +1840,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -392,7 +392,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -976,7 +976,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1301,7 +1301,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
+3
-3
@@ -826,7 +826,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1108,7 +1108,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -3581,7 +3581,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
|
||||
+4
-4
@@ -503,7 +503,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1679,7 +1679,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -2262,7 +2262,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -2845,7 +2845,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
|
||||
+1
-1
@@ -706,7 +706,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
@@ -1042,7 +1042,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -1588,7 +1588,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -2659,7 +2659,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -3570,7 +3570,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
|
||||
@@ -513,7 +513,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -1454,7 +1454,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
|
||||
+36
-2
@@ -2,6 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import re
|
||||
from enum import Enum
|
||||
|
||||
@@ -25,10 +26,43 @@ WXO_TRANSLATE = str.maketrans({" ": "_", "-": "_"})
|
||||
ERROR_PREFIX = "An error occurred while"
|
||||
ERROR_SUFFIX_IN = "in Watsonx Orchestrate."
|
||||
|
||||
# The IAM endpoints below generate
|
||||
# authentication tokens for production
|
||||
# wxO environments and are documented publicly:
|
||||
# Documentation: https://www.ibm.com/docs/en/watsonx/watson-orchestrate/base?topic=api-generating-jwt-aws
|
||||
IBM_IAM_MCSP_PRODUCTION_URL = "https://iam.platform.saas.ibm.com"
|
||||
# Documentation: https://www.ibm.com/docs/en/watsonx/watson-orchestrate/base?topic=api-generating-access-token-cloud
|
||||
IBM_IAM_PRODUCTION_URL = "https://iam.cloud.ibm.com"
|
||||
# Non-production wxO environments use different
|
||||
# IAM URLs, which are not documented publicly
|
||||
# and must not be used publicly in plain text.
|
||||
|
||||
|
||||
class WxOAuthURL(str, Enum):
|
||||
MCSP = "https://iam.platform.saas.ibm.com"
|
||||
IBM_IAM = "https://iam.cloud.ibm.com"
|
||||
"""IAM token endpoint URLs used to authenticate against Watsonx Orchestrate.
|
||||
|
||||
Non-production wxO environments use a different IAM URL than
|
||||
production environments. These cannot be exposed in plain text so
|
||||
environment variables are surfaced instead.
|
||||
Set ``IBM_IAM_MCSP_DEV_URL_OVERRIDE`` for AWS wxO environments,
|
||||
``IBM_IAM_DEV_URL_OVERRIDE`` for IBM Cloud.
|
||||
When unset, the production URLs are used
|
||||
("https://iam.platform.saas.ibm.com" and "https://iam.cloud.ibm.com" respectively).
|
||||
|
||||
Please note:
|
||||
- The stated environment variables are solely for
|
||||
internal testing and development purposes,
|
||||
and must be left unset when shipping Langflow
|
||||
for general availability.
|
||||
- The IAM URLs cannot be changed during runtime,
|
||||
and Langflow does not dynamically resolve the IAM URL based on
|
||||
the environment of a given wxO tenant. It simply uses the
|
||||
default production IAM URLs, or the environment variable
|
||||
overrides if set.
|
||||
"""
|
||||
|
||||
MCSP = os.getenv("IBM_IAM_MCSP_DEV_URL_OVERRIDE", "").strip() or IBM_IAM_MCSP_PRODUCTION_URL
|
||||
IBM_IAM = os.getenv("IBM_IAM_DEV_URL_OVERRIDE", "").strip() or IBM_IAM_PRODUCTION_URL
|
||||
|
||||
|
||||
class ErrorPrefix(str, Enum):
|
||||
|
||||
+19
-10
@@ -13,6 +13,7 @@ from lfx.services.adapters.deployment.base import BaseDeploymentService
|
||||
from lfx.services.adapters.deployment.exceptions import (
|
||||
AuthenticationError,
|
||||
AuthorizationError,
|
||||
AuthSchemeError,
|
||||
DeploymentConflictError,
|
||||
DeploymentError,
|
||||
DeploymentNotFoundError,
|
||||
@@ -776,27 +777,35 @@ class WatsonxOrchestrateDeploymentService(BaseDeploymentService):
|
||||
raise DeploymentError(message=msg, error_code="deployment_error")
|
||||
|
||||
provider_creds = verify_slot.parse(payload.provider_data)
|
||||
authenticator = get_authenticator(
|
||||
instance_url=payload.base_url,
|
||||
api_key=provider_creds.api_key,
|
||||
|
||||
malformed_credentials_msg = (
|
||||
"Provider credentials are malformed. Please ensure the URL and API key are correctly formatted."
|
||||
)
|
||||
# AuthSchemeError bubbles up from get_authenticator for unrecognised URLs
|
||||
|
||||
try:
|
||||
authenticator.validate()
|
||||
authenticator = get_authenticator(
|
||||
instance_url=payload.base_url,
|
||||
api_key=provider_creds.api_key,
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise InvalidContentError(
|
||||
message=(
|
||||
"Provider credentials are malformed. Please ensure the URL and API key are correctly formatted."
|
||||
),
|
||||
message=malformed_credentials_msg,
|
||||
cause=exc,
|
||||
) from exc
|
||||
except AuthSchemeError:
|
||||
raise
|
||||
except Exception as exc:
|
||||
raise DeploymentError(
|
||||
message="Credential verification failed unexpectedly.",
|
||||
error_code="deployment_error",
|
||||
cause=exc,
|
||||
) from exc
|
||||
|
||||
try:
|
||||
await asyncio.to_thread(authenticator.token_manager.get_token)
|
||||
except ApiException as exc:
|
||||
# Log the raw provider detail for diagnostics but do not
|
||||
# propagate it — the response body could echo secrets.
|
||||
# Log only the status code for diagnostics and avoid exposing
|
||||
# provider response details that could include sensitive values.
|
||||
logger.error( # noqa: TRY400
|
||||
"Credential verification failed (status=%s)",
|
||||
exc.status_code,
|
||||
|
||||
@@ -65,6 +65,12 @@ WxOCredentials = importlib.import_module(
|
||||
).WxOCredentials
|
||||
|
||||
|
||||
def _reload_wxo_auth_modules():
|
||||
constants_module = importlib.import_module("langflow.services.adapters.deployment.watsonx_orchestrate.constants")
|
||||
importlib.reload(constants_module)
|
||||
return importlib.reload(client_module)
|
||||
|
||||
|
||||
def _tool_refs(*tool_ids: str) -> list[dict[str, str]]:
|
||||
"""Build WatsonxToolRefBinding dicts for test data."""
|
||||
return [{"source_ref": f"fv-{tid}", "tool_id": tid} for tid in tool_ids]
|
||||
@@ -3155,6 +3161,58 @@ def test_get_authenticator_unknown_url():
|
||||
get_authenticator("https://example.com", "test-key")
|
||||
|
||||
|
||||
def test_get_authenticator_uses_default_iam_urls_when_unset(monkeypatch):
|
||||
try:
|
||||
with monkeypatch.context() as context:
|
||||
context.delenv("IBM_IAM_MCSP_DEV_URL_OVERRIDE", raising=False)
|
||||
context.delenv("IBM_IAM_DEV_URL_OVERRIDE", raising=False)
|
||||
reloaded_client_module = _reload_wxo_auth_modules()
|
||||
|
||||
iam_auth = reloaded_client_module.get_authenticator("https://api.region-foobar.cloud.ibm.com", "test-key")
|
||||
mcsp_auth = reloaded_client_module.get_authenticator("https://api.wxo.ibm.com", "test-key")
|
||||
|
||||
assert iam_auth.token_manager.url == "https://iam.cloud.ibm.com"
|
||||
assert mcsp_auth.token_manager.url == "https://iam.platform.saas.ibm.com"
|
||||
finally:
|
||||
_reload_wxo_auth_modules()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("env_value", ["", " "])
|
||||
def test_get_authenticator_empty_or_whitespace_env_var_falls_through_to_default(monkeypatch, env_value):
|
||||
try:
|
||||
with monkeypatch.context() as context:
|
||||
context.setenv("IBM_IAM_MCSP_DEV_URL_OVERRIDE", env_value)
|
||||
context.setenv("IBM_IAM_DEV_URL_OVERRIDE", env_value)
|
||||
reloaded_client_module = _reload_wxo_auth_modules()
|
||||
|
||||
iam_auth = reloaded_client_module.get_authenticator("https://api.region-foobar.cloud.ibm.com", "test-key")
|
||||
mcsp_auth = reloaded_client_module.get_authenticator("https://api.wxo.ibm.com", "test-key")
|
||||
|
||||
assert iam_auth.token_manager.url == "https://iam.cloud.ibm.com"
|
||||
assert mcsp_auth.token_manager.url == "https://iam.platform.saas.ibm.com"
|
||||
finally:
|
||||
_reload_wxo_auth_modules()
|
||||
|
||||
|
||||
def test_get_authenticator_uses_override_iam_urls(monkeypatch):
|
||||
custom_mcsp_url = " https://iam.platform.saas.ibm.com/custom-mcsp "
|
||||
custom_iam_url = " https://iam.cloud.ibm.com/custom-iam "
|
||||
|
||||
try:
|
||||
with monkeypatch.context() as context:
|
||||
context.setenv("IBM_IAM_MCSP_DEV_URL_OVERRIDE", custom_mcsp_url)
|
||||
context.setenv("IBM_IAM_DEV_URL_OVERRIDE", custom_iam_url)
|
||||
reloaded_client_module = _reload_wxo_auth_modules()
|
||||
|
||||
iam_auth = reloaded_client_module.get_authenticator("https://api.region-foobar.cloud.ibm.com", "test-key")
|
||||
mcsp_auth = reloaded_client_module.get_authenticator("https://api.wxo.ibm.com", "test-key")
|
||||
|
||||
assert iam_auth.token_manager.url == custom_iam_url.strip()
|
||||
assert mcsp_auth.token_manager.url == custom_mcsp_url.strip()
|
||||
finally:
|
||||
_reload_wxo_auth_modules()
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_get_provider_clients_uses_request_scoped_context_memoization(monkeypatch):
|
||||
resolve_calls = 0
|
||||
@@ -4744,9 +4802,6 @@ async def test_verify_credentials_success(monkeypatch):
|
||||
class FakeAuthenticator:
|
||||
token_manager = FakeTokenManager()
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
monkeypatch.setattr(
|
||||
service_module,
|
||||
"get_authenticator",
|
||||
@@ -4776,9 +4831,6 @@ async def test_verify_credentials_invalid_key_raises(monkeypatch):
|
||||
class FailingAuthenticator:
|
||||
token_manager = FakeTokenManager()
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
monkeypatch.setattr(
|
||||
service_module,
|
||||
"get_authenticator",
|
||||
@@ -4795,27 +4847,17 @@ async def test_verify_credentials_invalid_key_raises(monkeypatch):
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_verify_credentials_malformed_key_raises(monkeypatch):
|
||||
"""verify_credentials raises InvalidContentError when local validation fails."""
|
||||
async def test_verify_credentials_malformed_key_from_authenticator_constructor_raises():
|
||||
"""verify_credentials raises InvalidContentError when authenticator creation fails validation."""
|
||||
from lfx.services.adapters.deployment.exceptions import InvalidContentError
|
||||
from lfx.services.adapters.deployment.schema import VerifyCredentials
|
||||
|
||||
class MalformedAuthenticator:
|
||||
def validate(self):
|
||||
msg = "api key contains bad characters"
|
||||
raise ValueError(msg)
|
||||
|
||||
monkeypatch.setattr(
|
||||
service_module,
|
||||
"get_authenticator",
|
||||
lambda **_kwargs: MalformedAuthenticator(),
|
||||
)
|
||||
|
||||
svc = WatsonxOrchestrateDeploymentService(settings_service=DummySettingsService())
|
||||
payload = VerifyCredentials(
|
||||
base_url="https://api.us-south.wxo.cloud.ibm.com",
|
||||
provider_data={"api_key": "bad\x00key"}, # pragma: allowlist secret
|
||||
provider_data={"api_key": "{bad-key}"}, # pragma: allowlist secret
|
||||
)
|
||||
|
||||
with pytest.raises(InvalidContentError, match="malformed"):
|
||||
await svc.verify_credentials(user_id="u1", payload=payload)
|
||||
|
||||
@@ -4850,6 +4892,60 @@ async def test_verify_credentials_bad_auth_scheme_raises():
|
||||
await svc.verify_credentials(user_id="u1", payload=payload)
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_verify_credentials_authenticator_construction_unexpected_error(monkeypatch):
|
||||
"""verify_credentials raises DeploymentError when get_authenticator() throws unexpectedly."""
|
||||
from lfx.services.adapters.deployment.exceptions import DeploymentError
|
||||
from lfx.services.adapters.deployment.schema import VerifyCredentials
|
||||
|
||||
def _exploding_authenticator(**_kwargs):
|
||||
msg = "something unexpected"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
monkeypatch.setattr(
|
||||
service_module,
|
||||
"get_authenticator",
|
||||
_exploding_authenticator,
|
||||
)
|
||||
|
||||
svc = WatsonxOrchestrateDeploymentService(settings_service=DummySettingsService())
|
||||
payload = VerifyCredentials(
|
||||
base_url="https://api.us-south.wxo.cloud.ibm.com",
|
||||
provider_data={"api_key": "some-key"}, # pragma: allowlist secret
|
||||
)
|
||||
with pytest.raises(DeploymentError, match="failed unexpectedly"):
|
||||
await svc.verify_credentials(user_id="u1", payload=payload)
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_verify_credentials_forbidden_key_raises(monkeypatch):
|
||||
"""verify_credentials raises AuthorizationError when provider returns 403."""
|
||||
from ibm_cloud_sdk_core import ApiException
|
||||
from lfx.services.adapters.deployment.exceptions import AuthorizationError
|
||||
from lfx.services.adapters.deployment.schema import VerifyCredentials
|
||||
|
||||
class FakeTokenManager:
|
||||
def get_token(self):
|
||||
raise ApiException(403, message="forbidden")
|
||||
|
||||
class ForbiddenAuthenticator:
|
||||
token_manager = FakeTokenManager()
|
||||
|
||||
monkeypatch.setattr(
|
||||
service_module,
|
||||
"get_authenticator",
|
||||
lambda **_kwargs: ForbiddenAuthenticator(),
|
||||
)
|
||||
|
||||
svc = WatsonxOrchestrateDeploymentService(settings_service=DummySettingsService())
|
||||
payload = VerifyCredentials(
|
||||
base_url="https://api.us-south.wxo.cloud.ibm.com",
|
||||
provider_data={"api_key": "some-key"}, # pragma: allowlist secret
|
||||
)
|
||||
with pytest.raises(AuthorizationError, match="Credential verification"):
|
||||
await svc.verify_credentials(user_id="u1", payload=payload)
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_verify_credentials_provider_unreachable(monkeypatch):
|
||||
"""verify_credentials raises DeploymentError on network failure."""
|
||||
@@ -4864,9 +4960,6 @@ async def test_verify_credentials_provider_unreachable(monkeypatch):
|
||||
class UnreachableAuthenticator:
|
||||
token_manager = FakeTokenManager()
|
||||
|
||||
def validate(self):
|
||||
pass
|
||||
|
||||
monkeypatch.setattr(
|
||||
service_module,
|
||||
"get_authenticator",
|
||||
|
||||
@@ -304,7 +304,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
@@ -312,11 +312,11 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "markdown",
|
||||
"version": "3.7"
|
||||
"version": "3.10.2"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -481,11 +481,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -622,11 +622,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -791,11 +791,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -932,11 +932,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -1102,11 +1102,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -1273,11 +1273,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -1466,11 +1466,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -3588,7 +3588,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 2
|
||||
@@ -5712,7 +5712,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -6062,7 +6062,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -12786,7 +12786,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_openai",
|
||||
@@ -13162,7 +13162,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -56096,7 +56096,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -56104,7 +56104,7 @@
|
||||
},
|
||||
{
|
||||
"name": "cuga",
|
||||
"version": "0.2.9"
|
||||
"version": "0.2.10"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -57738,7 +57738,7 @@
|
||||
},
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
@@ -57984,7 +57984,7 @@
|
||||
},
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
@@ -58305,7 +58305,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
@@ -58685,7 +58685,7 @@
|
||||
},
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "bs4",
|
||||
@@ -59621,7 +59621,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -60045,7 +60045,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -60920,11 +60920,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -62120,7 +62120,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -62786,7 +62786,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -64872,7 +64872,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -66748,7 +66748,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "langchain_elasticsearch",
|
||||
@@ -68795,7 +68795,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "metaphor_python",
|
||||
@@ -69256,7 +69256,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -69944,7 +69944,7 @@
|
||||
},
|
||||
{
|
||||
"name": "cryptography",
|
||||
"version": "43.0.3"
|
||||
"version": "46.0.6"
|
||||
},
|
||||
{
|
||||
"name": "langchain_chroma",
|
||||
@@ -70195,7 +70195,7 @@
|
||||
},
|
||||
{
|
||||
"name": "cryptography",
|
||||
"version": "43.0.3"
|
||||
"version": "46.0.6"
|
||||
},
|
||||
{
|
||||
"name": "langchain_chroma",
|
||||
@@ -70555,7 +70555,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "pandas",
|
||||
@@ -73620,7 +73620,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -73973,7 +73973,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "langchain_google_community",
|
||||
@@ -74126,7 +74126,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "langchain_google_genai",
|
||||
@@ -74658,7 +74658,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -75839,11 +75839,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -76022,11 +76022,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -76188,7 +76188,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_community",
|
||||
@@ -77655,7 +77655,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -78150,7 +78150,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "orjson",
|
||||
"version": "3.10.15"
|
||||
"version": "3.11.7"
|
||||
},
|
||||
{
|
||||
"name": "fastapi",
|
||||
@@ -81665,7 +81665,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -82332,7 +82332,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -82960,7 +82960,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -84839,7 +84839,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -85237,7 +85237,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "langchain_experimental",
|
||||
@@ -85805,7 +85805,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -86616,7 +86616,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -91635,7 +91635,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
}
|
||||
],
|
||||
"total_dependencies": 3
|
||||
@@ -92945,7 +92945,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -94347,11 +94347,11 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -94624,7 +94624,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_openai",
|
||||
@@ -95582,7 +95582,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "pypdf",
|
||||
"version": "6.6.2"
|
||||
"version": "6.9.2"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -99682,7 +99682,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -102677,7 +102677,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -105247,7 +105247,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -107193,7 +107193,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -108264,7 +108264,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -108390,7 +108390,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -108580,7 +108580,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -108803,7 +108803,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -109094,7 +109094,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "langchain_experimental",
|
||||
@@ -109260,7 +109260,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_classic",
|
||||
@@ -109268,7 +109268,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -109451,7 +109451,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -109690,7 +109690,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -109912,7 +109912,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -110310,7 +110310,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -110651,7 +110651,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -116335,7 +116335,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "lfx",
|
||||
@@ -116780,7 +116780,7 @@
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "requests",
|
||||
"version": "2.32.5"
|
||||
"version": "2.33.0"
|
||||
},
|
||||
{
|
||||
"name": "langchain_openai",
|
||||
@@ -117164,7 +117164,7 @@
|
||||
},
|
||||
{
|
||||
"name": "langchain_core",
|
||||
"version": "1.2.20"
|
||||
"version": "1.2.22"
|
||||
},
|
||||
{
|
||||
"name": "pydantic",
|
||||
@@ -118890,6 +118890,6 @@
|
||||
"num_components": 360,
|
||||
"num_modules": 97
|
||||
},
|
||||
"sha256": "5740df4879d7590f10593825698265eefbded28feb020373f66e74a6dd83374b",
|
||||
"sha256": "6acfb292943005c8b3a887f4d4ae6cb41b725e05335e638e035d791ab4d3c7dc",
|
||||
"version": "0.4.0"
|
||||
}
|
||||
Reference in New Issue
Block a user