laminar integration (#2887)

This commit is contained in:
LawyZheng
2025-07-07 14:43:10 +08:00
committed by GitHub
parent a0aec45a5d
commit 95ab8295ce
16 changed files with 1107 additions and 66 deletions

848
poetry.lock generated
View File

@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand.
# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
[[package]]
name = "about-time"
@@ -452,6 +452,18 @@ cffi = ">=1.0.1"
dev = ["cogapp", "pre-commit", "pytest", "wheel"]
tests = ["pytest"]
[[package]]
name = "argparse"
version = "1.4.0"
description = "Python command-line parsing library"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314"},
{file = "argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4"},
]
[[package]]
name = "arrow"
version = "1.3.0"
@@ -1405,24 +1417,6 @@ files = [
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
]
[[package]]
name = "deprecated"
version = "1.2.18"
description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
groups = ["main"]
files = [
{file = "Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec"},
{file = "deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d"},
]
[package.dependencies]
wrapt = ">=1.10,<2"
[package.extras]
dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "setuptools ; python_version >= \"3.12\"", "tox"]
[[package]]
name = "distlib"
version = "0.3.9"
@@ -2330,7 +2324,7 @@ description = "Lightweight in-process concurrent programming"
optional = false
python-versions = ">=3.9"
groups = ["main"]
markers = "python_version >= \"3.12\""
markers = "python_version == \"3.12\" or python_version == \"3.13\""
files = [
{file = "greenlet-3.2.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c49e9f7c6f625507ed83a7485366b46cbe325717c60837f7244fc99ba16ba9d6"},
{file = "greenlet-3.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3cc1a3ed00ecfea8932477f729a9f616ad7347a5e55d50929efa50a86cb7be7"},
@@ -2864,6 +2858,18 @@ perf = ["ipython"]
test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
type = ["pytest-mypy"]
[[package]]
name = "inflection"
version = "0.5.1"
description = "A port of Ruby on Rails inflector to Python"
optional = false
python-versions = ">=3.5"
groups = ["main"]
files = [
{file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"},
{file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"},
]
[[package]]
name = "iniconfig"
version = "2.1.0"
@@ -3103,7 +3109,7 @@ description = "Low-level, pure Python DBus protocol wrapper."
optional = false
python-versions = ">=3.7"
groups = ["dev"]
markers = "sys_platform == \"linux\" and platform_machine != \"ppc64le\" and platform_machine != \"s390x\""
markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\""
files = [
{file = "jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683"},
{file = "jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732"},
@@ -3799,6 +3805,91 @@ extra-proxy = ["azure-identity (>=1.15.0,<2.0.0)", "azure-keyvault-secrets (>=4.
proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", "boto3 (==1.34.34)", "cryptography (>=43.0.1,<44.0.0)", "fastapi (>=0.115.5,<0.116.0)", "fastapi-sso (>=0.16.0,<0.17.0)", "gunicorn (>=23.0.0,<24.0.0)", "litellm-enterprise (==0.1.9)", "litellm-proxy-extras (==0.2.6)", "mcp (==1.9.3) ; python_version >= \"3.10\"", "orjson (>=3.9.7,<4.0.0)", "pynacl (>=1.5.0,<2.0.0)", "python-multipart (>=0.0.18,<0.0.19)", "pyyaml (>=6.0.1,<7.0.0)", "rich (==13.7.1)", "rq", "uvicorn (>=0.29.0,<0.30.0)", "uvloop (>=0.21.0,<0.22.0) ; sys_platform != \"win32\"", "websockets (>=13.1.0,<14.0.0)"]
utils = ["numpydoc"]
[[package]]
name = "lmnr"
version = "0.6.16"
description = "Python SDK for Laminar"
optional = false
python-versions = "<4,>=3.10"
groups = ["main"]
files = [
{file = "lmnr-0.6.16-py3-none-any.whl", hash = "sha256:9bd964147befd775fa667731ed0022f23d829d67bb7f0e28ccda57f062795e9c"},
{file = "lmnr-0.6.16.tar.gz", hash = "sha256:5001cdf487af169dffc78658b46427b579f28b9ec541c2f220a3c7aabe3e1f0a"},
]
[package.dependencies]
argparse = ">=1.0"
grpcio = ">=1"
httpx = ">=0.25.0"
opentelemetry-api = ">=1.33.0"
opentelemetry-exporter-otlp-proto-grpc = ">=1.33.0"
opentelemetry-exporter-otlp-proto-http = ">=1.33.0"
opentelemetry-instrumentation-alephalpha = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-anthropic = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-bedrock = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-chromadb = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-cohere = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-crewai = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-google-generativeai = {version = "<0.40.10", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-groq = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-haystack = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-lancedb = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-langchain = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-llamaindex = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-marqo = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-mcp = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-milvus = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-mistralai = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-ollama = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-openai = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-pinecone = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-qdrant = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-replicate = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-sagemaker = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-threading = ">=0.54b0"
opentelemetry-instrumentation-together = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-transformers = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-vertexai = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-watsonx = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-instrumentation-weaviate = {version = ">=0.40.12", optional = true, markers = "extra == \"all\""}
opentelemetry-sdk = ">=1.33.0"
opentelemetry-semantic-conventions = ">=0.54b0"
opentelemetry-semantic-conventions-ai = ">=0.4.8"
pydantic = ">=2.0.3,<3.0.0"
python-dotenv = ">=1.0"
tenacity = ">=8.0"
tqdm = ">=4.0"
[package.extras]
alephalpha = ["opentelemetry-instrumentation-alephalpha (>=0.40.12)"]
all = ["opentelemetry-instrumentation-alephalpha (>=0.40.12)", "opentelemetry-instrumentation-anthropic (>=0.40.12)", "opentelemetry-instrumentation-bedrock (>=0.40.12)", "opentelemetry-instrumentation-chromadb (>=0.40.12)", "opentelemetry-instrumentation-cohere (>=0.40.12)", "opentelemetry-instrumentation-crewai (>=0.40.12)", "opentelemetry-instrumentation-google-generativeai (<0.40.10)", "opentelemetry-instrumentation-groq (>=0.40.12)", "opentelemetry-instrumentation-haystack (>=0.40.12)", "opentelemetry-instrumentation-lancedb (>=0.40.12)", "opentelemetry-instrumentation-langchain (>=0.40.12)", "opentelemetry-instrumentation-llamaindex (>=0.40.12)", "opentelemetry-instrumentation-marqo (>=0.40.12)", "opentelemetry-instrumentation-mcp (>=0.40.12)", "opentelemetry-instrumentation-milvus (>=0.40.12)", "opentelemetry-instrumentation-mistralai (>=0.40.12)", "opentelemetry-instrumentation-ollama (>=0.40.12)", "opentelemetry-instrumentation-openai (>=0.40.12)", "opentelemetry-instrumentation-pinecone (>=0.40.12)", "opentelemetry-instrumentation-qdrant (>=0.40.12)", "opentelemetry-instrumentation-replicate (>=0.40.12)", "opentelemetry-instrumentation-sagemaker (>=0.40.12)", "opentelemetry-instrumentation-together (>=0.40.12)", "opentelemetry-instrumentation-transformers (>=0.40.12)", "opentelemetry-instrumentation-vertexai (>=0.40.12)", "opentelemetry-instrumentation-watsonx (>=0.40.12)", "opentelemetry-instrumentation-weaviate (>=0.40.12)"]
anthropic = ["opentelemetry-instrumentation-anthropic (>=0.40.12)"]
bedrock = ["opentelemetry-instrumentation-bedrock (>=0.40.12)"]
chromadb = ["opentelemetry-instrumentation-chromadb (>=0.40.12)"]
cohere = ["opentelemetry-instrumentation-cohere (>=0.40.12)"]
crewai = ["opentelemetry-instrumentation-crewai (>=0.40.12)"]
google-generativeai = ["opentelemetry-instrumentation-google-generativeai (<0.40.10)"]
groq = ["opentelemetry-instrumentation-groq (>=0.40.12)"]
haystack = ["opentelemetry-instrumentation-haystack (>=0.40.12)"]
lancedb = ["opentelemetry-instrumentation-lancedb (>=0.40.12)"]
langchain = ["opentelemetry-instrumentation-langchain (>=0.40.12)"]
llamaindex = ["opentelemetry-instrumentation-llamaindex (>=0.40.12)"]
marqo = ["opentelemetry-instrumentation-marqo (>=0.40.12)"]
mcp = ["opentelemetry-instrumentation-mcp (>=0.40.12)"]
milvus = ["opentelemetry-instrumentation-milvus (>=0.40.12)"]
mistralai = ["opentelemetry-instrumentation-mistralai (>=0.40.12)"]
ollama = ["opentelemetry-instrumentation-ollama (>=0.40.12)"]
openai = ["opentelemetry-instrumentation-openai (>=0.40.12)"]
pinecone = ["opentelemetry-instrumentation-pinecone (>=0.40.12)"]
qdrant = ["opentelemetry-instrumentation-qdrant (>=0.40.12)"]
replicate = ["opentelemetry-instrumentation-replicate (>=0.40.12)"]
sagemaker = ["opentelemetry-instrumentation-sagemaker (>=0.40.12)"]
together = ["opentelemetry-instrumentation-together (>=0.40.12)"]
transformers = ["opentelemetry-instrumentation-transformers (>=0.40.12)"]
vertexai = ["opentelemetry-instrumentation-vertexai (>=0.40.12)"]
watsonx = ["opentelemetry-instrumentation-watsonx (>=0.40.12)"]
weaviate = ["opentelemetry-instrumentation-weaviate (>=0.40.12)"]
[[package]]
name = "mako"
version = "1.3.10"
@@ -4649,7 +4740,7 @@ description = "ONNX Runtime is a runtime accelerator for Machine Learning models
optional = false
python-versions = ">=3.10"
groups = ["main"]
markers = "python_version >= \"3.12\""
markers = "python_version == \"3.12\" or python_version == \"3.13\""
files = [
{file = "onnxruntime-1.22.0-cp310-cp310-macosx_13_0_universal2.whl", hash = "sha256:85d8826cc8054e4d6bf07f779dc742a363c39094015bdad6a08b3c18cfe0ba8c"},
{file = "onnxruntime-1.22.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:468c9502a12f6f49ec335c2febd22fdceecc1e4cc96dfc27e419ba237dff5aff"},
@@ -4743,19 +4834,664 @@ openapi-schema-validator = ">=0.6.0,<0.7.0"
[[package]]
name = "opentelemetry-api"
version = "1.32.1"
version = "1.34.1"
description = "OpenTelemetry Python API"
optional = false
python-versions = ">=3.8"
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_api-1.32.1-py3-none-any.whl", hash = "sha256:bbd19f14ab9f15f0e85e43e6a958aa4cb1f36870ee62b7fd205783a112012724"},
{file = "opentelemetry_api-1.32.1.tar.gz", hash = "sha256:a5be71591694a4d9195caf6776b055aa702e964d961051a0715d05f8632c32fb"},
{file = "opentelemetry_api-1.34.1-py3-none-any.whl", hash = "sha256:b7df4cb0830d5a6c29ad0c0691dbae874d8daefa934b8b1d642de48323d32a8c"},
{file = "opentelemetry_api-1.34.1.tar.gz", hash = "sha256:64f0bd06d42824843731d05beea88d4d4b6ae59f9fe347ff7dfa2cc14233bbb3"},
]
[package.dependencies]
deprecated = ">=1.2.6"
importlib-metadata = ">=6.0,<8.7.0"
importlib-metadata = ">=6.0,<8.8.0"
typing-extensions = ">=4.5.0"
[[package]]
name = "opentelemetry-exporter-otlp-proto-common"
version = "1.34.1"
description = "OpenTelemetry Protobuf encoding"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_exporter_otlp_proto_common-1.34.1-py3-none-any.whl", hash = "sha256:8e2019284bf24d3deebbb6c59c71e6eef3307cd88eff8c633e061abba33f7e87"},
{file = "opentelemetry_exporter_otlp_proto_common-1.34.1.tar.gz", hash = "sha256:b59a20a927facd5eac06edaf87a07e49f9e4a13db487b7d8a52b37cb87710f8b"},
]
[package.dependencies]
opentelemetry-proto = "1.34.1"
[[package]]
name = "opentelemetry-exporter-otlp-proto-grpc"
version = "1.34.1"
description = "OpenTelemetry Collector Protobuf over gRPC Exporter"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_exporter_otlp_proto_grpc-1.34.1-py3-none-any.whl", hash = "sha256:04bb8b732b02295be79f8a86a4ad28fae3d4ddb07307a98c7aa6f331de18cca6"},
{file = "opentelemetry_exporter_otlp_proto_grpc-1.34.1.tar.gz", hash = "sha256:7c841b90caa3aafcfc4fee58487a6c71743c34c6dc1787089d8b0578bbd794dd"},
]
[package.dependencies]
googleapis-common-protos = ">=1.52,<2.0"
grpcio = [
{version = ">=1.63.2,<2.0.0", markers = "python_version < \"3.13\""},
{version = ">=1.66.2,<2.0.0", markers = "python_version >= \"3.13\""},
]
opentelemetry-api = ">=1.15,<2.0"
opentelemetry-exporter-otlp-proto-common = "1.34.1"
opentelemetry-proto = "1.34.1"
opentelemetry-sdk = ">=1.34.1,<1.35.0"
typing-extensions = ">=4.5.0"
[[package]]
name = "opentelemetry-exporter-otlp-proto-http"
version = "1.34.1"
description = "OpenTelemetry Collector Protobuf over HTTP Exporter"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_exporter_otlp_proto_http-1.34.1-py3-none-any.whl", hash = "sha256:5251f00ca85872ce50d871f6d3cc89fe203b94c3c14c964bbdc3883366c705d8"},
{file = "opentelemetry_exporter_otlp_proto_http-1.34.1.tar.gz", hash = "sha256:aaac36fdce46a8191e604dcf632e1f9380c7d5b356b27b3e0edb5610d9be28ad"},
]
[package.dependencies]
googleapis-common-protos = ">=1.52,<2.0"
opentelemetry-api = ">=1.15,<2.0"
opentelemetry-exporter-otlp-proto-common = "1.34.1"
opentelemetry-proto = "1.34.1"
opentelemetry-sdk = ">=1.34.1,<1.35.0"
requests = ">=2.7,<3.0"
typing-extensions = ">=4.5.0"
[[package]]
name = "opentelemetry-instrumentation"
version = "0.55b1"
description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation-0.55b1-py3-none-any.whl", hash = "sha256:cbb1496b42bc394e01bc63701b10e69094e8564e281de063e4328d122cc7a97e"},
{file = "opentelemetry_instrumentation-0.55b1.tar.gz", hash = "sha256:2dc50aa207b9bfa16f70a1a0571e011e737a9917408934675b89ef4d5718c87b"},
]
[package.dependencies]
opentelemetry-api = ">=1.4,<2.0"
opentelemetry-semantic-conventions = "0.55b1"
packaging = ">=18.0"
wrapt = ">=1.0.0,<2.0.0"
[[package]]
name = "opentelemetry-instrumentation-alephalpha"
version = "0.40.14"
description = "OpenTelemetry Aleph Alpha instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_alephalpha-0.40.14-py3-none-any.whl", hash = "sha256:2dfc50a7ab40edca2fecc18c38f3b7ef3942294bda2e8283298bbd51ec1f3f82"},
{file = "opentelemetry_instrumentation_alephalpha-0.40.14.tar.gz", hash = "sha256:a015d7697645e9275637152d1d94f2df8e3f7c9d1ee3f983f4987ffc927f186c"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-anthropic"
version = "0.40.14"
description = "OpenTelemetry Anthropic instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_anthropic-0.40.14-py3-none-any.whl", hash = "sha256:d516a7aaa4b81b6fa6585f3db7a84feacb288fc56721484c63422ea6a9119c00"},
{file = "opentelemetry_instrumentation_anthropic-0.40.14.tar.gz", hash = "sha256:5450cc52fbbd916c21fc74df511e93ce794e889fbd916f90decaa1240893419e"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-bedrock"
version = "0.40.14"
description = "OpenTelemetry Bedrock instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_bedrock-0.40.14-py3-none-any.whl", hash = "sha256:ba2a78bbc83f246f52bd1eaf2ed6d4a53ab37fad09ff0ca550b7f7bc3f0f9466"},
{file = "opentelemetry_instrumentation_bedrock-0.40.14.tar.gz", hash = "sha256:6e3be927922825992baf07e45521ed4f9cfd5d015e7d14714d478920241d6656"},
]
[package.dependencies]
anthropic = ">=0.17.0"
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
tokenizers = ">=0.13.0"
[[package]]
name = "opentelemetry-instrumentation-chromadb"
version = "0.40.14"
description = "OpenTelemetry Chroma DB instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_chromadb-0.40.14-py3-none-any.whl", hash = "sha256:ac721939d63c988f787e11f22e2df8003da4f8346c7485d7c25fb82a4edf5f9f"},
{file = "opentelemetry_instrumentation_chromadb-0.40.14.tar.gz", hash = "sha256:db2f01b324f95b5b69a6ad2152d855c1707290d3cd270702f3216cbae736c6d5"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-cohere"
version = "0.40.14"
description = "OpenTelemetry Cohere instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_cohere-0.40.14-py3-none-any.whl", hash = "sha256:23457fb8d0bffc405f1d22b940c49ac00358b2f5f5190466a2d687e62b819bf6"},
{file = "opentelemetry_instrumentation_cohere-0.40.14.tar.gz", hash = "sha256:4515396ca8b381fde45b7905db33a4da45a01c5346e4b4a567dff160bd85fb5e"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-crewai"
version = "0.40.14"
description = "OpenTelemetry crewAI instrumentation"
optional = false
python-versions = "<4,>=3.10"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_crewai-0.40.14-py3-none-any.whl", hash = "sha256:021ef20c0761a77be803623ce90e0697d17c27615d4aba8012d8b72982528641"},
{file = "opentelemetry_instrumentation_crewai-0.40.14.tar.gz", hash = "sha256:ce8b0140210c3a695a205bda1a6a0579c50aaf862598d20a5c3eebb7fb74401d"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-google-generativeai"
version = "0.40.9"
description = "OpenTelemetry Google Generative AI instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_google_generativeai-0.40.9-py3-none-any.whl", hash = "sha256:473ffe01f617b173072f71b1b092ac1932055817aa700e3a8fdfb1ca1085040b"},
{file = "opentelemetry_instrumentation_google_generativeai-0.40.9.tar.gz", hash = "sha256:4b901794a9690229fd5ebc3ce82addbdaa4b76123d8299652306ac8dcee892fa"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-groq"
version = "0.40.14"
description = "OpenTelemetry Groq instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_groq-0.40.14-py3-none-any.whl", hash = "sha256:f53342c8980d7546264e41cf4afecb604f4b590430dfe2d9d863b97225e2ee0a"},
{file = "opentelemetry_instrumentation_groq-0.40.14.tar.gz", hash = "sha256:f2f6b787382dac7309f28eed7f27a8ff6e36caf7e8fe85c02f09fc75b9967838"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-haystack"
version = "0.40.14"
description = "OpenTelemetry Haystack instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_haystack-0.40.14-py3-none-any.whl", hash = "sha256:b11c6e57c0c66dc9154f7c8328c5018501f268224c53307c0518a6e407d91cae"},
{file = "opentelemetry_instrumentation_haystack-0.40.14.tar.gz", hash = "sha256:e49be73ccb2302ebace9a28014ab20dbcaec6d00893358de54b9054202596f9b"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-lancedb"
version = "0.40.14"
description = "OpenTelemetry Lancedb instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_lancedb-0.40.14-py3-none-any.whl", hash = "sha256:3dc37d8b2791fe4769c1b8ffe90c9ccd53af57ccd0ec100ed3da387b60b88021"},
{file = "opentelemetry_instrumentation_lancedb-0.40.14.tar.gz", hash = "sha256:0907ddd3f8639880c2c65cb94789dc4ca0b0ef19a79173dd1278ab7fd80178a6"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-langchain"
version = "0.40.14"
description = "OpenTelemetry Langchain instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_langchain-0.40.14-py3-none-any.whl", hash = "sha256:f400d25b1c5fb03fcaabae40970a7980d9c45d2b22e0ceeb99ce62b7b3d3c6e2"},
{file = "opentelemetry_instrumentation_langchain-0.40.14.tar.gz", hash = "sha256:a196eef6990b98fc67acca945883e39fbdaf075f8a36636e7a9e580092f7c3ea"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-llamaindex"
version = "0.40.14"
description = "OpenTelemetry LlamaIndex instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_llamaindex-0.40.14-py3-none-any.whl", hash = "sha256:20362a9e94cf3a5632e62baaedd1f1a003674230d6a4352f2a83716751351267"},
{file = "opentelemetry_instrumentation_llamaindex-0.40.14.tar.gz", hash = "sha256:9916136126cd59c8360b189b022af6337f3ed091dccbf11317b045c452e5185b"},
]
[package.dependencies]
inflection = ">=0.5.1,<0.6.0"
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-marqo"
version = "0.40.14"
description = "OpenTelemetry Marqo instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_marqo-0.40.14-py3-none-any.whl", hash = "sha256:db93511f2a6990cf6cc3dcbb1279847f72723671503ca4a5a896c3595711e932"},
{file = "opentelemetry_instrumentation_marqo-0.40.14.tar.gz", hash = "sha256:1710e2d079ccb7e5aef9d204acde5bae002028a95865fec3e711ae1f07ffbc25"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-mcp"
version = "0.40.14"
description = "OpenTelemetry mcp instrumentation"
optional = false
python-versions = "<4,>=3.10"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_mcp-0.40.14-py3-none-any.whl", hash = "sha256:8ac37b7e138c48ea85cb67c8e737fb3b18b618650a7c2239731e6a7190586e65"},
{file = "opentelemetry_instrumentation_mcp-0.40.14.tar.gz", hash = "sha256:32ed438acc1e21d26e991ea5c5c9b03f381faf8d963878f2822e45e666a41a1c"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-milvus"
version = "0.40.14"
description = "OpenTelemetry Milvus instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_milvus-0.40.14-py3-none-any.whl", hash = "sha256:02c3c8e50558aed577d3527ca81904106a3ea86304b69fef9a2e8d7b2f9581a5"},
{file = "opentelemetry_instrumentation_milvus-0.40.14.tar.gz", hash = "sha256:7c7e3fb830acfac2a0b102c408f4c40f2c5b86e22cf12bebe35cc7555c612e5b"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-mistralai"
version = "0.40.14"
description = "OpenTelemetry Mistral AI instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_mistralai-0.40.14-py3-none-any.whl", hash = "sha256:be0360b8184d287aaf94e970ada56812ff6c313c23f78984f886948279ad2df7"},
{file = "opentelemetry_instrumentation_mistralai-0.40.14.tar.gz", hash = "sha256:17f77f82d3f3843a4c5d25c42899e729d572e1b1d5ae1947a0b8e8a9ef4f5665"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-ollama"
version = "0.40.14"
description = "OpenTelemetry Ollama instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_ollama-0.40.14-py3-none-any.whl", hash = "sha256:d38f31f8d06ef25acce34c490c8d113476781e2b2b2b50964c97c79d4fef3ad7"},
{file = "opentelemetry_instrumentation_ollama-0.40.14.tar.gz", hash = "sha256:6589aef14575e87f68e129e0f989742a8d751f029e56bccf158791202380e2cb"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-openai"
version = "0.40.14"
description = "OpenTelemetry OpenAI instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_openai-0.40.14-py3-none-any.whl", hash = "sha256:72319113370a018390e9c987dc3dac569380591fbaa5639c5e5cacd3f3165f4a"},
{file = "opentelemetry_instrumentation_openai-0.40.14.tar.gz", hash = "sha256:3ba8e36a3853833f5c0c6b3b8ffa0f1289e6423e0d428bd1c7b3f27abdc545f0"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
tiktoken = ">=0.6.0,<1"
[[package]]
name = "opentelemetry-instrumentation-pinecone"
version = "0.40.14"
description = "OpenTelemetry Pinecone instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_pinecone-0.40.14-py3-none-any.whl", hash = "sha256:a3cd747468ddb4a6f4caf249f3d7a21b61dc8c3fb9c44cb586943a7eec56ab3a"},
{file = "opentelemetry_instrumentation_pinecone-0.40.14.tar.gz", hash = "sha256:314be6cdc847dacde4a96d352c3739d809ed8753992e6e25f1e7d9586eb781d3"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-qdrant"
version = "0.40.14"
description = "OpenTelemetry Qdrant instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_qdrant-0.40.14-py3-none-any.whl", hash = "sha256:12666e657529977c4b08f78c869eba4868ff214c77cf6f40947b36934254a0c2"},
{file = "opentelemetry_instrumentation_qdrant-0.40.14.tar.gz", hash = "sha256:eef5b9a8a4a8069eca1d06652c2d5ba0fa9a012c5b2f48c7577507b5219528d0"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-replicate"
version = "0.40.14"
description = "OpenTelemetry Replicate instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_replicate-0.40.14-py3-none-any.whl", hash = "sha256:7f204bb5b36ee69c2068c3cdaac6ec9b49b449c07b2d39cb47157b672e59751d"},
{file = "opentelemetry_instrumentation_replicate-0.40.14.tar.gz", hash = "sha256:d010113254a1cdc142bc74e7feaff555344692eb808b46eebb25c56a26db5281"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-sagemaker"
version = "0.40.14"
description = "OpenTelemetry SageMaker instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_sagemaker-0.40.14-py3-none-any.whl", hash = "sha256:28d7cc2c43b77bb69f20d8902c0bede9b828f9bfb7aa8ebe75fd542dcb8a6545"},
{file = "opentelemetry_instrumentation_sagemaker-0.40.14.tar.gz", hash = "sha256:d1d31423a4d57239428d2b925e4801d61782b52adb9b80baf4e86c6f03b1ad06"},
]
[package.dependencies]
opentelemetry-api = ">=1.26.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-threading"
version = "0.55b1"
description = "Thread context propagation support for OpenTelemetry"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_threading-0.55b1-py3-none-any.whl", hash = "sha256:f865542b32b219c8fd01deb03b8c3c9ba2eb3f0501ae303338403fd2242962c7"},
{file = "opentelemetry_instrumentation_threading-0.55b1.tar.gz", hash = "sha256:4ed68502e7ed017bfc10b1f9e508cc5ccaea0e46ac1010f7f2541ab9c6eacd92"},
]
[package.dependencies]
opentelemetry-api = ">=1.12,<2.0"
opentelemetry-instrumentation = "0.55b1"
wrapt = ">=1.0.0,<2.0.0"
[[package]]
name = "opentelemetry-instrumentation-together"
version = "0.40.14"
description = "OpenTelemetry Together AI instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_together-0.40.14-py3-none-any.whl", hash = "sha256:7e5fe1793ab624fc8c104a46f707beabaaaec92666b0551c0ac80355ba324c17"},
{file = "opentelemetry_instrumentation_together-0.40.14.tar.gz", hash = "sha256:bdee203caa0e3a4dff5f20e0a7802860ea51d021a714e89de919091226fadb99"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-transformers"
version = "0.40.14"
description = "OpenTelemetry transformers instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_transformers-0.40.14-py3-none-any.whl", hash = "sha256:b7de54a27b4de8724981bb69c2cb4ec740e084dbea2ec834349b71b6d503c85d"},
{file = "opentelemetry_instrumentation_transformers-0.40.14.tar.gz", hash = "sha256:7dc3e11055a16c29e5bb9b0892deb9edb4927e4390d83c6678ca360af818fbff"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-vertexai"
version = "0.40.14"
description = "OpenTelemetry Vertex AI instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_vertexai-0.40.14-py3-none-any.whl", hash = "sha256:5146387a0060fbdec87a8cbbf5bee2aae7afb791cfd673fded2fa7394021cfb6"},
{file = "opentelemetry_instrumentation_vertexai-0.40.14.tar.gz", hash = "sha256:f6f8ecd47576575ff62d645d1b343cfbdc4143d7b3c4b1424605ab6278d5122b"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-watsonx"
version = "0.40.14"
description = "OpenTelemetry IBM Watsonx Instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_watsonx-0.40.14-py3-none-any.whl", hash = "sha256:119f0fc0e5a4dddac31a0ea9cfd7ea41398814923b3018836780fc4e46f930d1"},
{file = "opentelemetry_instrumentation_watsonx-0.40.14.tar.gz", hash = "sha256:e131f498b764fc76c1f433377b9ef554b12de604f2f6b8dd72e0440226034da7"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-instrumentation-weaviate"
version = "0.40.14"
description = "OpenTelemetry Weaviate instrumentation"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_instrumentation_weaviate-0.40.14-py3-none-any.whl", hash = "sha256:4ab8f786eb78394be37aed0df96ceefa46072d48f0aee7e9f8ad3526e04e23fd"},
{file = "opentelemetry_instrumentation_weaviate-0.40.14.tar.gz", hash = "sha256:539c62d542bcb2bf5e39a2939403397b1e898c852d5e343a3f348a9c33bfa7f5"},
]
[package.dependencies]
opentelemetry-api = ">=1.28.0,<2.0.0"
opentelemetry-instrumentation = ">=0.50b0"
opentelemetry-semantic-conventions = ">=0.50b0"
opentelemetry-semantic-conventions-ai = "0.4.9"
[[package]]
name = "opentelemetry-proto"
version = "1.34.1"
description = "OpenTelemetry Python Proto"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_proto-1.34.1-py3-none-any.whl", hash = "sha256:eb4bb5ac27f2562df2d6857fc557b3a481b5e298bc04f94cc68041f00cebcbd2"},
{file = "opentelemetry_proto-1.34.1.tar.gz", hash = "sha256:16286214e405c211fc774187f3e4bbb1351290b8dfb88e8948af209ce85b719e"},
]
[package.dependencies]
protobuf = ">=5.0,<6.0"
[[package]]
name = "opentelemetry-sdk"
version = "1.34.1"
description = "OpenTelemetry Python SDK"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_sdk-1.34.1-py3-none-any.whl", hash = "sha256:308effad4059562f1d92163c61c8141df649da24ce361827812c40abb2a1e96e"},
{file = "opentelemetry_sdk-1.34.1.tar.gz", hash = "sha256:8091db0d763fcd6098d4781bbc80ff0971f94e260739aa6afe6fd379cdf3aa4d"},
]
[package.dependencies]
opentelemetry-api = "1.34.1"
opentelemetry-semantic-conventions = "0.55b1"
typing-extensions = ">=4.5.0"
[[package]]
name = "opentelemetry-semantic-conventions"
version = "0.55b1"
description = "OpenTelemetry Semantic Conventions"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_semantic_conventions-0.55b1-py3-none-any.whl", hash = "sha256:5da81dfdf7d52e3d37f8fe88d5e771e191de924cfff5f550ab0b8f7b2409baed"},
{file = "opentelemetry_semantic_conventions-0.55b1.tar.gz", hash = "sha256:ef95b1f009159c28d7a7849f5cbc71c4c34c845bb514d66adfdf1b3fff3598b3"},
]
[package.dependencies]
opentelemetry-api = "1.34.1"
typing-extensions = ">=4.5.0"
[[package]]
name = "opentelemetry-semantic-conventions-ai"
version = "0.4.9"
description = "OpenTelemetry Semantic Conventions Extension for Large Language Models"
optional = false
python-versions = "<4,>=3.9"
groups = ["main"]
files = [
{file = "opentelemetry_semantic_conventions_ai-0.4.9-py3-none-any.whl", hash = "sha256:71149e46a72554ae17de46bca6c11ba540c19c89904bd4cc3111aac6edf10315"},
{file = "opentelemetry_semantic_conventions_ai-0.4.9.tar.gz", hash = "sha256:54a0b901959e2de5124384925846bac2ea0a6dab3de7e501ba6aecf5e293fe04"},
]
[[package]]
name = "orjson"
@@ -5149,7 +5885,7 @@ description = "A high-level API to automate web browsers"
optional = false
python-versions = ">=3.9"
groups = ["main"]
markers = "python_version >= \"3.12\""
markers = "python_version == \"3.12\" or python_version == \"3.13\""
files = [
{file = "playwright-1.52.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:19b2cb9d4794062008a635a99bd135b03ebb782d460f96534a91cb583f549512"},
{file = "playwright-1.52.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0797c0479cbdc99607412a3c486a3a2ec9ddc77ac461259fd2878c975bcbb94a"},
@@ -5396,21 +6132,23 @@ testing = ["google-api-core (>=1.31.5)"]
[[package]]
name = "protobuf"
version = "6.31.1"
version = "5.29.5"
description = ""
optional = false
python-versions = ">=3.9"
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9"},
{file = "protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447"},
{file = "protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402"},
{file = "protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39"},
{file = "protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6"},
{file = "protobuf-6.31.1-cp39-cp39-win32.whl", hash = "sha256:0414e3aa5a5f3ff423828e1e6a6e907d6c65c1d5b7e6e975793d5590bdeecc16"},
{file = "protobuf-6.31.1-cp39-cp39-win_amd64.whl", hash = "sha256:8764cf4587791e7564051b35524b72844f845ad0bb011704c3736cce762d8fe9"},
{file = "protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e"},
{file = "protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a"},
{file = "protobuf-5.29.5-cp310-abi3-win32.whl", hash = "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079"},
{file = "protobuf-5.29.5-cp310-abi3-win_amd64.whl", hash = "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc"},
{file = "protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671"},
{file = "protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015"},
{file = "protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61"},
{file = "protobuf-5.29.5-cp38-cp38-win32.whl", hash = "sha256:ef91363ad4faba7b25d844ef1ada59ff1604184c0bcd8b39b8a6bef15e1af238"},
{file = "protobuf-5.29.5-cp38-cp38-win_amd64.whl", hash = "sha256:7318608d56b6402d2ea7704ff1e1e4597bee46d760e7e4dd42a3d45e24b87f2e"},
{file = "protobuf-5.29.5-cp39-cp39-win32.whl", hash = "sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736"},
{file = "protobuf-5.29.5-cp39-cp39-win_amd64.whl", hash = "sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353"},
{file = "protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5"},
{file = "protobuf-5.29.5.tar.gz", hash = "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84"},
]
[[package]]
@@ -5444,7 +6182,7 @@ description = "PostgreSQL database adapter for Python"
optional = false
python-versions = ">=3.7"
groups = ["main"]
markers = "python_version < \"3.13\""
markers = "python_version == \"3.12\" or python_version == \"3.11\""
files = [
{file = "psycopg-3.1.18-py3-none-any.whl", hash = "sha256:4d5a0a5a8590906daa58ebd5f3cfc34091377354a1acced269dd10faf55da60e"},
{file = "psycopg-3.1.18.tar.gz", hash = "sha256:31144d3fb4c17d78094d9e579826f047d4af1da6a10427d91dfcfb6ecdf6f12b"},
@@ -5497,7 +6235,7 @@ description = "PostgreSQL database adapter for Python -- C optimisation distribu
optional = false
python-versions = ">=3.7"
groups = ["main"]
markers = "python_version < \"3.13\" and implementation_name != \"pypy\""
markers = "(python_version == \"3.12\" or python_version == \"3.11\") and implementation_name != \"pypy\""
files = [
{file = "psycopg_binary-3.1.18-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c323103dfa663b88204cf5f028e83c77d7a715f9b6f51d2bbc8184b99ddd90a"},
{file = "psycopg_binary-3.1.18-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:887f8d856c91510148be942c7acd702ccf761a05f59f8abc123c22ab77b5a16c"},
@@ -5947,7 +6685,7 @@ description = "A rough port of Node.js's EventEmitter to Python with a few trick
optional = false
python-versions = ">=3.8"
groups = ["main"]
markers = "python_version >= \"3.12\""
markers = "python_version == \"3.12\" or python_version == \"3.13\""
files = [
{file = "pyee-13.0.0-py3-none-any.whl", hash = "sha256:48195a3cddb3b1515ce0695ed76036b5ccc2ef3a9f963ff9f77aec0139845498"},
{file = "pyee-13.0.0.tar.gz", hash = "sha256:b391e3c5a434d1f5118a25615001dbc8f669cf410ab67d04c4d4e07c55481c37"},
@@ -6231,7 +6969,7 @@ description = "A (partial) reimplementation of pywin32 using ctypes/cffi"
optional = false
python-versions = ">=3.6"
groups = ["dev"]
markers = "sys_platform == \"win32\" and platform_machine != \"ppc64le\" and platform_machine != \"s390x\""
markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"win32\""
files = [
{file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"},
{file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"},
@@ -6938,7 +7676,7 @@ description = "Python bindings to FreeDesktop.org Secret Service API"
optional = false
python-versions = ">=3.6"
groups = ["dev"]
markers = "sys_platform == \"linux\" and platform_machine != \"ppc64le\" and platform_machine != \"s390x\""
markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\""
files = [
{file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"},
{file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"},
@@ -7374,6 +8112,22 @@ grpc = ["grpcio (>=1.48.2,<2)"]
opentelemetry = ["opentelemetry-api (>=1.11.1,<2)", "opentelemetry-sdk (>=1.11.1,<2)"]
pydantic = ["pydantic (>=2.0.0,<3)"]
[[package]]
name = "tenacity"
version = "9.1.2"
description = "Retry code until it succeeds"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"},
{file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"},
]
[package.extras]
doc = ["reno", "sphinx"]
test = ["pytest", "tornado (>=4.5)", "typeguard"]
[[package]]
name = "terminado"
version = "0.18.1"
@@ -8258,7 +9012,7 @@ description = "Fast implementation of asyncio event loop on top of libuv"
optional = false
python-versions = ">=3.8.0"
groups = ["main"]
markers = "platform_python_implementation != \"PyPy\" and sys_platform != \"win32\" and sys_platform != \"cygwin\""
markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\""
files = [
{file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f"},
{file = "uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d"},
@@ -8858,4 +9612,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.11,<3.14"
content-hash = "cf74ed450038ba2efd72f86b361f135b6cab2e2a4f275061d69d7cbb0ed7dfb5"
content-hash = "3bd6f84bd33a4a4f94a2fb7047fa1b089162a4743a1448355807003b83fb575f"

View File

@@ -77,6 +77,7 @@ types-boto3 = {extras = ["full"], version = "^1.38.31"}
lark = "^1.2.2"
libcst = "^1.8.2"
curlparser = "^0.1.0"
lmnr = {extras = ["all"], version = "^0.6.16"}
[tool.poetry.group.dev.dependencies]
isort = "^5.13.2"

View File

@@ -284,6 +284,12 @@ class Settings(BaseSettings):
The secret used to sign the email/identity of the user.
"""
# Trace settings
TRACE_ENABLED: bool = False
TRACE_PROVIDER: str = "lmnr"
TRACE_PROVIDER_HOST: str | None = None
TRACE_PROVIDER_API_KEY: str = "fillmein"
def get_model_name_to_llm_key(self) -> dict[str, dict[str, str]]:
"""
Keys are model names available to blocks in the frontend. These map to key names

View File

@@ -71,6 +71,7 @@ from skyvern.forge.sdk.models import Step, StepStatus
from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.schemas.tasks import Task, TaskRequest, TaskResponse, TaskStatus
from skyvern.forge.sdk.trace import TraceManager
from skyvern.forge.sdk.workflow.context_manager import WorkflowRunContext
from skyvern.forge.sdk.workflow.models.block import ActionBlock, BaseTaskBlock, ValidationBlock
from skyvern.forge.sdk.workflow.models.workflow import Workflow, WorkflowRun, WorkflowRunStatus
@@ -268,6 +269,9 @@ class ForgeAgent:
operations = await app.AGENT_FUNCTION.generate_async_operations(organization, task, page)
self.async_operation_pool.add_operations(task.task_id, operations)
@TraceManager.traced_async(
ignore_inputs=["api_key", "close_browser_on_completion", "task_block", "cua_response", "llm_caller"]
)
async def execute_step(
self,
organization: Organization,
@@ -428,8 +432,9 @@ class ForgeAgent:
if not llm_caller:
# create a new UI-TARS llm_caller
llm_key = task.llm_key or settings.VOLCENGINE_CUA_LLM_KEY
llm_caller = UITarsLLMCaller(llm_key=llm_key, screenshot_scaling_enabled=True)
llm_caller.initialize_conversation(task)
ui_tars_llm_caller = UITarsLLMCaller(llm_key=llm_key, screenshot_scaling_enabled=True)
ui_tars_llm_caller.initialize_conversation(task)
llm_caller = ui_tars_llm_caller
# TODO: remove the code after migrating everything to llm callers
# currently, only anthropic cua and ui_tars tasks use llm_caller
@@ -829,6 +834,9 @@ class ForgeAgent:
)
return True
@TraceManager.traced_async(
ignore_inputs=["browser_state", "organization", "task_block", "cua_response", "llm_caller"]
)
async def agent_step(
self,
task: Task,

View File

@@ -18,6 +18,7 @@ from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.models import Step, StepStatus
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.schemas.tasks import Task, TaskStatus
from skyvern.forge.sdk.trace import TraceManager
from skyvern.forge.sdk.workflow.models.block import BlockTypeVar
from skyvern.webeye.browser_factory import BrowserState
from skyvern.webeye.scraper.scraper import ELEMENT_NODE_ATTRIBUTES, CleanupElementTreeFunc, json_to_html
@@ -538,6 +539,7 @@ class AgentFunction:
) -> CleanupElementTreeFunc:
MAX_ELEMENT_CNT = 3000
@TraceManager.traced_async(ignore_input=True)
async def cleanup_element_tree_func(frame: Page | Frame, url: str, element_tree: list[dict]) -> list[dict]:
"""
Remove rect and attribute.unique_id from the elements.

View File

@@ -15,6 +15,8 @@ from skyvern.forge.sdk.db.client import AgentDB
from skyvern.forge.sdk.experimentation.providers import BaseExperimentationProvider, NoOpExperimentationProvider
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.settings_manager import SettingsManager
from skyvern.forge.sdk.trace import TraceManager
from skyvern.forge.sdk.trace.lmnr import LaminarTrace
from skyvern.forge.sdk.workflow.context_manager import WorkflowContextManager
from skyvern.forge.sdk.workflow.service import WorkflowService
from skyvern.webeye.browser_manager import BrowserManager
@@ -76,3 +78,7 @@ authentication_function: Callable[[str], Awaitable[Organization]] | None = None
setup_api_app: Callable[[FastAPI], None] | None = None
agent = ForgeAgent()
if SettingsManager.get_settings().TRACE_ENABLED:
if SettingsManager.get_settings().TRACE_PROVIDER == "lmnr":
TraceManager.set_trace_provider(LaminarTrace(api_key=SettingsManager.get_settings().TRACE_PROVIDER_API_KEY))

View File

@@ -31,6 +31,7 @@ from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.models import Step
from skyvern.forge.sdk.schemas.ai_suggestions import AISuggestion
from skyvern.forge.sdk.schemas.task_v2 import TaskV2, Thought
from skyvern.forge.sdk.trace import TraceManager
from skyvern.utils.image_resizer import Resolution, get_resize_target_dimension, resize_screenshots
LOG = structlog.get_logger()
@@ -89,6 +90,7 @@ class LLMAPIHandlerFactory:
)
main_model_group = llm_config.main_model_group
@TraceManager.traced_async(tags=[llm_key], ignore_inputs=["prompt", "screenshots", "parameters"])
async def llm_api_handler_with_router_and_fallback(
prompt: str,
prompt_name: str,
@@ -286,6 +288,7 @@ class LLMAPIHandlerFactory:
assert isinstance(llm_config, LLMConfig)
@TraceManager.traced_async(tags=[llm_key], ignore_inputs=["prompt", "screenshots", "parameters"])
async def llm_api_handler(
prompt: str,
prompt_name: str,
@@ -743,6 +746,7 @@ class LLMCaller:
return get_resize_target_dimension(window_dimension)
return self.screenshot_resize_target_dimension
@TraceManager.traced_async(ignore_input=True)
async def _dispatch_llm_call(
self,
messages: list[dict[str, Any]],

View File

@@ -0,0 +1,92 @@
from functools import wraps
from typing import Any, Awaitable, Callable, ParamSpec, TypeVar
from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.settings_manager import SettingsManager
from skyvern.forge.sdk.trace.base import BaseTrace, NoOpTrace
P = ParamSpec("P")
R = TypeVar("R")
class TraceManager:
__instance: BaseTrace = NoOpTrace()
@staticmethod
def traced_async(
*,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**trace_parameters: Any,
) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]:
def decorator(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[R]]:
@wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
new_metadata: dict[str, Any] = metadata or {}
user_id: str | None = None
context = skyvern_context.current()
if context is not None:
new_metadata["request_id"] = context.request_id
new_metadata["organization_id"] = context.organization_id
new_metadata["task_id"] = context.task_id
new_metadata["workflow_id"] = context.workflow_id
new_metadata["workflow_run_id"] = context.workflow_run_id
new_metadata["task_v2_id"] = context.task_v2_id
new_metadata["run_id"] = context.run_id
new_metadata["organization_name"] = context.organization_name
user_id = context.run_id
new_tags: list[str] = tags or []
new_tags.append(SettingsManager.get_settings().ENV)
return await TraceManager.__instance.traced_async(
name=name, metadata=new_metadata, tags=new_tags, user_id=user_id, **trace_parameters
)(func)(*args, **kwargs)
return wrapper
return decorator
@staticmethod
def traced(
*,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**trace_parameters: Any,
) -> Callable[[Callable[P, R]], Callable[P, R]]:
def decorator(func: Callable[P, R]) -> Callable[P, R]:
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
new_metadata: dict[str, Any] = metadata or {}
user_id: str | None = None
context = skyvern_context.current()
if context is not None:
new_metadata["request_id"] = context.request_id
new_metadata["organization_id"] = context.organization_id
new_metadata["task_id"] = context.task_id
new_metadata["workflow_id"] = context.workflow_id
new_metadata["workflow_run_id"] = context.workflow_run_id
new_metadata["task_v2_id"] = context.task_v2_id
new_metadata["run_id"] = context.run_id
new_metadata["organization_name"] = context.organization_name
user_id = context.run_id
new_tags: list[str] = tags or []
new_tags.append(SettingsManager.get_settings().ENV)
return TraceManager.__instance.traced(
name=name, metadata=new_metadata, tags=new_tags, user_id=user_id, **trace_parameters
)(func)(*args, **kwargs)
return wrapper
return decorator
@staticmethod
def get_trace_provider() -> BaseTrace:
return TraceManager.__instance
@staticmethod
def set_trace_provider(trace_provider: BaseTrace) -> None:
TraceManager.__instance = trace_provider

View File

@@ -0,0 +1,47 @@
from abc import ABC, abstractmethod
from typing import Any, Awaitable, Callable, ParamSpec, TypeVar
P = ParamSpec("P")
R = TypeVar("R")
class BaseTrace(ABC):
@abstractmethod
def traced(
self,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**kwargs: Any,
) -> Callable[[Callable[P, R]], Callable[P, R]]:
pass
@abstractmethod
def traced_async(
self,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**kwargs: Any,
) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]:
pass
class NoOpTrace(BaseTrace):
def traced(
self,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**kwargs: Any,
) -> Callable[[Callable[P, R]], Callable[P, R]]:
return lambda func: func
def traced_async(
self,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**kwargs: Any,
) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]:
return lambda func: func

View File

@@ -0,0 +1,33 @@
from typing import Any, Awaitable, Callable, ParamSpec, TypeVar
import litellm
from lmnr import Instruments, Laminar, LaminarLiteLLMCallback, observe
from skyvern.forge.sdk.trace.base import BaseTrace
P = ParamSpec("P")
R = TypeVar("R")
class LaminarTrace(BaseTrace):
def __init__(self, api_key: str) -> None:
Laminar.initialize(project_api_key=api_key, disabled_instruments={Instruments.SKYVERN})
litellm.callbacks.append(LaminarLiteLLMCallback())
def traced(
self,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**kwargs: Any,
) -> Callable[[Callable[P, R]], Callable[P, R]]:
return observe(name=name, ignore_output=True, metadata=metadata, tags=tags, **kwargs)
def traced_async(
self,
name: str | None = None,
metadata: dict[str, Any] | None = None,
tags: list[str] | None = None,
**kwargs: Any,
) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]:
return observe(name=name, ignore_output=True, metadata=metadata, tags=tags, **kwargs)

View File

@@ -54,6 +54,7 @@ from skyvern.forge.sdk.db.enums import TaskType
from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.schemas.task_v2 import TaskV2Status
from skyvern.forge.sdk.schemas.tasks import Task, TaskOutput, TaskStatus
from skyvern.forge.sdk.trace import TraceManager
from skyvern.forge.sdk.workflow.context_manager import BlockMetadata, WorkflowRunContext
from skyvern.forge.sdk.workflow.exceptions import (
CustomizedCodeException,
@@ -292,6 +293,7 @@ class Block(BaseModel, abc.ABC):
organization_id=organization_id,
)
@TraceManager.traced_async(ignore_inputs=["kwargs"])
async def execute_safe(
self,
workflow_run_id: str,

View File

@@ -30,6 +30,7 @@ from skyvern.forge.sdk.schemas.files import FileInfo
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.schemas.tasks import Task
from skyvern.forge.sdk.schemas.workflow_runs import WorkflowRunBlock, WorkflowRunTimeline, WorkflowRunTimelineType
from skyvern.forge.sdk.trace import TraceManager
from skyvern.forge.sdk.workflow.exceptions import (
ContextParameterSourceNotDefined,
InvalidWaitBlockTime,
@@ -248,6 +249,7 @@ class WorkflowService:
return workflow_run
@TraceManager.traced_async(ignore_inputs=["organization", "api_key"])
async def execute_workflow(
self,
workflow_run_id: str,

View File

@@ -30,6 +30,7 @@ from skyvern.forge.sdk.db.enums import OrganizationAuthTokenType
from skyvern.forge.sdk.schemas.organizations import Organization
from skyvern.forge.sdk.schemas.task_v2 import TaskV2, TaskV2Metadata, TaskV2Status, ThoughtScenario, ThoughtType
from skyvern.forge.sdk.schemas.workflow_runs import WorkflowRunTimeline, WorkflowRunTimelineType
from skyvern.forge.sdk.trace import TraceManager
from skyvern.forge.sdk.workflow.models.block import (
BlockResult,
BlockStatus,
@@ -298,6 +299,7 @@ async def initialize_task_v2(
return task_v2
@TraceManager.traced_async(ignore_inputs=["organization"])
async def run_task_v2(
organization: Organization,
task_v2_id: str,

View File

@@ -71,6 +71,7 @@ from skyvern.forge.sdk.models import Step
from skyvern.forge.sdk.schemas.tasks import Task
from skyvern.forge.sdk.services.bitwarden import BitwardenConstants
from skyvern.forge.sdk.services.credentials import OnePasswordConstants
from skyvern.forge.sdk.trace import TraceManager
from skyvern.services.task_v1_service import is_cua_task
from skyvern.utils.prompt_engine import CheckPhoneNumberFormatResponse, load_prompt_with_elements
from skyvern.webeye.actions import actions, handler_utils
@@ -340,6 +341,7 @@ class ActionHandler:
cls._teardown_action_types[action_type] = handler
@staticmethod
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_action(
scraped_page: ScrapedPage,
task: Task,
@@ -459,6 +461,7 @@ def check_for_invalid_web_action(
return []
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_solve_captcha_action(
action: actions.SolveCaptchaAction,
page: Page,
@@ -474,6 +477,7 @@ async def handle_solve_captcha_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_click_action(
action: actions.ClickAction,
page: Page,
@@ -650,6 +654,7 @@ async def handle_click_action(
return results
@TraceManager.traced_async(ignore_inputs=["anchor_element", "scraped_page", "page", "incremental_scraped", "dom"])
async def handle_sequential_click_for_dropdown(
action: actions.ClickAction,
anchor_element: SkyvernElement,
@@ -722,6 +727,7 @@ async def handle_sequential_click_for_dropdown(
)
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_click_to_download_file_action(
action: actions.ClickAction,
page: Page,
@@ -814,6 +820,7 @@ async def handle_click_to_download_file_action(
return [ActionSuccess(download_triggered=True)]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_input_text_action(
action: actions.InputTextAction,
page: Page,
@@ -1135,6 +1142,7 @@ async def handle_input_text_action(
await skyvern_element.press_key("Tab")
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_upload_file_action(
action: actions.UploadFileAction,
page: Page,
@@ -1212,6 +1220,7 @@ async def handle_upload_file_action(
# This function is deprecated. Downloads are handled by the click action handler now.
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_download_file_action(
action: actions.DownloadFileAction,
page: Page,
@@ -1253,6 +1262,7 @@ async def handle_download_file_action(
return [ActionSuccess(data={"file_path": full_file_path})]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_null_action(
action: actions.NullAction,
page: Page,
@@ -1263,6 +1273,7 @@ async def handle_null_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_select_option_action(
action: actions.SelectOptionAction,
page: Page,
@@ -1600,6 +1611,7 @@ async def handle_select_option_action(
await incremental_scraped.stop_listen_dom_increment()
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_checkbox_action(
action: actions.CheckboxAction,
page: Page,
@@ -1628,6 +1640,7 @@ async def handle_checkbox_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_wait_action(
action: actions.WaitAction,
page: Page,
@@ -1639,6 +1652,7 @@ async def handle_wait_action(
return [ActionFailure(exception=Exception("Wait action is treated as a failure"))]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_terminate_action(
action: actions.TerminateAction,
page: Page,
@@ -1649,6 +1663,7 @@ async def handle_terminate_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_complete_action(
action: actions.CompleteAction,
page: Page,
@@ -1694,6 +1709,7 @@ async def handle_complete_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_extract_action(
action: actions.ExtractAction,
page: Page,
@@ -1715,6 +1731,7 @@ async def handle_extract_action(
return [ActionFailure(exception=Exception("No data extraction goal"))]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_scroll_action(
action: actions.ScrollAction,
page: Page,
@@ -1728,6 +1745,7 @@ async def handle_scroll_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_keypress_action(
action: actions.KeypressAction,
page: Page,
@@ -1787,6 +1805,7 @@ async def handle_keypress_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_move_action(
action: actions.MoveAction,
page: Page,
@@ -1798,6 +1817,7 @@ async def handle_move_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_drag_action(
action: actions.DragAction,
page: Page,
@@ -1815,6 +1835,7 @@ async def handle_drag_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_verification_code_action(
action: actions.VerificationCodeAction,
page: Page,
@@ -1833,6 +1854,7 @@ async def handle_verification_code_action(
return [ActionSuccess()]
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def handle_left_mouse_action(
action: actions.LeftMouseAction,
page: Page,
@@ -2092,6 +2114,7 @@ async def chain_click(
return [ActionFailure(WrongElementToUploadFile(action.element_id))]
@TraceManager.traced_async(ignore_inputs=["context", "page", "dom", "text", "skyvern_element", "preserved_elements"])
async def choose_auto_completion_dropdown(
context: InputOrSelectContext,
page: Page,
@@ -2418,6 +2441,19 @@ async def input_or_auto_complete_input(
return None
@TraceManager.traced_async(
ignore_inputs=[
"input_or_select_context",
"page",
"dom",
"skyvern_element",
"skyvern_frame",
"incremental_scraped",
"dropdown_menu_element",
"target_value",
"continue_until_close",
]
)
async def sequentially_select_from_dropdown(
action: SelectOptionAction,
input_or_select_context: InputOrSelectContext,
@@ -2470,6 +2506,7 @@ async def sequentially_select_from_dropdown(
force_select=force_select,
target_value=target_value,
)
assert single_select_result is not None
select_history.append(single_select_result)
values.append(single_select_result.value)
# wait 1s until DOM finished updating
@@ -2614,6 +2651,7 @@ class CustomSelectPromptOptions(BaseModel):
target_value: str | None = None
@TraceManager.traced_async(ignore_inputs=["scraped_page", "page"])
async def select_from_emerging_elements(
current_element_id: str,
options: CustomSelectPromptOptions,
@@ -2702,6 +2740,19 @@ async def select_from_emerging_elements(
return ActionSuccess()
@TraceManager.traced_async(
ignore_inputs=[
"context",
"page",
"skyvern_element",
"skyvern_frame",
"incremental_scraped",
"check_filter_funcs",
"dropdown_menu_element",
"select_history",
"target_value",
]
)
async def select_from_dropdown(
context: InputOrSelectContext,
page: Page,
@@ -2893,6 +2944,17 @@ async def select_from_dropdown(
return single_select_result
@TraceManager.traced_async(
ignore_inputs=[
"value",
"page",
"skyvern_element",
"skyvern_frame",
"dom",
"incremental_scraped",
"dropdown_menu_element",
]
)
async def select_from_dropdown_by_value(
value: str,
page: Page,
@@ -3133,6 +3195,9 @@ async def try_to_find_potential_scrollable_element(
return skyvern_element
@TraceManager.traced_async(
ignore_inputs=["scrollable_element", "page", "skyvern_frame", "incremental_scraped", "is_continue"]
)
async def scroll_down_to_load_all_options(
scrollable_element: SkyvernElement,
page: Page,

View File

@@ -16,6 +16,7 @@ from skyvern.constants import BUILDING_ELEMENT_TREE_TIMEOUT_MS, DEFAULT_MAX_TOKE
from skyvern.exceptions import FailedToTakeScreenshot, ScrapingFailed, UnknownElementTreeFormat
from skyvern.forge.sdk.api.crypto import calculate_sha256
from skyvern.forge.sdk.core import skyvern_context
from skyvern.forge.sdk.trace import TraceManager
from skyvern.utils.image_resizer import Resolution
from skyvern.utils.token_counter import count_tokens
from skyvern.webeye.browser_factory import BrowserState
@@ -392,6 +393,7 @@ class ScrapedPage(BaseModel, ElementTreeBuilder):
return await self.generate_scraped_page(take_screenshots=False)
@TraceManager.traced_async(ignore_input=True)
async def scrape_website(
browser_state: BrowserState,
url: str,
@@ -646,11 +648,9 @@ async def add_frame_interactable_elements(
)
return elements, element_tree
frame_js_script = f"async () => await buildTreeFromBody('{unique_id}', {frame_index})"
await SkyvernFrame.evaluate(frame=frame, expression=JS_FUNCTION_DEFS)
frame_elements, frame_element_tree = await SkyvernFrame.evaluate(
frame=frame, expression=frame_js_script, timeout_ms=BUILDING_ELEMENT_TREE_TIMEOUT_MS
skyvern_frame = await SkyvernFrame.create_instance(frame)
frame_elements, frame_element_tree = await skyvern_frame.build_tree_from_body(
frame_name=unique_id, frame_index=frame_index
)
for element in elements:
@@ -662,6 +662,7 @@ async def add_frame_interactable_elements(
return elements, element_tree
@TraceManager.traced_async(ignore_input=True)
async def get_interactable_element_tree(
page: Page,
scrape_exclude: ScrapeExcludeFunc | None = None,
@@ -671,12 +672,9 @@ async def get_interactable_element_tree(
:param page: Page instance to get the element tree from.
:return: Tuple containing the element tree and a map of element IDs to elements.
"""
await SkyvernFrame.evaluate(frame=page, expression=JS_FUNCTION_DEFS)
# main page index is 0
main_frame_js_script = "async () => await buildTreeFromBody('main.frame', 0)"
elements, element_tree = await SkyvernFrame.evaluate(
frame=page, expression=main_frame_js_script, timeout_ms=BUILDING_ELEMENT_TREE_TIMEOUT_MS
)
skyvern_page = await SkyvernFrame.create_instance(page)
elements, element_tree = await skyvern_page.build_tree_from_body(frame_name="main.frame", frame_index=0)
context = skyvern_context.ensure_context()
frames = await get_all_children_frames(page)
@@ -718,25 +716,23 @@ class IncrementalScrapePage(ElementTreeBuilder):
return True
return False
@TraceManager.traced_async(ignore_input=True)
async def get_incremental_element_tree(
self,
cleanup_element_tree: CleanupElementTreeFunc,
) -> list[dict]:
frame = self.skyvern_frame.get_frame()
js_script = "async () => await getIncrementElements()"
try:
incremental_elements, incremental_tree = await SkyvernFrame.evaluate(
frame=frame, expression=js_script, timeout_ms=BUILDING_ELEMENT_TREE_TIMEOUT_MS
incremental_elements, incremental_tree = await self.skyvern_frame.get_incremental_element_tree(
wait_until_finished=True
)
except TimeoutError:
LOG.warning(
"Timeout to get incremental elements with wait_until_finished, going to get incremental elements without waiting",
)
js_script = "async () => await getIncrementElements(false)"
incremental_elements, incremental_tree = await SkyvernFrame.evaluate(
frame=frame, expression=js_script, timeout_ms=BUILDING_ELEMENT_TREE_TIMEOUT_MS
incremental_elements, incremental_tree = await self.skyvern_frame.get_incremental_element_tree(
wait_until_finished=False
)
# we listen the incremental elements seperated by frames, so all elements will be in the same SkyvernFrame

View File

@@ -14,6 +14,7 @@ from playwright.async_api import ElementHandle, Frame, Page
from skyvern.config import settings
from skyvern.constants import BUILDING_ELEMENT_TREE_TIMEOUT_MS, PAGE_CONTENT_TIMEOUT, SKYVERN_DIR
from skyvern.exceptions import FailedToTakeScreenshot
from skyvern.forge.sdk.trace import TraceManager
LOG = structlog.get_logger()
@@ -221,6 +222,7 @@ class SkyvernFrame:
return await SkyvernFrame.evaluate(frame=frame, expression="() => document.location.href")
@staticmethod
@TraceManager.traced_async(ignore_inputs=["file_path", "timeout"])
async def take_scrolling_screenshot(
page: Page,
file_path: str | None = None,
@@ -286,6 +288,7 @@ class SkyvernFrame:
await skyvern_frame.scroll_to_x_y(x, y)
@staticmethod
@TraceManager.traced_async(ignore_inputs=["page"])
async def take_split_screenshots(
page: Page,
url: str | None = None,
@@ -436,3 +439,21 @@ class SkyvernFrame:
async def get_select_options(self, element: ElementHandle) -> tuple[list, str]:
js_script = "([element]) => getSelectOptions(element)"
return await self.evaluate(frame=self.frame, expression=js_script, arg=[element])
@TraceManager.traced_async()
async def build_tree_from_body(
self, frame_name: str | None, frame_index: int, timeout_ms: float = BUILDING_ELEMENT_TREE_TIMEOUT_MS
) -> tuple[list[dict], list[dict]]:
js_script = "async ([frame_name, frame_index]) => await buildTreeFromBody(frame_name, frame_index)"
return await self.evaluate(
frame=self.frame, expression=js_script, timeout_ms=timeout_ms, arg=[frame_name, frame_index]
)
@TraceManager.traced_async()
async def get_incremental_element_tree(
self, wait_until_finished: bool = True, timeout_ms: float = BUILDING_ELEMENT_TREE_TIMEOUT_MS
) -> tuple[list[dict], list[dict]]:
js_script = "async ([wait_until_finished]) => await getIncrementElements(wait_until_finished)"
return await self.evaluate(
frame=self.frame, expression=js_script, timeout_ms=timeout_ms, arg=[wait_until_finished]
)