feat: Enhance Observability with ArizePhoenixTracer Integration (#5058)
* Added ArizePhoenixTracer * [autofix.ci] apply automated fixes * Fixed Ruff Style Check Errors * add Arize icon * Fixed Mypy Errors * Refactor ArizeIcon component to use arrow function syntax Co-authored-by: Jeff Carpenter <jeffrey.carpenter@datastax.com> Co-authored-by: Ítalo Johnny <italojohnnydosanjos@gmail.com> Co-authored-by: anovazzi1 <otavio2204@gmail.com>
This commit is contained in:
parent
776e32df4c
commit
7c01b5a040
8 changed files with 453 additions and 0 deletions
|
|
@ -112,6 +112,8 @@ dependencies = [
|
|||
"mem0ai>=0.1.26,<1.0.0",
|
||||
"aiofile>=3.9.0,<4.0.0",
|
||||
"sseclient-py==1.8.0",
|
||||
"arize-phoenix-otel>=0.6.1",
|
||||
"openinference-instrumentation-langchain>=0.1.29",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
|||
324
src/backend/base/langflow/services/tracing/arize_phoenix.py
Normal file
324
src/backend/base/langflow/services/tracing/arize_phoenix.py
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import traceback
|
||||
import types
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from langchain_core.documents import Document
|
||||
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
|
||||
from loguru import logger
|
||||
from openinference.semconv.trace import OpenInferenceMimeTypeValues, SpanAttributes
|
||||
from opentelemetry.semconv.trace import SpanAttributes as OTELSpanAttributes
|
||||
from opentelemetry.trace import Span, Status, StatusCode
|
||||
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
||||
from typing_extensions import override
|
||||
|
||||
from langflow.schema.data import Data
|
||||
from langflow.schema.message import Message
|
||||
from langflow.services.tracing.base import BaseTracer
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Sequence
|
||||
from uuid import UUID
|
||||
|
||||
from langchain.callbacks.base import BaseCallbackHandler
|
||||
from opentelemetry.propagators.textmap import CarrierT
|
||||
from opentelemetry.util.types import AttributeValue
|
||||
|
||||
from langflow.graph.vertex.base import Vertex
|
||||
from langflow.services.tracing.schema import Log
|
||||
|
||||
|
||||
class ArizePhoenixTracer(BaseTracer):
|
||||
flow_id: str
|
||||
|
||||
def __init__(self, trace_name: str, trace_type: str, project_name: str, trace_id: UUID):
|
||||
"""Initializes the ArizePhoenixTracer instance and sets up a root span."""
|
||||
self.trace_name = trace_name
|
||||
self.trace_type = trace_type
|
||||
self.project_name = project_name
|
||||
self.trace_id = trace_id
|
||||
self.flow_id = trace_name.split(" - ")[-1]
|
||||
|
||||
try:
|
||||
self._ready = self.setup_arize_phoenix()
|
||||
if not self._ready:
|
||||
return
|
||||
|
||||
self.tracer = self.tracer_provider.get_tracer(__name__)
|
||||
self.propagator = TraceContextTextMapPropagator()
|
||||
self.carrier: dict[Any, CarrierT] = {}
|
||||
|
||||
with self.tracer.start_as_current_span(
|
||||
name=self.flow_id,
|
||||
start_time=self._get_current_timestamp(),
|
||||
) as root_span:
|
||||
root_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, self.trace_type)
|
||||
root_span.set_status(Status(StatusCode.OK))
|
||||
self.propagator.inject(carrier=self.carrier)
|
||||
|
||||
self.child_spans: dict[str, Span] = {}
|
||||
|
||||
except Exception: # noqa: BLE001
|
||||
logger.opt(exception=True).debug("Error setting up Arize/Phoenix tracer")
|
||||
self._ready = False
|
||||
|
||||
@property
|
||||
def ready(self):
|
||||
"""Indicates if the tracer is ready for usage."""
|
||||
return self._ready
|
||||
|
||||
def setup_arize_phoenix(self) -> bool:
|
||||
"""Configures Arize/Phoenix specific environment variables and registers the tracer provider."""
|
||||
arize_phoenix_batch = os.getenv("ARIZE_PHOENIX_BATCH", "False").lower() in (
|
||||
"true",
|
||||
"t",
|
||||
"yes",
|
||||
"y",
|
||||
"1",
|
||||
)
|
||||
|
||||
# Arize Config
|
||||
arize_api_key = os.getenv("ARIZE_API_KEY", None)
|
||||
arize_space_id = os.getenv("ARIZE_SPACE_ID", None)
|
||||
arize_collector_endpoint = os.getenv("ARIZE_COLLECTOR_ENDPOINT", "https://otlp.arize.com")
|
||||
enable_arize_tracing = bool(arize_api_key and arize_space_id)
|
||||
arize_endpoint = f"{arize_collector_endpoint}/v1"
|
||||
arize_headers = {
|
||||
"api_key": arize_api_key,
|
||||
"space_id": arize_space_id,
|
||||
"authorization": f"Bearer {arize_api_key}",
|
||||
}
|
||||
|
||||
# Phoenix Config
|
||||
phoenix_api_key = os.getenv("PHOENIX_API_KEY", None)
|
||||
phoenix_collector_endpoint = os.getenv("PHOENIX_COLLECTOR_ENDPOINT", "https://app.phoenix.arize.com")
|
||||
enable_phoenix_tracing = bool(phoenix_api_key)
|
||||
phoenix_endpoint = f"{phoenix_collector_endpoint}/v1/traces"
|
||||
phoenix_headers = {
|
||||
"api_key": phoenix_api_key,
|
||||
"authorization": f"Bearer {phoenix_api_key}",
|
||||
}
|
||||
|
||||
if not (enable_arize_tracing or enable_phoenix_tracing):
|
||||
return False
|
||||
|
||||
try:
|
||||
from phoenix.otel import (
|
||||
PROJECT_NAME,
|
||||
BatchSpanProcessor,
|
||||
GRPCSpanExporter,
|
||||
HTTPSpanExporter,
|
||||
Resource,
|
||||
SimpleSpanProcessor,
|
||||
TracerProvider,
|
||||
)
|
||||
|
||||
project_name = self.project_name or self.flow_id
|
||||
attributes = {PROJECT_NAME: project_name, "model_id": project_name}
|
||||
resource = Resource.create(attributes=attributes)
|
||||
tracer_provider = TracerProvider(resource=resource, verbose=False)
|
||||
span_processor = BatchSpanProcessor if arize_phoenix_batch else SimpleSpanProcessor
|
||||
|
||||
if enable_arize_tracing:
|
||||
tracer_provider.add_span_processor(
|
||||
span_processor=span_processor(
|
||||
span_exporter=GRPCSpanExporter(endpoint=arize_endpoint, headers=arize_headers),
|
||||
)
|
||||
)
|
||||
|
||||
if enable_phoenix_tracing:
|
||||
tracer_provider.add_span_processor(
|
||||
span_processor=span_processor(
|
||||
span_exporter=HTTPSpanExporter(
|
||||
endpoint=phoenix_endpoint,
|
||||
headers=phoenix_headers,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
self.tracer_provider = tracer_provider
|
||||
except ImportError:
|
||||
logger.exception(
|
||||
"Could not import arize-phoenix-otel. Please install it with `pip install arize-phoenix-otel`."
|
||||
)
|
||||
return False
|
||||
|
||||
try:
|
||||
from openinference.instrumentation.langchain import LangChainInstrumentor
|
||||
|
||||
LangChainInstrumentor().instrument(tracer_provider=self.tracer_provider, skip_dep_check=True)
|
||||
except ImportError:
|
||||
logger.exception(
|
||||
"Could not import LangChainInstrumentor."
|
||||
"Please install it with `pip install openinference-instrumentation-langchain`."
|
||||
)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@override
|
||||
def add_trace(
|
||||
self,
|
||||
trace_id: str,
|
||||
trace_name: str,
|
||||
trace_type: str,
|
||||
inputs: dict[str, Any],
|
||||
metadata: dict[str, Any] | None = None,
|
||||
vertex: Vertex | None = None,
|
||||
) -> None:
|
||||
"""Adds a trace span, attaching inputs and metadata as attributes."""
|
||||
if not self._ready:
|
||||
return
|
||||
|
||||
span_context = self.propagator.extract(carrier=self.carrier)
|
||||
child_span = self.tracer.start_span(
|
||||
name=trace_name,
|
||||
context=span_context,
|
||||
start_time=self._get_current_timestamp(),
|
||||
)
|
||||
|
||||
if trace_type == "prompt":
|
||||
child_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, "chain")
|
||||
else:
|
||||
child_span.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, trace_type)
|
||||
|
||||
if "session_id" in inputs and len(inputs["session_id"]) > 0 and inputs["session_id"] != self.flow_id:
|
||||
child_span.set_attribute(SpanAttributes.SESSION_ID, inputs["session_id"])
|
||||
else:
|
||||
child_span.set_attribute(SpanAttributes.SESSION_ID, self.flow_id)
|
||||
|
||||
processed_inputs = self._convert_to_arize_phoenix_types(inputs) if inputs else {}
|
||||
if processed_inputs:
|
||||
child_span.set_attribute(SpanAttributes.INPUT_VALUE, self._safe_json_dumps(processed_inputs))
|
||||
child_span.set_attribute(SpanAttributes.INPUT_MIME_TYPE, OpenInferenceMimeTypeValues.JSON.value)
|
||||
|
||||
processed_metadata = self._convert_to_arize_phoenix_types(metadata) if metadata else {}
|
||||
if processed_metadata:
|
||||
for key, value in processed_metadata.items():
|
||||
child_span.set_attribute(f"{SpanAttributes.METADATA}.{key}", value)
|
||||
|
||||
self.child_spans[trace_id] = child_span
|
||||
|
||||
@override
|
||||
def end_trace(
|
||||
self,
|
||||
trace_id: str,
|
||||
trace_name: str,
|
||||
outputs: dict[str, Any] | None = None,
|
||||
error: Exception | None = None,
|
||||
logs: Sequence[Log | dict] = (),
|
||||
) -> None:
|
||||
"""Ends a trace span, attaching outputs, errors, and logs as attributes."""
|
||||
if not self._ready or trace_id not in self.child_spans:
|
||||
return
|
||||
|
||||
child_span = self.child_spans[trace_id]
|
||||
|
||||
processed_outputs = self._convert_to_arize_phoenix_types(outputs) if outputs else {}
|
||||
if processed_outputs:
|
||||
child_span.set_attribute(SpanAttributes.OUTPUT_VALUE, self._safe_json_dumps(processed_outputs))
|
||||
child_span.set_attribute(SpanAttributes.OUTPUT_MIME_TYPE, OpenInferenceMimeTypeValues.JSON.value)
|
||||
|
||||
logs_dicts = [log if isinstance(log, dict) else log.model_dump() for log in logs]
|
||||
processed_logs = (
|
||||
self._convert_to_arize_phoenix_types({log.get("name"): log for log in logs_dicts}) if logs else {}
|
||||
)
|
||||
if processed_logs:
|
||||
for key, value in processed_logs.items():
|
||||
child_span.set_attribute(f"logs.{key}", value)
|
||||
|
||||
if error:
|
||||
error_string = self._error_to_string(error)
|
||||
child_span.set_status(Status(StatusCode.ERROR, error_string))
|
||||
child_span.set_attribute("error.message", error_string)
|
||||
|
||||
if isinstance(error, Exception):
|
||||
child_span.record_exception(error)
|
||||
else:
|
||||
exception_type = error.__class__.__name__
|
||||
exception_message = str(error)
|
||||
if not exception_message:
|
||||
exception_message = repr(error)
|
||||
attributes: dict[str, AttributeValue] = {
|
||||
OTELSpanAttributes.EXCEPTION_TYPE: exception_type,
|
||||
OTELSpanAttributes.EXCEPTION_MESSAGE: exception_message,
|
||||
OTELSpanAttributes.EXCEPTION_ESCAPED: False,
|
||||
OTELSpanAttributes.EXCEPTION_STACKTRACE: error_string,
|
||||
}
|
||||
child_span.add_event(name="exception", attributes=attributes)
|
||||
else:
|
||||
child_span.set_status(Status(StatusCode.OK))
|
||||
|
||||
child_span.end(end_time=self._get_current_timestamp())
|
||||
self.child_spans.pop(trace_id)
|
||||
|
||||
@override
|
||||
def end(
|
||||
self,
|
||||
inputs: dict[str, Any],
|
||||
outputs: dict[str, Any],
|
||||
error: Exception | None = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Ends tracing with the specified inputs, outputs, errors, and metadata as attributes."""
|
||||
if not self._ready:
|
||||
return
|
||||
|
||||
def _convert_to_arize_phoenix_types(self, io_dict: dict[str, Any]):
|
||||
"""Converts data types to Arize/Phoenix compatible formats."""
|
||||
return {key: self._convert_to_arize_phoenix_type(value) for key, value in io_dict.items()}
|
||||
|
||||
def _convert_to_arize_phoenix_type(self, value):
|
||||
"""Recursively converts a value to a Arize/Phoenix compatible type."""
|
||||
if isinstance(value, dict):
|
||||
for key, _value in value.copy().items():
|
||||
_value = self._convert_to_arize_phoenix_type(_value)
|
||||
value[key] = _value
|
||||
|
||||
elif isinstance(value, list):
|
||||
value = [self._convert_to_arize_phoenix_type(v) for v in value]
|
||||
|
||||
elif isinstance(value, Message):
|
||||
value = value.text
|
||||
|
||||
elif isinstance(value, Data):
|
||||
value = value.get_text()
|
||||
|
||||
elif isinstance(value, (BaseMessage | HumanMessage | SystemMessage)):
|
||||
value = value.content
|
||||
|
||||
elif isinstance(value, Document):
|
||||
value = value.page_content
|
||||
|
||||
elif isinstance(value, (types.GeneratorType | types.NoneType)):
|
||||
value = str(value)
|
||||
|
||||
elif isinstance(value, float) and not math.isfinite(value):
|
||||
value = "NaN"
|
||||
|
||||
return value
|
||||
|
||||
def _error_to_string(self, error: Exception | None):
|
||||
"""Converts an error to a string with traceback details."""
|
||||
error_message = None
|
||||
if error:
|
||||
string_stacktrace = traceback.format_exception(error)
|
||||
error_message = f"{error.__class__.__name__}: {error}\n\n{string_stacktrace}"
|
||||
return error_message
|
||||
|
||||
def _get_current_timestamp(self) -> int:
|
||||
"""Gets the current UTC timestamp in nanoseconds."""
|
||||
return int(datetime.now(timezone.utc).timestamp() * 1_000_000_000)
|
||||
|
||||
def _safe_json_dumps(self, obj: Any, **kwargs: Any) -> str:
|
||||
"""A convenience wrapper around `json.dumps` that ensures that any object can be safely encoded."""
|
||||
return json.dumps(obj, default=str, ensure_ascii=False, **kwargs)
|
||||
|
||||
def get_langchain_callback(self) -> BaseCallbackHandler | None:
|
||||
"""Returns the LangChain callback handler if applicable."""
|
||||
return None
|
||||
|
|
@ -40,6 +40,12 @@ def _get_langfuse_tracer():
|
|||
return LangFuseTracer
|
||||
|
||||
|
||||
def _get_arize_phoenix_tracer():
|
||||
from langflow.services.tracing.arize_phoenix import ArizePhoenixTracer
|
||||
|
||||
return ArizePhoenixTracer
|
||||
|
||||
|
||||
class TracingService(Service):
|
||||
name = "tracing_service"
|
||||
|
||||
|
|
@ -111,6 +117,7 @@ class TracingService(Service):
|
|||
await asyncio.to_thread(self._initialize_langsmith_tracer)
|
||||
await asyncio.to_thread(self._initialize_langwatch_tracer)
|
||||
await asyncio.to_thread(self._initialize_langfuse_tracer)
|
||||
await asyncio.to_thread(self._initialize_arize_phoenix_tracer)
|
||||
except Exception as e: # noqa: BLE001
|
||||
logger.debug(f"Error initializing tracers: {e}")
|
||||
|
||||
|
|
@ -145,6 +152,16 @@ class TracingService(Service):
|
|||
trace_id=self.run_id,
|
||||
)
|
||||
|
||||
def _initialize_arize_phoenix_tracer(self) -> None:
|
||||
self.project_name = os.getenv("ARIZE_PHOENIX_PROJECT", "Langflow")
|
||||
arize_phoenix_tracer = _get_arize_phoenix_tracer()
|
||||
self._tracers["arize_phoenix"] = arize_phoenix_tracer(
|
||||
trace_name=self.run_name,
|
||||
trace_type="chain",
|
||||
project_name=self.project_name,
|
||||
trace_id=self.run_id,
|
||||
)
|
||||
|
||||
def set_run_name(self, name: str) -> None:
|
||||
self.run_name = name
|
||||
|
||||
|
|
|
|||
20
src/frontend/src/icons/Arize/Arize.jsx
Normal file
20
src/frontend/src/icons/Arize/Arize.jsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
const SvgArize = (props) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="823"
|
||||
height="807"
|
||||
viewBox="0 0 823 807"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="#EE2C8B"
|
||||
d="m451 30 2.227 1.594C461.463 38.183 467.08 47.396 473 56l1.594 2.312c2.669 3.876 5.322 7.762 7.969 11.653 3.713 5.453 7.478 10.871 11.25 16.285a37210.514 37210.514 0 0 0 6.14 8.81q5.026 7.218 10.047 14.44l4 5.75 40 57.5 2.001 2.877q1.995 2.866 3.988 5.733 5.091 7.32 10.187 14.636c5.837 8.383 11.674 16.766 17.449 25.191 4.57 6.666 9.198 13.29 13.837 19.906 6.52 9.3 13.001 18.627 19.484 27.953q3.117 4.482 6.238 8.962c5.834 8.379 11.668 16.758 17.441 25.18 4.57 6.665 9.198 13.288 13.837 19.905 6.52 9.3 13.001 18.627 19.484 27.953q3.117 4.482 6.238 8.962c5.834 8.379 11.668 16.758 17.441 25.18 4.57 6.665 9.198 13.288 13.837 19.905 6.52 9.3 13.001 18.627 19.484 27.953q3.117 4.482 6.238 8.962c5.834 8.379 11.668 16.758 17.441 25.18a2035 2035 0 0 0 12.063 17.375c14.872 21.225 14.872 21.225 21.42 30.702q1.839 2.658 3.685 5.31C809.298 540 817 558.968 812.813 583.062c-1.319 6.836-3.477 12.834-6.813 18.938l-1.375 2.578c-8.507 15.073-22.217 26.158-38.77 31.422-5.58 1.46-11.108 2.529-16.855 3l-1.926.16c-18.082.783-36.106-6.549-49.886-17.91-7.241-6.766-12.611-15.118-18.188-23.25l-1.622-2.355a2641 2641 0 0 1-8.073-11.81c-3.332-4.89-6.718-9.741-10.117-14.585-9.663-13.772-19.3-27.561-28.813-41.437-4.57-6.666-9.198-13.29-13.837-19.906-6.52-9.3-13.001-18.627-19.484-27.953q-3.117-4.482-6.238-8.962c-5.834-8.379-11.668-16.758-17.441-25.18-4.57-6.665-9.198-13.288-13.837-19.905-6.52-9.3-13.001-18.627-19.484-27.953q-3.117-4.482-6.238-8.962c-5.834-8.379-11.668-16.758-17.441-25.18-4.57-6.665-9.198-13.288-13.837-19.905-6.52-9.3-13.001-18.627-19.484-27.953q-3.117-4.482-6.238-8.962c-11.473-16.476-11.473-16.476-16.231-23.42-1.741-2.54-3.49-5.075-5.239-7.611a863 863 0 0 1-2.813-4.125C444.018 259.285 435.899 248.007 422 241l-1.879-1.027c-7.75-3.633-18.27-3.348-26.246-.598C381.837 245.114 373.447 254.18 366 265l-1.467 2.114c-2.73 3.943-5.433 7.904-8.123 11.874-3.36 4.954-6.782 9.863-10.223 14.762-9.662 13.772-19.3 27.561-28.812 41.438-4.57 6.665-9.198 13.288-13.837 19.905-6.52 9.3-13.001 18.627-19.484 27.953q-3.117 4.482-6.238 8.962c-5.834 8.379-11.668 16.758-17.441 25.18-4.57 6.665-9.198 13.288-13.837 19.905-6.52 9.3-13.001 18.627-19.484 27.953q-3.117 4.482-6.238 8.962c-5.834 8.379-11.668 16.758-17.441 25.18-4.57 6.665-9.198 13.288-13.837 19.905-6.52 9.3-13.001 18.627-19.484 27.953q-3.117 4.482-6.238 8.962c-5.834 8.379-11.667 16.758-17.441 25.18Q143.69 585.096 141 589l-1.68 2.442C123.518 614.38 108.918 633 79.855 638.398c-17.483 2.552-35.658-1.514-50.261-11.457-16.17-12.103-25.2-27.585-29.281-47.254-2.315-27.315 8.336-45.857 23.585-67.304a856 856 0 0 0 8.477-12.196 1951 1951 0 0 1 12.313-17.75 9072 9072 0 0 0 21.258-30.483q3.117-4.482 6.238-8.962c5.834-8.379 11.668-16.758 17.441-25.18 4.57-6.665 9.198-13.288 13.837-19.905 6.52-9.3 13.001-18.627 19.484-27.953q3.117-4.482 6.238-8.962c5.834-8.379 11.668-16.758 17.441-25.18 4.57-6.665 9.198-13.288 13.837-19.905 6.52-9.3 13.001-18.627 19.484-27.953q3.117-4.482 6.238-8.962c5.834-8.379 11.668-16.758 17.441-25.18 4.57-6.665 9.198-13.288 13.837-19.905 6.527-9.31 13.016-18.647 19.506-27.984a38524 38524 0 0 1 12.02-17.282q5.092-7.32 10.188-14.637c5.837-8.383 11.674-16.766 17.449-25.191 4.57-6.666 9.198-13.29 13.837-19.906 6.52-9.3 13.001-18.627 19.484-27.953q3.117-4.482 6.238-8.962c5.877-8.44 11.751-16.883 17.566-25.367q1.948-2.834 3.9-5.664 1.419-2.062 2.833-4.125c15.224-22.165 29.843-36.059 57.115-41.332C416.54 12.698 435.684 18.879 451 30"
|
||||
></path>
|
||||
<path
|
||||
fill="#EE2C8A"
|
||||
d="M460.543 655.941C476.174 669.038 488.656 688.385 491 709c1.912 26.065-2.94 48.653-20 69-14.01 16.165-34.113 26.37-55.375 28.75q-2.31.156-4.625.25l-2.117.121c-20.961.653-42.347-7.16-57.883-21.121l-2.785-2.5c-16.102-15.238-25.322-36.43-26.246-58.55.178-22.55 6.822-42.883 22.031-59.95.665-.76 1.33-1.519 2.016-2.3 9.578-10.271 21.872-16.981 34.984-21.7l2.855-1.031c26.5-7.725 55.232-.53 76.688 15.972"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default SvgArize;
|
||||
6
src/frontend/src/icons/Arize/arize.svg
Normal file
6
src/frontend/src/icons/Arize/arize.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 9 KiB |
8
src/frontend/src/icons/Arize/index.tsx
Normal file
8
src/frontend/src/icons/Arize/index.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import React, { forwardRef } from "react";
|
||||
import SvgArize from "./Arize";
|
||||
|
||||
export const ArizeIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
|
||||
(props, ref) => {
|
||||
return <SvgArize ref={ref} {...props} />;
|
||||
},
|
||||
);
|
||||
|
|
@ -233,6 +233,7 @@ import { FaApple, FaDiscord, FaGithub } from "react-icons/fa";
|
|||
import { AWSIcon } from "../icons/AWS";
|
||||
import { AirbyteIcon } from "../icons/Airbyte";
|
||||
import { AnthropicIcon } from "../icons/Anthropic";
|
||||
import { ArizeIcon } from "../icons/Arize";
|
||||
import { AssemblyAIIcon } from "../icons/AssemblyAI";
|
||||
import { AstraDBIcon } from "../icons/AstraDB";
|
||||
import { AzureIcon } from "../icons/Azure";
|
||||
|
|
@ -704,6 +705,7 @@ export const nodeIconsLucide: iconsType = {
|
|||
SerpSearch: SerpSearchIcon,
|
||||
SearchAPI: SearchAPIIcon,
|
||||
Wikipedia: WikipediaIcon,
|
||||
Arize: ArizeIcon,
|
||||
|
||||
//Node Icons
|
||||
model_specs: FileSliders,
|
||||
|
|
|
|||
74
uv.lock
generated
74
uv.lock
generated
|
|
@ -215,6 +215,23 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arize-phoenix-otel"
|
||||
version = "0.6.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "openinference-semantic-conventions" },
|
||||
{ name = "opentelemetry-exporter-otlp" },
|
||||
{ name = "opentelemetry-proto" },
|
||||
{ name = "opentelemetry-sdk" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b7/70/41eef869b46882aae54e9b8c757223da93160633bba82752158a77b1566a/arize_phoenix_otel-0.6.1.tar.gz", hash = "sha256:f5f7a257159f49b398dfe2ba45bb70e22766cdf61bb365c0c47dc55f329bfe95", size = 9691 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/f3/f2390a9d7b3ee46b28a8ccee6510a489ae0974f31b51c67d79cab4c45ef8/arize_phoenix_otel-0.6.1-py3-none-any.whl", hash = "sha256:fc00dd847a248cece5f20dffeb8fabfab72c1c38f198bcee4260618c6af1d8a5", size = 10783 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "asgi-lifespan"
|
||||
version = "2.1.0"
|
||||
|
|
@ -3522,6 +3539,7 @@ version = "1.1.1"
|
|||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "aiofile" },
|
||||
{ name = "arize-phoenix-otel" },
|
||||
{ name = "assemblyai" },
|
||||
{ name = "astra-assistants", extra = ["tools"] },
|
||||
{ name = "atlassian-python-api" },
|
||||
|
|
@ -3578,6 +3596,7 @@ dependencies = [
|
|||
{ name = "networkx" },
|
||||
{ name = "nltk" },
|
||||
{ name = "numexpr" },
|
||||
{ name = "openinference-instrumentation-langchain" },
|
||||
{ name = "opensearch-py" },
|
||||
{ name = "pgvector" },
|
||||
{ name = "pyarrow" },
|
||||
|
|
@ -3666,6 +3685,7 @@ dev = [
|
|||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "aiofile", specifier = ">=3.9.0,<4.0.0" },
|
||||
{ name = "arize-phoenix-otel", specifier = ">=0.6.1" },
|
||||
{ name = "assemblyai", specifier = ">=0.33.0,<1.0.0" },
|
||||
{ name = "astra-assistants", extras = ["tools"], specifier = "~=2.2.6" },
|
||||
{ name = "atlassian-python-api", specifier = ">=3.41.16,<4.0.0" },
|
||||
|
|
@ -3730,6 +3750,7 @@ requires-dist = [
|
|||
{ name = "networkx", specifier = ">=3.1,<4.0.0" },
|
||||
{ name = "nltk", specifier = ">=3.9.1,<4.0.0" },
|
||||
{ name = "numexpr", specifier = ">=2.8.6,<3.0.0" },
|
||||
{ name = "openinference-instrumentation-langchain", specifier = ">=0.1.29" },
|
||||
{ name = "opensearch-py", specifier = ">=2.7.1,<3.0.0" },
|
||||
{ name = "pgvector", specifier = ">=0.2.3,<1.0.0" },
|
||||
{ name = "pyarrow", specifier = ">=14.0.0,<18.0.0" },
|
||||
|
|
@ -4931,6 +4952,46 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/39/1e/9dc3ccee95d0e16e54e353d3c355bb7cc506d56a2dbb0a07bc739cc48eac/openai-1.52.0-py3-none-any.whl", hash = "sha256:0c249f20920183b0a2ca4f7dba7b0452df3ecd0fa7985eb1d91ad884bc3ced9c", size = 386947 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openinference-instrumentation"
|
||||
version = "0.1.19"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "openinference-semantic-conventions" },
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-sdk" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/96/b2c98e52caf35d1f9f1e5499646498667afbf17155c7ea8e990956bca98b/openinference_instrumentation-0.1.19.tar.gz", hash = "sha256:48e91e655dfe49a320f898bb1ec9e68d919e2e222b152cd33366fc94502e9a27", size = 11801 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/5c/5632de07c9ec5a18f9f16c1b50814cfee46cdefca9ff9417e859a42c38f8/openinference_instrumentation-0.1.19-py3-none-any.whl", hash = "sha256:f1a6e31c0c7668f5e3849f7d4a0156409456f35ea1cb19d7495b31f2f5b7d3e5", size = 14569 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openinference-instrumentation-langchain"
|
||||
version = "0.1.29"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "openinference-instrumentation" },
|
||||
{ name = "openinference-semantic-conventions" },
|
||||
{ name = "opentelemetry-api" },
|
||||
{ name = "opentelemetry-instrumentation" },
|
||||
{ name = "opentelemetry-semantic-conventions" },
|
||||
{ name = "wrapt" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/10/d2/185e4dd18431f35faba90482f511328d283e71ed12737e050664f7b5efeb/openinference_instrumentation_langchain-0.1.29.tar.gz", hash = "sha256:f6c10079c91f810cff39ff24c278e41d16df0c3706b230e1859f46cad20f8e0b", size = 45868 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/ba/b0855a5f9bb565e462d85ecfad63d108c4c4bc209a34850623273f7dbcef/openinference_instrumentation_langchain-0.1.29-py3-none-any.whl", hash = "sha256:9faaedb62f90ca8099b48c0b9ded97fe109a646b756f4bf7c98479b500a8446d", size = 17043 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openinference-semantic-conventions"
|
||||
version = "0.1.12"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5f/ae/0bf5e0dcda695fd66428da05880e137c67f6fcbc494b31edec72635dc9e1/openinference_semantic_conventions-0.1.12.tar.gz", hash = "sha256:f1a378429873128892f44505a994e2b29277a8dc1be9a56b1726b1069d70dcdc", size = 9240 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/fb/ea6c04bb12b2e5ade3faf32b24d45ffce9a21a1468ea179de96ceec1fb3d/openinference_semantic_conventions-0.1.12-py3-none-any.whl", hash = "sha256:3489262a148ba25b3203e500dedcf8955f0c68072f7e45db3a958c0d12585e62", size = 9061 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opensearch-py"
|
||||
version = "2.7.1"
|
||||
|
|
@ -4960,6 +5021,19 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/fb/1f/737dcdbc9fea2fa96c1b392ae47275165a7c641663fbb08a8d252968eed2/opentelemetry_api-1.27.0-py3-none-any.whl", hash = "sha256:953d5871815e7c30c81b56d910c707588000fff7a3ca1c73e6531911d53065e7", size = 63970 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-exporter-otlp"
|
||||
version = "1.27.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "opentelemetry-exporter-otlp-proto-grpc" },
|
||||
{ name = "opentelemetry-exporter-otlp-proto-http" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/d3/8156cc14e8f4573a3572ee7f30badc7aabd02961a09acc72ab5f2c789ef1/opentelemetry_exporter_otlp-1.27.0.tar.gz", hash = "sha256:4a599459e623868cc95d933c301199c2367e530f089750e115599fccd67cb2a1", size = 6166 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/59/6d/95e1fc2c8d945a734db32e87a5aa7a804f847c1657a21351df9338bd1c9c/opentelemetry_exporter_otlp-1.27.0-py3-none-any.whl", hash = "sha256:7688791cbdd951d71eb6445951d1cfbb7b6b2d7ee5948fac805d404802931145", size = 7001 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-exporter-otlp-proto-common"
|
||||
version = "1.27.0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue