From 0904899bcfd8dd3651bb1d94deb3dc543a275707 Mon Sep 17 00:00:00 2001 From: Jamie Rasmussen <112953339+jamie-rasmussen@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:00:42 -0600 Subject: [PATCH 01/35] chore(ui): Fix React warning in PopupDropdown (#3277) --- weave-js/src/common/components/PopupDropdown.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/weave-js/src/common/components/PopupDropdown.tsx b/weave-js/src/common/components/PopupDropdown.tsx index 23423506f50b..8efe1468fcdb 100644 --- a/weave-js/src/common/components/PopupDropdown.tsx +++ b/weave-js/src/common/components/PopupDropdown.tsx @@ -56,7 +56,11 @@ const PopupDropdownComp: React.FC = props => { (opts, i: number) => ( { opts.onClick?.(e); handleClose(); From af7e4215f084a079348575e546b4eee22334e7da Mon Sep 17 00:00:00 2001 From: Adrian Swanberg Date: Tue, 17 Dec 2024 17:08:50 -0800 Subject: [PATCH 02/35] fix(weave): Bump feedback payload size limit to 1 MiB (#2926) * fix(weave): Bump feedback payload size limit to 1 MiB * revert conftest lol --- tests/trace/test_client_feedback.py | 2 +- weave/trace_server/clickhouse_trace_server_batched.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/trace/test_client_feedback.py b/tests/trace/test_client_feedback.py index 82d87198e133..c01127370a5a 100644 --- a/tests/trace/test_client_feedback.py +++ b/tests/trace/test_client_feedback.py @@ -228,7 +228,7 @@ def test_feedback_payload(client): def test_feedback_create_too_large(client): project_id = client._project_id() - value = "a" * 10000 + value = "a" * (1 << 21) # > 1 MiB, past the limit req = tsi.FeedbackCreateReq( project_id=project_id, wb_user_id="VXNlcjo0NTI1NDQ=", diff --git a/weave/trace_server/clickhouse_trace_server_batched.py b/weave/trace_server/clickhouse_trace_server_batched.py index 973d51080e29..e97e020b1abe 100644 --- a/weave/trace_server/clickhouse_trace_server_batched.py +++ b/weave/trace_server/clickhouse_trace_server_batched.py @@ -1312,7 +1312,7 @@ def feedback_create(self, req: tsi.FeedbackCreateReq) -> tsi.FeedbackCreateRes: created_at = datetime.datetime.now(ZoneInfo("UTC")) # TODO: Any validation on weave_ref? payload = _dict_value_to_dump(req.payload) - MAX_PAYLOAD = 1024 + MAX_PAYLOAD = 1 << 20 # 1 MiB if len(payload) > MAX_PAYLOAD: raise InvalidRequest("Feedback payload too large") row: Row = { From adb740bec5304df1130b92b0ce4b90bb909f6e34 Mon Sep 17 00:00:00 2001 From: Andrew Truong Date: Tue, 17 Dec 2024 20:20:45 -0500 Subject: [PATCH 03/35] feat(weave): Support op configuration for autopatched functions for remaining integrations (#3216) --- tests/integrations/litellm/litellm_test.py | 6 +- weave/integrations/anthropic/anthropic_sdk.py | 135 +++-- weave/integrations/cerebras/cerebras_sdk.py | 72 ++- weave/integrations/cohere/__init__.py | 2 +- weave/integrations/cohere/cohere_sdk.py | 198 +++++--- weave/integrations/dspy/dspy_sdk.py | 477 +++++++++++------- .../google_ai_studio/google_ai_studio_sdk.py | 129 +++-- weave/integrations/groq/groq_sdk.py | 77 ++- .../instructor/instructor_iterable_utils.py | 14 +- .../instructor/instructor_partial_utils.py | 7 +- .../integrations/instructor/instructor_sdk.py | 84 ++- weave/integrations/litellm/litellm.py | 73 ++- weave/integrations/mistral/__init__.py | 4 +- weave/integrations/mistral/v0/mistral.py | 124 +++-- weave/integrations/mistral/v1/mistral.py | 112 ++-- weave/integrations/notdiamond/__init__.py | 2 +- weave/integrations/notdiamond/tracing.py | 135 +++-- weave/integrations/vertexai/vertexai_sdk.py | 126 +++-- weave/trace/autopatch.py | 114 ++--- 19 files changed, 1206 insertions(+), 685 deletions(-) diff --git a/tests/integrations/litellm/litellm_test.py b/tests/integrations/litellm/litellm_test.py index 8cc0966c4768..ffd1094e6534 100644 --- a/tests/integrations/litellm/litellm_test.py +++ b/tests/integrations/litellm/litellm_test.py @@ -8,7 +8,7 @@ from packaging.version import parse as version_parse import weave -from weave.integrations.litellm.litellm import litellm_patcher +from weave.integrations.litellm.litellm import get_litellm_patcher # This PR: # https://github.com/BerriAI/litellm/commit/fe2aa706e8ff4edbcd109897e5da6b83ef6ad693 @@ -38,9 +38,9 @@ def patch_litellm(request: Any) -> Generator[None, None, None]: yield return - litellm_patcher.attempt_patch() + get_litellm_patcher().attempt_patch() yield - litellm_patcher.undo_patch() + get_litellm_patcher().undo_patch() @pytest.mark.skip_clickhouse_client # TODO:VCR recording does not seem to allow us to make requests to the clickhouse db in non-recording mode diff --git a/weave/integrations/anthropic/anthropic_sdk.py b/weave/integrations/anthropic/anthropic_sdk.py index 6e33e1a39062..9cd06f532594 100644 --- a/weave/integrations/anthropic/anthropic_sdk.py +++ b/weave/integrations/anthropic/anthropic_sdk.py @@ -1,27 +1,26 @@ +from __future__ import annotations + import importlib from collections.abc import AsyncIterator, Iterator from functools import wraps -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Optional, - Union, -) +from typing import TYPE_CHECKING, Any, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import _IteratorWrapper, add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher if TYPE_CHECKING: from anthropic.lib.streaming import MessageStream from anthropic.types import Message, MessageStreamEvent +_anthropic_patcher: MultiPatcher | None = None + def anthropic_accumulator( - acc: Optional["Message"], - value: "MessageStreamEvent", -) -> "Message": + acc: Message | None, + value: MessageStreamEvent, +) -> Message: from anthropic.types import ( ContentBlockDeltaEvent, Message, @@ -73,13 +72,11 @@ def should_use_accumulator(inputs: dict) -> bool: return isinstance(inputs, dict) and bool(inputs.get("stream")) -def create_wrapper_sync( - name: str, -) -> Callable[[Callable], Callable]: +def create_wrapper_sync(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: "We need to do this so we can check if `stream` is used" - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: anthropic_accumulator, @@ -92,9 +89,7 @@ def wrapper(fn: Callable) -> Callable: # Surprisingly, the async `client.chat.completions.create` does not pass # `inspect.iscoroutinefunction`, so we can't dispatch on it and must write # it manually here... -def create_wrapper_async( - name: str, -) -> Callable[[Callable], Callable]: +def create_wrapper_async(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: def _fn_wrapper(fn: Callable) -> Callable: @wraps(fn) @@ -104,8 +99,8 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return _async_wrapper "We need to do this so we can check if `stream` is used" - op = weave.op()(_fn_wrapper(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(_fn_wrapper(fn), **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: anthropic_accumulator, @@ -123,9 +118,9 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: def anthropic_stream_accumulator( - acc: Optional["Message"], - value: "MessageStream", -) -> "Message": + acc: Message | None, + value: MessageStream, +) -> Message: from anthropic.lib.streaming._types import MessageStopEvent if acc is None: @@ -150,7 +145,7 @@ def __getattr__(self, name: str) -> Any: return object.__getattribute__(self, name) return getattr(self._iterator_or_ctx_manager, name) - def __stream_text__(self) -> Union[Iterator[str], AsyncIterator[str]]: + def __stream_text__(self) -> Iterator[str] | AsyncIterator[str]: if isinstance(self._iterator_or_ctx_manager, AsyncIterator): return self.__async_stream_text__() else: @@ -167,16 +162,14 @@ async def __async_stream_text__(self) -> AsyncIterator[str]: # type: ignore yield chunk.delta.text # type: ignore @property - def text_stream(self) -> Union[Iterator[str], AsyncIterator[str]]: + def text_stream(self) -> Iterator[str] | AsyncIterator[str]: return self.__stream_text__() -def create_stream_wrapper( - name: str, -) -> Callable[[Callable], Callable]: +def create_stream_wrapper(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda _: anthropic_stream_accumulator, @@ -187,28 +180,58 @@ def wrapper(fn: Callable) -> Callable: return wrapper -anthropic_patcher = MultiPatcher( - [ - # Patch the sync messages.create method for all messages.create methods - SymbolPatcher( - lambda: importlib.import_module("anthropic.resources.messages"), - "Messages.create", - create_wrapper_sync(name="anthropic.Messages.create"), - ), - SymbolPatcher( - lambda: importlib.import_module("anthropic.resources.messages"), - "AsyncMessages.create", - create_wrapper_async(name="anthropic.AsyncMessages.create"), - ), - SymbolPatcher( - lambda: importlib.import_module("anthropic.resources.messages"), - "Messages.stream", - create_stream_wrapper(name="anthropic.Messages.stream"), - ), - SymbolPatcher( - lambda: importlib.import_module("anthropic.resources.messages"), - "AsyncMessages.stream", - create_stream_wrapper(name="anthropic.AsyncMessages.stream"), - ), - ] -) +def get_anthropic_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _anthropic_patcher + if _anthropic_patcher is not None: + return _anthropic_patcher + + base = settings.op_settings + + messages_create_settings = base.model_copy( + update={"name": base.name or "anthropic.Messages.create"} + ) + async_messages_create_settings = base.model_copy( + update={"name": base.name or "anthropic.AsyncMessages.create"} + ) + stream_settings = base.model_copy( + update={"name": base.name or "anthropic.Messages.stream"} + ) + async_stream_settings = base.model_copy( + update={"name": base.name or "anthropic.AsyncMessages.stream"} + ) + + _anthropic_patcher = MultiPatcher( + [ + # Patch the sync messages.create method for all messages.create methods + SymbolPatcher( + lambda: importlib.import_module("anthropic.resources.messages"), + "Messages.create", + create_wrapper_sync(messages_create_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("anthropic.resources.messages"), + "AsyncMessages.create", + create_wrapper_async(async_messages_create_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("anthropic.resources.messages"), + "Messages.stream", + create_stream_wrapper(stream_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("anthropic.resources.messages"), + "AsyncMessages.stream", + create_stream_wrapper(async_stream_settings), + ), + ] + ) + + return _anthropic_patcher diff --git a/weave/integrations/cerebras/cerebras_sdk.py b/weave/integrations/cerebras/cerebras_sdk.py index bdce368290e0..a2096a184e79 100644 --- a/weave/integrations/cerebras/cerebras_sdk.py +++ b/weave/integrations/cerebras/cerebras_sdk.py @@ -1,25 +1,26 @@ +from __future__ import annotations + import importlib from functools import wraps from typing import Any, Callable import weave -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.autopatch import IntegrationSettings, OpSettings +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher + +_cerebras_patcher: MultiPatcher | None = None -def create_wrapper_sync( - name: str, -) -> Callable[[Callable], Callable]: +def create_wrapper_sync(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return op return wrapper -def create_wrapper_async( - name: str, -) -> Callable[[Callable], Callable]: +def create_wrapper_async(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: def _fn_wrapper(fn: Callable) -> Callable: @wraps(fn) @@ -28,24 +29,45 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return _async_wrapper - op = weave.op()(_fn_wrapper(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(_fn_wrapper(fn), **op_kwargs) return op return wrapper -cerebras_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("cerebras.cloud.sdk.resources.chat"), - "CompletionsResource.create", - create_wrapper_sync(name="cerebras.chat.completions.create"), - ), - SymbolPatcher( - lambda: importlib.import_module("cerebras.cloud.sdk.resources.chat"), - "AsyncCompletionsResource.create", - create_wrapper_async(name="cerebras.chat.completions.create"), - ), - ] -) +def get_cerebras_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _cerebras_patcher + if _cerebras_patcher is not None: + return _cerebras_patcher + + base = settings.op_settings + + create_settings = base.model_copy( + update={"name": base.name or "cerebras.chat.completions.create"} + ) + + _cerebras_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module("cerebras.cloud.sdk.resources.chat"), + "CompletionsResource.create", + create_wrapper_sync(create_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("cerebras.cloud.sdk.resources.chat"), + "AsyncCompletionsResource.create", + create_wrapper_async(create_settings), + ), + ] + ) + + return _cerebras_patcher diff --git a/weave/integrations/cohere/__init__.py b/weave/integrations/cohere/__init__.py index 45f925b6eeac..288cce91aaea 100644 --- a/weave/integrations/cohere/__init__.py +++ b/weave/integrations/cohere/__init__.py @@ -1 +1 @@ -from weave.integrations.cohere.cohere_sdk import cohere_patcher as cohere_patcher +from weave.integrations.cohere.cohere_sdk import get_cohere_patcher # noqa: F401 diff --git a/weave/integrations/cohere/cohere_sdk.py b/weave/integrations/cohere/cohere_sdk.py index b0a5944795b4..a9b216c070b5 100644 --- a/weave/integrations/cohere/cohere_sdk.py +++ b/weave/integrations/cohere/cohere_sdk.py @@ -1,20 +1,23 @@ +from __future__ import annotations + import importlib from functools import wraps -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher if TYPE_CHECKING: from cohere.types.non_streamed_chat_response import NonStreamedChatResponse from cohere.v2.types.non_streamed_chat_response2 import NonStreamedChatResponse2 -def cohere_accumulator( - acc: Optional[dict], - value: Any, -) -> "NonStreamedChatResponse": +_cohere_patcher: MultiPatcher | None = None + + +def cohere_accumulator(acc: dict | None, value: Any) -> NonStreamedChatResponse: # don't need to accumulate, is build-in by cohere! # https://docs.cohere.com/docs/streaming # A stream-end event is the final event of the stream, and is returned only when streaming is finished. @@ -31,10 +34,7 @@ def cohere_accumulator( return acc -def cohere_accumulator_v2( - acc: Optional[dict], - value: Any, -) -> "NonStreamedChatResponse2": +def cohere_accumulator_v2(acc: dict | None, value: Any) -> NonStreamedChatResponse2: from cohere.v2.types.assistant_message_response import AssistantMessageResponse from cohere.v2.types.non_streamed_chat_response2 import NonStreamedChatResponse2 @@ -86,16 +86,16 @@ def _accumulate_content( return acc -def cohere_wrapper(name: str) -> Callable: +def cohere_wrapper(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: - op = weave.op(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return op return wrapper -def cohere_wrapper_v2(name: str) -> Callable: +def cohere_wrapper_v2(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: def _post_process_response(fn: Callable) -> Any: @wraps(fn) @@ -122,14 +122,14 @@ def _wrapper(*args: Any, **kwargs: Any) -> Any: return _wrapper - op = weave.op(_post_process_response(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(_post_process_response(fn), **op_kwargs) return op return wrapper -def cohere_wrapper_async_v2(name: str) -> Callable: +def cohere_wrapper_async_v2(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: def _post_process_response(fn: Callable) -> Any: @wraps(fn) @@ -156,81 +156,119 @@ async def _wrapper(*args: Any, **kwargs: Any) -> Any: return _wrapper - op = weave.op(_post_process_response(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(_post_process_response(fn), **op_kwargs) return op return wrapper -def cohere_stream_wrapper(name: str) -> Callable: +def cohere_stream_wrapper(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: - op = weave.op(fn) - op.name = name # type: ignore - return add_accumulator(op, lambda inputs: cohere_accumulator) # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) + return add_accumulator(op, lambda inputs: cohere_accumulator) return wrapper -def cohere_stream_wrapper_v2(name: str) -> Callable: +def cohere_stream_wrapper_v2(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: - op = weave.op(fn) - op.name = name # type: ignore - return add_accumulator( - op, make_accumulator=lambda inputs: cohere_accumulator_v2 - ) + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) + return add_accumulator(op, lambda inputs: cohere_accumulator_v2) return wrapper -cohere_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "Client.chat", - cohere_wrapper("cohere.Client.chat"), - ), - # Patch the async chat method - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "AsyncClient.chat", - cohere_wrapper("cohere.AsyncClient.chat"), - ), - # Add patch for chat_stream method - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "Client.chat_stream", - cohere_stream_wrapper("cohere.Client.chat_stream"), - ), - # Add patch for async chat_stream method - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "AsyncClient.chat_stream", - cohere_stream_wrapper("cohere.AsyncClient.chat_stream"), - ), - # Add patch for cohere v2 - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "ClientV2.chat", - cohere_wrapper_v2("cohere.ClientV2.chat"), - ), - # Add patch for cohre v2 async chat method - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "AsyncClientV2.chat", - cohere_wrapper_async_v2("cohere.AsyncClientV2.chat"), - ), - # Add patch for chat_stream method v2 - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "ClientV2.chat_stream", - cohere_stream_wrapper_v2("cohere.ClientV2.chat_stream"), - ), - # Add patch for async chat_stream method v2 - SymbolPatcher( - lambda: importlib.import_module("cohere"), - "AsyncClientV2.chat_stream", - cohere_stream_wrapper_v2("cohere.AsyncClientV2.chat_stream"), - ), - ] -) +def get_cohere_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _cohere_patcher + if _cohere_patcher is not None: + return _cohere_patcher + + base = settings.op_settings + + chat_settings = base.model_copy(update={"name": base.name or "cohere.Client.chat"}) + async_chat_settings = base.model_copy( + update={"name": base.name or "cohere.AsyncClient.chat"} + ) + chat_stream_settings = base.model_copy( + update={"name": base.name or "cohere.Client.chat_stream"} + ) + async_chat_stream_settings = base.model_copy( + update={"name": base.name or "cohere.AsyncClient.chat_stream"} + ) + chat_v2_settings = base.model_copy( + update={"name": base.name or "cohere.ClientV2.chat"} + ) + async_chat_v2_settings = base.model_copy( + update={"name": base.name or "cohere.AsyncClientV2.chat"} + ) + chat_stream_v2_settings = base.model_copy( + update={"name": base.name or "cohere.ClientV2.chat_stream"} + ) + async_chat_stream_v2_settings = base.model_copy( + update={"name": base.name or "cohere.AsyncClientV2.chat_stream"} + ) + + _cohere_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "Client.chat", + cohere_wrapper(chat_settings), + ), + # Patch the async chat method + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "AsyncClient.chat", + cohere_wrapper(async_chat_settings), + ), + # Add patch for chat_stream method + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "Client.chat_stream", + cohere_stream_wrapper(chat_stream_settings), + ), + # Add patch for async chat_stream method + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "AsyncClient.chat_stream", + cohere_stream_wrapper(async_chat_stream_settings), + ), + # Add patch for cohere v2 + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "ClientV2.chat", + cohere_wrapper_v2(chat_v2_settings), + ), + # Add patch for cohre v2 async chat method + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "AsyncClientV2.chat", + cohere_wrapper_async_v2(async_chat_v2_settings), + ), + # Add patch for chat_stream method v2 + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "ClientV2.chat_stream", + cohere_stream_wrapper_v2(chat_stream_v2_settings), + ), + # Add patch for async chat_stream method v2 + SymbolPatcher( + lambda: importlib.import_module("cohere"), + "AsyncClientV2.chat_stream", + cohere_stream_wrapper_v2(async_chat_stream_v2_settings), + ), + ] + ) + + return _cohere_patcher diff --git a/weave/integrations/dspy/dspy_sdk.py b/weave/integrations/dspy/dspy_sdk.py index b205c77a4588..25293b0f4947 100644 --- a/weave/integrations/dspy/dspy_sdk.py +++ b/weave/integrations/dspy/dspy_sdk.py @@ -1,216 +1,331 @@ +from __future__ import annotations + import importlib from typing import Callable import weave -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.autopatch import IntegrationSettings, OpSettings +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher + +_dspy_patcher: MultiPatcher | None = None -def dspy_wrapper(name: str) -> Callable[[Callable], Callable]: +def dspy_wrapper(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return op return wrapper def dspy_get_patched_lm_functions( - base_symbol: str, lm_class_name: str + base_symbol: str, lm_class_name: str, settings: OpSettings ) -> list[SymbolPatcher]: patchable_functional_attributes = [ "basic_request", "request", "__call__", ] + basic_request_settings = settings.model_copy( + update={"name": settings.name or f"{base_symbol}.{lm_class_name}.basic_request"} + ) + request_settings = settings.model_copy( + update={"name": settings.name or f"{base_symbol}.{lm_class_name}.request"} + ) + call_settings = settings.model_copy( + update={"name": settings.name or f"{base_symbol}.{lm_class_name}"} + ) return [ SymbolPatcher( get_base_symbol=lambda: importlib.import_module(base_symbol), attribute_name=f"{lm_class_name}.basic_request", - make_new_value=dspy_wrapper(f"dspy.{lm_class_name}.basic_request"), + make_new_value=dspy_wrapper(basic_request_settings), ), SymbolPatcher( get_base_symbol=lambda: importlib.import_module(base_symbol), attribute_name=f"{lm_class_name}.request", - make_new_value=dspy_wrapper(f"dspy.{lm_class_name}.request"), + make_new_value=dspy_wrapper(request_settings), ), SymbolPatcher( get_base_symbol=lambda: importlib.import_module(base_symbol), attribute_name=f"{lm_class_name}.__call__", - make_new_value=dspy_wrapper(f"dspy.{lm_class_name}"), + make_new_value=dspy_wrapper(call_settings), + ), + ] + + +def get_dspy_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _dspy_patcher + if _dspy_patcher is not None: + return _dspy_patcher + + base = settings.op_settings + + predict_call_settings = base.model_copy( + update={"name": base.name or "dspy.Predict"} + ) + predict_forward_settings = base.model_copy( + update={"name": base.name or "dspy.Predict.forward"} + ) + typed_predictor_call_settings = base.model_copy( + update={"name": base.name or "dspy.TypedPredictor"} + ) + typed_predictor_forward_settings = base.model_copy( + update={"name": base.name or "dspy.TypedPredictor.forward"} + ) + module_call_settings = base.model_copy(update={"name": base.name or "dspy.Module"}) + typed_chain_of_thought_call_settings = base.model_copy( + update={"name": base.name or "dspy.TypedChainOfThought"} + ) + retrieve_call_settings = base.model_copy( + update={"name": base.name or "dspy.Retrieve"} + ) + retrieve_forward_settings = base.model_copy( + update={"name": base.name or "dspy.Retrieve.forward"} + ) + evaluate_call_settings = base.model_copy( + update={"name": base.name or "dspy.evaluate.Evaluate"} + ) + bootstrap_few_shot_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.BootstrapFewShot.compile"} + ) + copro_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.COPRO.compile"} + ) + ensemble_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.Ensemble.compile"} + ) + bootstrap_finetune_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.BootstrapFinetune.compile"} + ) + knn_few_shot_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.KNNFewShot.compile"} + ) + mipro_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.MIPRO.compile"} + ) + bootstrap_few_shot_with_random_search_compile_settings = base.model_copy( + update={ + "name": base.name + or "dspy.teleprompt.BootstrapFewShotWithRandomSearch.compile" + } + ) + signature_optimizer_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.SignatureOptimizer.compile"} + ) + bayesian_signature_optimizer_compile_settings = base.model_copy( + update={ + "name": base.name or "dspy.teleprompt.BayesianSignatureOptimizer.compile" + } + ) + signature_opt_typed_optimize_signature_settings = base.model_copy( + update={ + "name": base.name + or "dspy.teleprompt.signature_opt_typed.optimize_signature" + } + ) + bootstrap_few_shot_with_optuna_compile_settings = base.model_copy( + update={ + "name": base.name or "dspy.teleprompt.BootstrapFewShotWithOptuna.compile" + } + ) + labeled_few_shot_compile_settings = base.model_copy( + update={"name": base.name or "dspy.teleprompt.LabeledFewShot.compile"} + ) + + patched_functions = [ + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Predict.__call__", + make_new_value=dspy_wrapper(predict_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Predict.forward", + make_new_value=dspy_wrapper(predict_forward_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="TypedPredictor.__call__", + make_new_value=dspy_wrapper(typed_predictor_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="TypedPredictor.forward", + make_new_value=dspy_wrapper(typed_predictor_forward_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Module.__call__", + make_new_value=dspy_wrapper(module_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="TypedChainOfThought.__call__", + make_new_value=dspy_wrapper(typed_chain_of_thought_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Retrieve.__call__", + make_new_value=dspy_wrapper(retrieve_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Retrieve.forward", + make_new_value=dspy_wrapper(retrieve_forward_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.evaluate.evaluate"), + attribute_name="Evaluate.__call__", + make_new_value=dspy_wrapper(evaluate_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="BootstrapFewShot.compile", + make_new_value=dspy_wrapper(bootstrap_few_shot_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="COPRO.compile", + make_new_value=dspy_wrapper(copro_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="Ensemble.compile", + make_new_value=dspy_wrapper(ensemble_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="BootstrapFinetune.compile", + make_new_value=dspy_wrapper(bootstrap_finetune_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="KNNFewShot.compile", + make_new_value=dspy_wrapper(knn_few_shot_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="MIPRO.compile", + make_new_value=dspy_wrapper(mipro_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="BootstrapFewShotWithRandomSearch.compile", + make_new_value=dspy_wrapper( + bootstrap_few_shot_with_random_search_compile_settings + ), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="SignatureOptimizer.compile", + make_new_value=dspy_wrapper(signature_optimizer_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="BayesianSignatureOptimizer.compile", + make_new_value=dspy_wrapper(bayesian_signature_optimizer_compile_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module( + "dspy.teleprompt.signature_opt_typed" + ), + attribute_name="optimize_signature", + make_new_value=dspy_wrapper( + signature_opt_typed_optimize_signature_settings + ), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="BootstrapFewShotWithOptuna.compile", + make_new_value=dspy_wrapper( + bootstrap_few_shot_with_optuna_compile_settings + ), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), + attribute_name="LabeledFewShot.compile", + make_new_value=dspy_wrapper(labeled_few_shot_compile_settings), + ), + ] + + # Patch LM classes + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="AzureOpenAI", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="OpenAI", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="Cohere", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="Clarifai", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="Google", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="HFClientTGI", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="HFClientVLLM", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="Anyscale", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="Together", settings=base + ) + patched_functions += dspy_get_patched_lm_functions( + base_symbol="dspy", lm_class_name="OllamaLocal", settings=base + ) + + databricks_basic_request_settings = base.model_copy( + update={"name": base.name or "dspy.Databricks.basic_request"} + ) + databricks_call_settings = base.model_copy( + update={"name": base.name or "dspy.Databricks"} + ) + colbertv2_call_settings = base.model_copy( + update={"name": base.name or "dspy.ColBERTv2"} + ) + pyserini_call_settings = base.model_copy( + update={"name": base.name or "dspy.Pyserini"} + ) + + patched_functions += [ + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Databricks.basic_request", + make_new_value=dspy_wrapper(databricks_basic_request_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Databricks.__call__", + make_new_value=dspy_wrapper(databricks_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="ColBERTv2.__call__", + make_new_value=dspy_wrapper(colbertv2_call_settings), + ), + SymbolPatcher( + get_base_symbol=lambda: importlib.import_module("dspy"), + attribute_name="Pyserini.__call__", + make_new_value=dspy_wrapper(pyserini_call_settings), ), ] + _dspy_patcher = MultiPatcher(patched_functions) -patched_functions = [ - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Predict.__call__", - make_new_value=dspy_wrapper("dspy.Predict"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Predict.forward", - make_new_value=dspy_wrapper("dspy.Predict.forward"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="TypedPredictor.__call__", - make_new_value=dspy_wrapper("dspy.TypedPredictor"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="TypedPredictor.forward", - make_new_value=dspy_wrapper("dspy.TypedPredictor.forward"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Module.__call__", - make_new_value=dspy_wrapper("dspy.Module"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="TypedChainOfThought.__call__", - make_new_value=dspy_wrapper("dspy.TypedChainOfThought"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Retrieve.__call__", - make_new_value=dspy_wrapper("dspy.Retrieve"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Retrieve.forward", - make_new_value=dspy_wrapper("dspy.Retrieve.forward"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.evaluate.evaluate"), - attribute_name="Evaluate.__call__", - make_new_value=dspy_wrapper("dspy.evaluate.Evaluate"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="BootstrapFewShot.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.BootstrapFewShot.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="COPRO.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.COPRO.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="Ensemble.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.Ensemble.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="BootstrapFinetune.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.BootstrapFinetune.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="KNNFewShot.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.KNNFewShot.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="MIPRO.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.MIPRO.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="BootstrapFewShotWithRandomSearch.compile", - make_new_value=dspy_wrapper( - "dspy.teleprompt.BootstrapFewShotWithRandomSearch.compile" - ), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="SignatureOptimizer.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.SignatureOptimizer.compile"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="BayesianSignatureOptimizer.compile", - make_new_value=dspy_wrapper( - "dspy.teleprompt.BayesianSignatureOptimizer.compile" - ), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module( - "dspy.teleprompt.signature_opt_typed" - ), - attribute_name="optimize_signature", - make_new_value=dspy_wrapper( - "dspy.teleprompt.signature_opt_typed.optimize_signature" - ), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="BootstrapFewShotWithOptuna.compile", - make_new_value=dspy_wrapper( - "dspy.teleprompt.BootstrapFewShotWithOptuna.compile" - ), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy.teleprompt"), - attribute_name="LabeledFewShot.compile", - make_new_value=dspy_wrapper("dspy.teleprompt.LabeledFewShot.compile"), - ), -] - -# Patch LM classes -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="AzureOpenAI" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="OpenAI" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="Cohere" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="Clarifai" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="Google" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="HFClientTGI" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="HFClientVLLM" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="Anyscale" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="Together" -) -patched_functions += dspy_get_patched_lm_functions( - base_symbol="dspy", lm_class_name="OllamaLocal" -) -patched_functions += [ - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Databricks.basic_request", - make_new_value=dspy_wrapper("dspy.Databricks.basic_request"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Databricks.__call__", - make_new_value=dspy_wrapper("dspy.Databricks"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="ColBERTv2.__call__", - make_new_value=dspy_wrapper("dspy.ColBERTv2"), - ), - SymbolPatcher( - get_base_symbol=lambda: importlib.import_module("dspy"), - attribute_name="Pyserini.__call__", - make_new_value=dspy_wrapper("dspy.Pyserini"), - ), -] - -dspy_patcher = MultiPatcher(patched_functions) + return _dspy_patcher diff --git a/weave/integrations/google_ai_studio/google_ai_studio_sdk.py b/weave/integrations/google_ai_studio/google_ai_studio_sdk.py index 2cd8a2fe1377..7c4e6d2a7406 100644 --- a/weave/integrations/google_ai_studio/google_ai_studio_sdk.py +++ b/weave/integrations/google_ai_studio/google_ai_studio_sdk.py @@ -1,16 +1,21 @@ +from __future__ import annotations + import importlib from functools import wraps -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher from weave.trace.serialize import dictify from weave.trace.weave_client import Call if TYPE_CHECKING: from google.generativeai.types.generation_types import GenerateContentResponse +_google_genai_patcher: MultiPatcher | None = None + def gemini_postprocess_inputs(inputs: dict[str, Any]) -> dict[str, Any]: if "self" in inputs: @@ -19,8 +24,8 @@ def gemini_postprocess_inputs(inputs: dict[str, Any]) -> dict[str, Any]: def gemini_accumulator( - acc: Optional["GenerateContentResponse"], value: "GenerateContentResponse" -) -> "GenerateContentResponse": + acc: GenerateContentResponse | None, value: GenerateContentResponse +) -> GenerateContentResponse: if acc is None: return value @@ -64,9 +69,7 @@ def gemini_accumulator( return acc -def gemini_on_finish( - call: Call, output: Any, exception: Optional[BaseException] -) -> None: +def gemini_on_finish(call: Call, output: Any, exception: BaseException | None) -> None: if "model_name" in call.inputs["self"]: original_model_name = call.inputs["self"]["model_name"] elif "model" in call.inputs["self"]: @@ -89,10 +92,13 @@ def gemini_on_finish( call.summary.update(summary_update) -def gemini_wrapper_sync(name: str) -> Callable[[Callable], Callable]: +def gemini_wrapper_sync(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op(postprocess_inputs=gemini_postprocess_inputs)(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + if not op_kwargs.get("postprocess_inputs"): + op_kwargs["postprocess_inputs"] = gemini_postprocess_inputs + + op = weave.op(fn, **op_kwargs) op._set_on_finish_handler(gemini_on_finish) return add_accumulator( op, # type: ignore @@ -104,7 +110,7 @@ def wrapper(fn: Callable) -> Callable: return wrapper -def gemini_wrapper_async(name: str) -> Callable[[Callable], Callable]: +def gemini_wrapper_async(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: def _fn_wrapper(fn: Callable) -> Callable: @wraps(fn) @@ -113,9 +119,11 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return _async_wrapper - "We need to do this so we can check if `stream` is used" - op = weave.op(postprocess_inputs=gemini_postprocess_inputs)(_fn_wrapper(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + if not op_kwargs.get("postprocess_inputs"): + op_kwargs["postprocess_inputs"] = gemini_postprocess_inputs + + op = weave.op(_fn_wrapper(fn), **op_kwargs) op._set_on_finish_handler(gemini_on_finish) return add_accumulator( op, # type: ignore @@ -127,33 +135,72 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return wrapper -google_genai_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("google.generativeai.generative_models"), - "GenerativeModel.generate_content", - gemini_wrapper_sync( - name="google.generativeai.GenerativeModel.generate_content" +def get_google_genai_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _google_genai_patcher + if _google_genai_patcher is not None: + return _google_genai_patcher + + base = settings.op_settings + + generate_content_settings = base.model_copy( + update={ + "name": base.name or "google.generativeai.GenerativeModel.generate_content" + } + ) + generate_content_async_settings = base.model_copy( + update={ + "name": base.name + or "google.generativeai.GenerativeModel.generate_content_async" + } + ) + send_message_settings = base.model_copy( + update={"name": base.name or "google.generativeai.ChatSession.send_message"} + ) + send_message_async_settings = base.model_copy( + update={ + "name": base.name or "google.generativeai.ChatSession.send_message_async" + } + ) + + _google_genai_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module( + "google.generativeai.generative_models" + ), + "GenerativeModel.generate_content", + gemini_wrapper_sync(generate_content_settings), + ), + SymbolPatcher( + lambda: importlib.import_module( + "google.generativeai.generative_models" + ), + "GenerativeModel.generate_content_async", + gemini_wrapper_async(generate_content_async_settings), ), - ), - SymbolPatcher( - lambda: importlib.import_module("google.generativeai.generative_models"), - "GenerativeModel.generate_content_async", - gemini_wrapper_async( - name="google.generativeai.GenerativeModel.generate_content_async" + SymbolPatcher( + lambda: importlib.import_module( + "google.generativeai.generative_models" + ), + "ChatSession.send_message", + gemini_wrapper_sync(send_message_settings), ), - ), - SymbolPatcher( - lambda: importlib.import_module("google.generativeai.generative_models"), - "ChatSession.send_message", - gemini_wrapper_sync(name="google.generativeai.ChatSession.send_message"), - ), - SymbolPatcher( - lambda: importlib.import_module("google.generativeai.generative_models"), - "ChatSession.send_message_async", - gemini_wrapper_async( - name="google.generativeai.ChatSession.send_message_async" + SymbolPatcher( + lambda: importlib.import_module( + "google.generativeai.generative_models" + ), + "ChatSession.send_message_async", + gemini_wrapper_async(send_message_async_settings), ), - ), - ] -) + ] + ) + + return _google_genai_patcher diff --git a/weave/integrations/groq/groq_sdk.py b/weave/integrations/groq/groq_sdk.py index 4f470e6d7437..c5c07fd705f7 100644 --- a/weave/integrations/groq/groq_sdk.py +++ b/weave/integrations/groq/groq_sdk.py @@ -1,17 +1,23 @@ +from __future__ import annotations + import importlib -from typing import TYPE_CHECKING, Callable, Optional +from typing import TYPE_CHECKING, Callable + +import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings +from weave.trace.op_extensions.accumulator import add_accumulator +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher if TYPE_CHECKING: from groq.types.chat import ChatCompletion, ChatCompletionChunk -import weave -from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher + +_groq_patcher: MultiPatcher | None = None def groq_accumulator( - acc: Optional["ChatCompletion"], value: "ChatCompletionChunk" -) -> "ChatCompletion": + acc: ChatCompletion | None, value: ChatCompletionChunk +) -> ChatCompletion: from groq.types.chat import ChatCompletion, ChatCompletionMessage from groq.types.chat.chat_completion import Choice from groq.types.chat.chat_completion_chunk import Choice as ChoiceChunk @@ -83,11 +89,10 @@ def should_use_accumulator(inputs: dict) -> bool: return isinstance(inputs, dict) and bool(inputs.get("stream")) -def groq_wrapper(name: str) -> Callable[[Callable], Callable]: +def groq_wrapper(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore - # return op + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: groq_accumulator, @@ -97,17 +102,41 @@ def wrapper(fn: Callable) -> Callable: return wrapper -groq_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("groq.resources.chat.completions"), - "Completions.create", - groq_wrapper(name="groq.chat.completions.create"), - ), - SymbolPatcher( - lambda: importlib.import_module("groq.resources.chat.completions"), - "AsyncCompletions.create", - groq_wrapper(name="groq.async.chat.completions.create"), - ), - ] -) +def get_groq_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _groq_patcher + if _groq_patcher is not None: + return _groq_patcher + + base = settings.op_settings + + chat_completions_settings = base.model_copy( + update={"name": base.name or "groq.chat.completions.create"} + ) + async_chat_completions_settings = base.model_copy( + update={"name": base.name or "groq.async.chat.completions.create"} + ) + + _groq_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module("groq.resources.chat.completions"), + "Completions.create", + groq_wrapper(chat_completions_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("groq.resources.chat.completions"), + "AsyncCompletions.create", + groq_wrapper(async_chat_completions_settings), + ), + ] + ) + + return _groq_patcher diff --git a/weave/integrations/instructor/instructor_iterable_utils.py b/weave/integrations/instructor/instructor_iterable_utils.py index 84d64a103b6b..3b0f128a1320 100644 --- a/weave/integrations/instructor/instructor_iterable_utils.py +++ b/weave/integrations/instructor/instructor_iterable_utils.py @@ -4,6 +4,7 @@ from pydantic import BaseModel import weave +from weave.trace.autopatch import OpSettings from weave.trace.op_extensions.accumulator import add_accumulator @@ -27,10 +28,10 @@ def should_accumulate_iterable(inputs: dict) -> bool: return False -def instructor_wrapper_sync(name: str) -> Callable[[Callable], Callable]: +def instructor_wrapper_sync(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: instructor_iterable_accumulator, @@ -40,7 +41,7 @@ def wrapper(fn: Callable) -> Callable: return wrapper -def instructor_wrapper_async(name: str) -> Callable[[Callable], Callable]: +def instructor_wrapper_async(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: def _fn_wrapper(fn: Callable) -> Callable: @wraps(fn) @@ -49,9 +50,8 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return _async_wrapper - "We need to do this so we can check if `stream` is used" - op = weave.op(_fn_wrapper(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(_fn_wrapper(fn), **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: instructor_iterable_accumulator, diff --git a/weave/integrations/instructor/instructor_partial_utils.py b/weave/integrations/instructor/instructor_partial_utils.py index f90dc7edb17b..8efa84b302f8 100644 --- a/weave/integrations/instructor/instructor_partial_utils.py +++ b/weave/integrations/instructor/instructor_partial_utils.py @@ -3,6 +3,7 @@ from pydantic import BaseModel import weave +from weave.trace.autopatch import OpSettings from weave.trace.op_extensions.accumulator import add_accumulator @@ -14,10 +15,10 @@ def instructor_partial_accumulator( return acc -def instructor_wrapper_partial(name: str) -> Callable[[Callable], Callable]: +def instructor_wrapper_partial(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: instructor_partial_accumulator, diff --git a/weave/integrations/instructor/instructor_sdk.py b/weave/integrations/instructor/instructor_sdk.py index 867e9f2a785e..00dfde029c9c 100644 --- a/weave/integrations/instructor/instructor_sdk.py +++ b/weave/integrations/instructor/instructor_sdk.py @@ -1,31 +1,65 @@ +from __future__ import annotations + import importlib -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.autopatch import IntegrationSettings +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher from .instructor_iterable_utils import instructor_wrapper_async, instructor_wrapper_sync from .instructor_partial_utils import instructor_wrapper_partial -instructor_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("instructor.client"), - "Instructor.create", - instructor_wrapper_sync(name="Instructor.create"), - ), - SymbolPatcher( - lambda: importlib.import_module("instructor.client"), - "AsyncInstructor.create", - instructor_wrapper_async(name="AsyncInstructor.create"), - ), - SymbolPatcher( - lambda: importlib.import_module("instructor.client"), - "Instructor.create_partial", - instructor_wrapper_partial(name="Instructor.create_partial"), - ), - SymbolPatcher( - lambda: importlib.import_module("instructor.client"), - "AsyncInstructor.create_partial", - instructor_wrapper_partial(name="AsyncInstructor.create_partial"), - ), - ] -) +_instructor_patcher: MultiPatcher | None = None + + +def get_instructor_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _instructor_patcher + if _instructor_patcher is not None: + return _instructor_patcher + + base = settings.op_settings + + create_settings = base.model_copy(update={"name": base.name or "Instructor.create"}) + async_create_settings = base.model_copy( + update={"name": base.name or "AsyncInstructor.create"} + ) + create_partial_settings = base.model_copy( + update={"name": base.name or "Instructor.create_partial"} + ) + async_create_partial_settings = base.model_copy( + update={"name": base.name or "AsyncInstructor.create_partial"} + ) + + _instructor_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module("instructor.client"), + "Instructor.create", + instructor_wrapper_sync(create_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("instructor.client"), + "AsyncInstructor.create", + instructor_wrapper_async(async_create_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("instructor.client"), + "Instructor.create_partial", + instructor_wrapper_partial(create_partial_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("instructor.client"), + "AsyncInstructor.create_partial", + instructor_wrapper_partial(async_create_partial_settings), + ), + ] + ) + + return _instructor_patcher diff --git a/weave/integrations/litellm/litellm.py b/weave/integrations/litellm/litellm.py index c3bf1bf114a2..9ae6e492c84e 100644 --- a/weave/integrations/litellm/litellm.py +++ b/weave/integrations/litellm/litellm.py @@ -1,19 +1,24 @@ +from __future__ import annotations + import importlib -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher if TYPE_CHECKING: from litellm.utils import ModelResponse +_litellm_patcher: MultiPatcher | None = None + # This accumulator is nearly identical to the mistral accumulator, just with different types. def litellm_accumulator( - acc: Optional["ModelResponse"], - value: "ModelResponse", -) -> "ModelResponse": + acc: ModelResponse | None, + value: ModelResponse, +) -> ModelResponse: # This import should be safe at this point from litellm.utils import Choices, Message, ModelResponse, Usage @@ -82,10 +87,10 @@ def should_use_accumulator(inputs: dict) -> bool: return isinstance(inputs, dict) and bool(inputs.get("stream")) -def make_wrapper(name: str) -> Callable: +def make_wrapper(settings: OpSettings) -> Callable: def litellm_wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return add_accumulator( op, # type: ignore make_accumulator=lambda inputs: litellm_accumulator, @@ -96,17 +101,41 @@ def litellm_wrapper(fn: Callable) -> Callable: return litellm_wrapper -litellm_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("litellm"), - "completion", - make_wrapper("litellm.completion"), - ), - SymbolPatcher( - lambda: importlib.import_module("litellm"), - "acompletion", - make_wrapper("litellm.acompletion"), - ), - ] -) +def get_litellm_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _litellm_patcher + if _litellm_patcher is not None: + return _litellm_patcher + + base = settings.op_settings + + completion_settings = base.model_copy( + update={"name": base.name or "litellm.completion"} + ) + acompletion_settings = base.model_copy( + update={"name": base.name or "litellm.acompletion"} + ) + + _litellm_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module("litellm"), + "completion", + make_wrapper(completion_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("litellm"), + "acompletion", + make_wrapper(acompletion_settings), + ), + ] + ) + + return _litellm_patcher diff --git a/weave/integrations/mistral/__init__.py b/weave/integrations/mistral/__init__.py index 34b40835efcf..d78812d9afa8 100644 --- a/weave/integrations/mistral/__init__.py +++ b/weave/integrations/mistral/__init__.py @@ -8,10 +8,10 @@ mistral_version = "1.0" # we need to return a patching function if version.parse(mistral_version) < version.parse("1.0.0"): - from .v0.mistral import mistral_patcher + from .v0.mistral import get_mistral_patcher # noqa: F401 print( f"Using MistralAI version {mistral_version}. Please consider upgrading to version 1.0.0 or later." ) else: - from .v1.mistral import mistral_patcher # noqa: F401 + from .v1.mistral import get_mistral_patcher # noqa: F401 diff --git a/weave/integrations/mistral/v0/mistral.py b/weave/integrations/mistral/v0/mistral.py index 6d4915eab41b..70a3fa183bb8 100644 --- a/weave/integrations/mistral/v0/mistral.py +++ b/weave/integrations/mistral/v0/mistral.py @@ -1,9 +1,12 @@ +from __future__ import annotations + import importlib -from typing import TYPE_CHECKING, Callable, Optional +from typing import TYPE_CHECKING, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher if TYPE_CHECKING: from mistralai.models.chat_completion import ( @@ -11,11 +14,13 @@ ChatCompletionStreamResponse, ) +_mistral_patcher: MultiPatcher | None = None + def mistral_accumulator( - acc: Optional["ChatCompletionResponse"], - value: "ChatCompletionStreamResponse", -) -> "ChatCompletionResponse": + acc: ChatCompletionResponse | None, + value: ChatCompletionStreamResponse, +) -> ChatCompletionResponse: # This import should be safe at this point from mistralai.models.chat_completion import ( ChatCompletionResponse, @@ -72,37 +77,78 @@ def mistral_accumulator( return acc -def mistral_stream_wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - acc_op = add_accumulator(op, lambda inputs: mistral_accumulator) # type: ignore - return acc_op - - -mistral_patcher = MultiPatcher( - [ - # Patch the sync, non-streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.client"), - "MistralClient.chat", - weave.op(), - ), - # Patch the sync, streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.client"), - "MistralClient.chat_stream", - mistral_stream_wrapper, - ), - # Patch the async, non-streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.async_client"), - "MistralAsyncClient.chat", - weave.op(), - ), - # Patch the async, streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.async_client"), - "MistralAsyncClient.chat_stream", - mistral_stream_wrapper, - ), - ] -) +def mistral_stream_wrapper(settings: OpSettings) -> Callable: + def wrapper(fn: Callable) -> Callable: + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) + acc_op = add_accumulator(op, lambda inputs: mistral_accumulator) # type: ignore + return acc_op + + return wrapper + + +def mistral_wrapper(settings: OpSettings) -> Callable: + def wrapper(fn: Callable) -> Callable: + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) + return op + + return wrapper + + +def get_mistral_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _mistral_patcher + if _mistral_patcher is not None: + return _mistral_patcher + + base = settings.op_settings + + chat_settings = base.model_copy(update={"name": base.name or "mistralai.chat"}) + chat_stream_settings = base.model_copy( + update={"name": base.name or "mistralai.chat_stream"} + ) + async_chat_settings = base.model_copy( + update={"name": base.name or "mistralai.async_client.chat"} + ) + async_chat_stream_settings = base.model_copy( + update={"name": base.name or "mistralai.async_client.chat_stream"} + ) + + _mistral_patcher = MultiPatcher( + [ + # Patch the sync, non-streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.client"), + "MistralClient.chat", + mistral_wrapper(chat_settings), + ), + # Patch the sync, streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.client"), + "MistralClient.chat_stream", + mistral_stream_wrapper(chat_stream_settings), + ), + # Patch the async, non-streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.async_client"), + "MistralAsyncClient.chat", + mistral_wrapper(async_chat_settings), + ), + # Patch the async, streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.async_client"), + "MistralAsyncClient.chat_stream", + mistral_stream_wrapper(async_chat_stream_settings), + ), + ] + ) + + return _mistral_patcher diff --git a/weave/integrations/mistral/v1/mistral.py b/weave/integrations/mistral/v1/mistral.py index 692aa7b159bf..d52d42af3c4f 100644 --- a/weave/integrations/mistral/v1/mistral.py +++ b/weave/integrations/mistral/v1/mistral.py @@ -1,9 +1,12 @@ +from __future__ import annotations + import importlib -from typing import TYPE_CHECKING, Callable, Optional +from typing import TYPE_CHECKING, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher if TYPE_CHECKING: from mistralai.models import ( @@ -11,11 +14,13 @@ CompletionEvent, ) +_mistral_patcher: MultiPatcher | None = None + def mistral_accumulator( - acc: Optional["ChatCompletionResponse"], - value: "CompletionEvent", -) -> "ChatCompletionResponse": + acc: ChatCompletionResponse | None, + value: CompletionEvent, +) -> ChatCompletionResponse: # This import should be safe at this point from mistralai.models import ( AssistantMessage, @@ -79,50 +84,79 @@ def mistral_accumulator( return acc -def mistral_stream_wrapper(name: str) -> Callable: +def mistral_stream_wrapper(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) acc_op = add_accumulator(op, lambda inputs: mistral_accumulator) # type: ignore - acc_op.name = name # type: ignore return acc_op return wrapper -def mistral_wrapper(name: str) -> Callable: +def mistral_wrapper(settings: OpSettings) -> Callable: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return op return wrapper -mistral_patcher = MultiPatcher( - [ - # Patch the sync, non-streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.chat"), - "Chat.complete", - mistral_wrapper(name="Mistral.chat.complete"), - ), - # Patch the sync, streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.chat"), - "Chat.stream", - mistral_stream_wrapper(name="Mistral.chat.stream"), - ), - # Patch the async, non-streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.chat"), - "Chat.complete_async", - mistral_wrapper(name="Mistral.chat.complete_async"), - ), - # Patch the async, streaming chat method - SymbolPatcher( - lambda: importlib.import_module("mistralai.chat"), - "Chat.stream_async", - mistral_stream_wrapper(name="Mistral.chat.stream_async"), - ), - ] -) +def get_mistral_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _mistral_patcher + if _mistral_patcher is not None: + return _mistral_patcher + + base = settings.op_settings + chat_complete_settings = base.model_copy( + update={"name": base.name or "mistralai.chat.complete"} + ) + chat_stream_settings = base.model_copy( + update={"name": base.name or "mistralai.chat.stream"} + ) + async_chat_complete_settings = base.model_copy( + update={"name": base.name or "mistralai.async_client.chat.complete"} + ) + async_chat_stream_settings = base.model_copy( + update={"name": base.name or "mistralai.async_client.chat.stream"} + ) + + _mistral_patcher = MultiPatcher( + [ + # Patch the sync, non-streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.chat"), + "Chat.complete", + mistral_wrapper(chat_complete_settings), + ), + # Patch the sync, streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.chat"), + "Chat.stream", + mistral_stream_wrapper(chat_stream_settings), + ), + # Patch the async, non-streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.chat"), + "Chat.complete_async", + mistral_wrapper(async_chat_complete_settings), + ), + # Patch the async, streaming chat method + SymbolPatcher( + lambda: importlib.import_module("mistralai.chat"), + "Chat.stream_async", + mistral_stream_wrapper(async_chat_stream_settings), + ), + ] + ) + + return _mistral_patcher diff --git a/weave/integrations/notdiamond/__init__.py b/weave/integrations/notdiamond/__init__.py index d99c31c4176d..8cb72ef2a55e 100644 --- a/weave/integrations/notdiamond/__init__.py +++ b/weave/integrations/notdiamond/__init__.py @@ -1 +1 @@ -from .tracing import notdiamond_patcher as notdiamond_patcher +from .tracing import get_notdiamond_patcher # noqa: F401 diff --git a/weave/integrations/notdiamond/tracing.py b/weave/integrations/notdiamond/tracing.py index 90c08b9e8c62..23589719be78 100644 --- a/weave/integrations/notdiamond/tracing.py +++ b/weave/integrations/notdiamond/tracing.py @@ -1,19 +1,32 @@ +from __future__ import annotations + import importlib from typing import Callable import weave -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.autopatch import IntegrationSettings, OpSettings +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher + +_notdiamond_patcher: MultiPatcher | None = None -def nd_wrapper(name: str) -> Callable[[Callable], Callable]: +def nd_wrapper(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op()(fn) - op.name = name # type: ignore + op_kwargs = settings.model_dump() + op = weave.op(fn, **op_kwargs) return op return wrapper +def passthrough_wrapper(settings: OpSettings) -> Callable: + def wrapper(fn: Callable) -> Callable: + op_kwargs = settings.model_dump() + return weave.op(fn, **op_kwargs) + + return wrapper + + def _patch_client_op(method_name: str) -> list[SymbolPatcher]: return [ SymbolPatcher( @@ -29,36 +42,84 @@ def _patch_client_op(method_name: str) -> list[SymbolPatcher]: ] -patched_client_functions = _patch_client_op("model_select") - -patched_llmconfig_functions = [ - SymbolPatcher( - lambda: importlib.import_module("notdiamond"), - "LLMConfig.__init__", - weave.op(), - ), - SymbolPatcher( - lambda: importlib.import_module("notdiamond"), - "LLMConfig.from_string", - weave.op(), - ), -] - -patched_toolkit_functions = [ - SymbolPatcher( - lambda: importlib.import_module("notdiamond.toolkit.custom_router"), - "CustomRouter.fit", - weave.op(), - ), - SymbolPatcher( - lambda: importlib.import_module("notdiamond.toolkit.custom_router"), - "CustomRouter.eval", - weave.op(), - ), -] - -all_patched_functions = ( - patched_client_functions + patched_toolkit_functions + patched_llmconfig_functions -) - -notdiamond_patcher = MultiPatcher(all_patched_functions) +def get_notdiamond_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _notdiamond_patcher + if _notdiamond_patcher is not None: + return _notdiamond_patcher + + base = settings.op_settings + + model_select_settings = base.model_copy( + update={"name": base.name or "NotDiamond.model_select"} + ) + async_model_select_settings = base.model_copy( + update={"name": base.name or "NotDiamond.amodel_select"} + ) + patched_client_functions = [ + SymbolPatcher( + lambda: importlib.import_module("notdiamond"), + "NotDiamond.model_select", + passthrough_wrapper(model_select_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("notdiamond"), + "NotDiamond.amodel_select", + passthrough_wrapper(async_model_select_settings), + ), + ] + + llm_config_init_settings = base.model_copy( + update={"name": base.name or "NotDiamond.LLMConfig.__init__"} + ) + llm_config_from_string_settings = base.model_copy( + update={"name": base.name or "NotDiamond.LLMConfig.from_string"} + ) + patched_llmconfig_functions = [ + SymbolPatcher( + lambda: importlib.import_module("notdiamond"), + "LLMConfig.__init__", + passthrough_wrapper(llm_config_init_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("notdiamond"), + "LLMConfig.from_string", + passthrough_wrapper(llm_config_from_string_settings), + ), + ] + + toolkit_custom_router_fit_settings = base.model_copy( + update={"name": base.name or "NotDiamond.toolkit.custom_router.fit"} + ) + toolkit_custom_router_eval_settings = base.model_copy( + update={"name": base.name or "NotDiamond.toolkit.custom_router.eval"} + ) + patched_toolkit_functions = [ + SymbolPatcher( + lambda: importlib.import_module("notdiamond.toolkit.custom_router"), + "CustomRouter.fit", + passthrough_wrapper(toolkit_custom_router_fit_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("notdiamond.toolkit.custom_router"), + "CustomRouter.eval", + passthrough_wrapper(toolkit_custom_router_eval_settings), + ), + ] + + all_patched_functions = ( + patched_client_functions + + patched_toolkit_functions + + patched_llmconfig_functions + ) + + _notdiamond_patcher = MultiPatcher(all_patched_functions) + + return _notdiamond_patcher diff --git a/weave/integrations/vertexai/vertexai_sdk.py b/weave/integrations/vertexai/vertexai_sdk.py index c2f7a9906c78..a64620cbe5fb 100644 --- a/weave/integrations/vertexai/vertexai_sdk.py +++ b/weave/integrations/vertexai/vertexai_sdk.py @@ -1,10 +1,13 @@ +from __future__ import annotations + import importlib from functools import wraps -from typing import TYPE_CHECKING, Any, Callable, Optional +from typing import TYPE_CHECKING, Any, Callable import weave +from weave.trace.autopatch import IntegrationSettings, OpSettings from weave.trace.op_extensions.accumulator import add_accumulator -from weave.trace.patcher import MultiPatcher, SymbolPatcher +from weave.trace.patcher import MultiPatcher, NoOpPatcher, SymbolPatcher from weave.trace.serialize import dictify from weave.trace.weave_client import Call @@ -12,6 +15,9 @@ from vertexai.generative_models import GenerationResponse +_vertexai_patcher: MultiPatcher | None = None + + def vertexai_postprocess_inputs(inputs: dict[str, Any]) -> dict[str, Any]: if "self" in inputs: model_name = ( @@ -25,8 +31,8 @@ def vertexai_postprocess_inputs(inputs: dict[str, Any]) -> dict[str, Any]: def vertexai_accumulator( - acc: Optional["GenerationResponse"], value: "GenerationResponse" -) -> "GenerationResponse": + acc: GenerationResponse | None, value: GenerationResponse +) -> GenerationResponse: from google.cloud.aiplatform_v1beta1.types import content as gapic_content_types from google.cloud.aiplatform_v1beta1.types import ( prediction_service as gapic_prediction_service_types, @@ -62,7 +68,7 @@ def vertexai_accumulator( def vertexai_on_finish( - call: Call, output: Any, exception: Optional[BaseException] + call: Call, output: Any, exception: BaseException | None ) -> None: original_model_name = call.inputs["model_name"] model_name = original_model_name.split("/")[-1] @@ -81,10 +87,13 @@ def vertexai_on_finish( call.summary.update(summary_update) -def vertexai_wrapper_sync(name: str) -> Callable[[Callable], Callable]: +def vertexai_wrapper_sync(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: - op = weave.op(postprocess_inputs=vertexai_postprocess_inputs)(fn) - op.name = name # type: ignore + op_kwargs = settings.model_copy() + if not op_kwargs.get("postprocess_inputs"): + op_kwargs["postprocess_inputs"] = vertexai_postprocess_inputs + + op = weave.op(fn, **op_kwargs) op._set_on_finish_handler(vertexai_on_finish) return add_accumulator( op, # type: ignore @@ -96,7 +105,7 @@ def wrapper(fn: Callable) -> Callable: return wrapper -def vertexai_wrapper_async(name: str) -> Callable[[Callable], Callable]: +def vertexai_wrapper_async(settings: OpSettings) -> Callable[[Callable], Callable]: def wrapper(fn: Callable) -> Callable: def _fn_wrapper(fn: Callable) -> Callable: @wraps(fn) @@ -105,9 +114,11 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return _async_wrapper - "We need to do this so we can check if `stream` is used" - op = weave.op(postprocess_inputs=vertexai_postprocess_inputs)(_fn_wrapper(fn)) - op.name = name # type: ignore + op_kwargs = settings.model_copy() + if not op_kwargs.get("postprocess_inputs"): + op_kwargs["postprocess_inputs"] = vertexai_postprocess_inputs + + op = weave.op(_fn_wrapper(fn), **op_kwargs) op._set_on_finish_handler(vertexai_on_finish) return add_accumulator( op, # type: ignore @@ -119,34 +130,65 @@ async def _async_wrapper(*args: Any, **kwargs: Any) -> Any: return wrapper -vertexai_patcher = MultiPatcher( - [ - SymbolPatcher( - lambda: importlib.import_module("vertexai.generative_models"), - "GenerativeModel.generate_content", - vertexai_wrapper_sync(name="vertexai.GenerativeModel.generate_content"), - ), - SymbolPatcher( - lambda: importlib.import_module("vertexai.generative_models"), - "GenerativeModel.generate_content_async", - vertexai_wrapper_async( - name="vertexai.GenerativeModel.generate_content_async" +def get_vertexai_patcher( + settings: IntegrationSettings | None = None, +) -> MultiPatcher | NoOpPatcher: + if settings is None: + settings = IntegrationSettings() + + if not settings.enabled: + return NoOpPatcher() + + global _vertexai_patcher + if _vertexai_patcher is not None: + return _vertexai_patcher + + base = settings.op_settings + + generate_content_settings = base.model_copy( + update={"name": base.name or "vertexai.GenerativeModel.generate_content"} + ) + generate_content_async_settings = base.model_copy( + update={"name": base.name or "vertexai.GenerativeModel.generate_content_async"} + ) + send_message_settings = base.model_copy( + update={"name": base.name or "vertexai.ChatSession.send_message"} + ) + send_message_async_settings = base.model_copy( + update={"name": base.name or "vertexai.ChatSession.send_message_async"} + ) + generate_images_settings = base.model_copy( + update={"name": base.name or "vertexai.ImageGenerationModel.generate_images"} + ) + + _vertexai_patcher = MultiPatcher( + [ + SymbolPatcher( + lambda: importlib.import_module("vertexai.generative_models"), + "GenerativeModel.generate_content", + vertexai_wrapper_sync(generate_content_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("vertexai.generative_models"), + "GenerativeModel.generate_content_async", + vertexai_wrapper_async(generate_content_async_settings), ), - ), - SymbolPatcher( - lambda: importlib.import_module("vertexai.generative_models"), - "ChatSession.send_message", - vertexai_wrapper_sync(name="vertexai.ChatSession.send_message"), - ), - SymbolPatcher( - lambda: importlib.import_module("vertexai.generative_models"), - "ChatSession.send_message_async", - vertexai_wrapper_async(name="vertexai.ChatSession.send_message_async"), - ), - SymbolPatcher( - lambda: importlib.import_module("vertexai.preview.vision_models"), - "ImageGenerationModel.generate_images", - vertexai_wrapper_sync(name="vertexai.ImageGenerationModel.generate_images"), - ), - ] -) + SymbolPatcher( + lambda: importlib.import_module("vertexai.generative_models"), + "ChatSession.send_message", + vertexai_wrapper_sync(send_message_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("vertexai.generative_models"), + "ChatSession.send_message_async", + vertexai_wrapper_async(send_message_async_settings), + ), + SymbolPatcher( + lambda: importlib.import_module("vertexai.preview.vision_models"), + "ImageGenerationModel.generate_images", + vertexai_wrapper_sync(generate_images_settings), + ), + ] + ) + + return _vertexai_patcher diff --git a/weave/trace/autopatch.py b/weave/trace/autopatch.py index 0619194a2247..c1c47d375127 100644 --- a/weave/trace/autopatch.py +++ b/weave/trace/autopatch.py @@ -34,89 +34,89 @@ class AutopatchSettings(BaseModel): # These will be uncommented as we add support for more integrations. Note that - # anthropic: IntegrationSettings = Field(default_factory=IntegrationSettings) - # cerebras: IntegrationSettings = Field(default_factory=IntegrationSettings) - # cohere: IntegrationSettings = Field(default_factory=IntegrationSettings) - # dspy: IntegrationSettings = Field(default_factory=IntegrationSettings) - # google_ai_studio: IntegrationSettings = Field(default_factory=IntegrationSettings) - # groq: IntegrationSettings = Field(default_factory=IntegrationSettings) - # instructor: IntegrationSettings = Field(default_factory=IntegrationSettings) - # langchain: IntegrationSettings = Field(default_factory=IntegrationSettings) - # litellm: IntegrationSettings = Field(default_factory=IntegrationSettings) - # llamaindex: IntegrationSettings = Field(default_factory=IntegrationSettings) - # mistral: IntegrationSettings = Field(default_factory=IntegrationSettings) - # notdiamond: IntegrationSettings = Field(default_factory=IntegrationSettings) + anthropic: IntegrationSettings = Field(default_factory=IntegrationSettings) + cerebras: IntegrationSettings = Field(default_factory=IntegrationSettings) + cohere: IntegrationSettings = Field(default_factory=IntegrationSettings) + dspy: IntegrationSettings = Field(default_factory=IntegrationSettings) + google_ai_studio: IntegrationSettings = Field(default_factory=IntegrationSettings) + groq: IntegrationSettings = Field(default_factory=IntegrationSettings) + instructor: IntegrationSettings = Field(default_factory=IntegrationSettings) + litellm: IntegrationSettings = Field(default_factory=IntegrationSettings) + mistral: IntegrationSettings = Field(default_factory=IntegrationSettings) + notdiamond: IntegrationSettings = Field(default_factory=IntegrationSettings) openai: IntegrationSettings = Field(default_factory=IntegrationSettings) - # vertexai: IntegrationSettings = Field(default_factory=IntegrationSettings) + vertexai: IntegrationSettings = Field(default_factory=IntegrationSettings) @validate_call def autopatch(settings: Optional[AutopatchSettings] = None) -> None: - from weave.integrations.anthropic.anthropic_sdk import anthropic_patcher - from weave.integrations.cerebras.cerebras_sdk import cerebras_patcher - from weave.integrations.cohere.cohere_sdk import cohere_patcher - from weave.integrations.dspy.dspy_sdk import dspy_patcher + from weave.integrations.anthropic.anthropic_sdk import get_anthropic_patcher + from weave.integrations.cerebras.cerebras_sdk import get_cerebras_patcher + from weave.integrations.cohere.cohere_sdk import get_cohere_patcher + from weave.integrations.dspy.dspy_sdk import get_dspy_patcher from weave.integrations.google_ai_studio.google_ai_studio_sdk import ( - google_genai_patcher, + get_google_genai_patcher, ) - from weave.integrations.groq.groq_sdk import groq_patcher - from weave.integrations.instructor.instructor_sdk import instructor_patcher + from weave.integrations.groq.groq_sdk import get_groq_patcher + from weave.integrations.instructor.instructor_sdk import get_instructor_patcher from weave.integrations.langchain.langchain import langchain_patcher - from weave.integrations.litellm.litellm import litellm_patcher + from weave.integrations.litellm.litellm import get_litellm_patcher from weave.integrations.llamaindex.llamaindex import llamaindex_patcher - from weave.integrations.mistral import mistral_patcher - from weave.integrations.notdiamond.tracing import notdiamond_patcher + from weave.integrations.mistral import get_mistral_patcher + from weave.integrations.notdiamond.tracing import get_notdiamond_patcher from weave.integrations.openai.openai_sdk import get_openai_patcher - from weave.integrations.vertexai.vertexai_sdk import vertexai_patcher + from weave.integrations.vertexai.vertexai_sdk import get_vertexai_patcher if settings is None: settings = AutopatchSettings() get_openai_patcher(settings.openai).attempt_patch() - mistral_patcher.attempt_patch() - litellm_patcher.attempt_patch() + get_mistral_patcher(settings.mistral).attempt_patch() + get_litellm_patcher(settings.litellm).attempt_patch() + get_anthropic_patcher(settings.anthropic).attempt_patch() + get_groq_patcher(settings.groq).attempt_patch() + get_instructor_patcher(settings.instructor).attempt_patch() + get_dspy_patcher(settings.dspy).attempt_patch() + get_cerebras_patcher(settings.cerebras).attempt_patch() + get_cohere_patcher(settings.cohere).attempt_patch() + get_google_genai_patcher(settings.google_ai_studio).attempt_patch() + get_notdiamond_patcher(settings.notdiamond).attempt_patch() + get_vertexai_patcher(settings.vertexai).attempt_patch() + llamaindex_patcher.attempt_patch() langchain_patcher.attempt_patch() - anthropic_patcher.attempt_patch() - groq_patcher.attempt_patch() - instructor_patcher.attempt_patch() - dspy_patcher.attempt_patch() - cerebras_patcher.attempt_patch() - cohere_patcher.attempt_patch() - google_genai_patcher.attempt_patch() - notdiamond_patcher.attempt_patch() - vertexai_patcher.attempt_patch() def reset_autopatch() -> None: - from weave.integrations.anthropic.anthropic_sdk import anthropic_patcher - from weave.integrations.cerebras.cerebras_sdk import cerebras_patcher - from weave.integrations.cohere.cohere_sdk import cohere_patcher - from weave.integrations.dspy.dspy_sdk import dspy_patcher + from weave.integrations.anthropic.anthropic_sdk import get_anthropic_patcher + from weave.integrations.cerebras.cerebras_sdk import get_cerebras_patcher + from weave.integrations.cohere.cohere_sdk import get_cohere_patcher + from weave.integrations.dspy.dspy_sdk import get_dspy_patcher from weave.integrations.google_ai_studio.google_ai_studio_sdk import ( - google_genai_patcher, + get_google_genai_patcher, ) - from weave.integrations.groq.groq_sdk import groq_patcher - from weave.integrations.instructor.instructor_sdk import instructor_patcher + from weave.integrations.groq.groq_sdk import get_groq_patcher + from weave.integrations.instructor.instructor_sdk import get_instructor_patcher from weave.integrations.langchain.langchain import langchain_patcher - from weave.integrations.litellm.litellm import litellm_patcher + from weave.integrations.litellm.litellm import get_litellm_patcher from weave.integrations.llamaindex.llamaindex import llamaindex_patcher - from weave.integrations.mistral import mistral_patcher - from weave.integrations.notdiamond.tracing import notdiamond_patcher + from weave.integrations.mistral import get_mistral_patcher + from weave.integrations.notdiamond.tracing import get_notdiamond_patcher from weave.integrations.openai.openai_sdk import get_openai_patcher - from weave.integrations.vertexai.vertexai_sdk import vertexai_patcher + from weave.integrations.vertexai.vertexai_sdk import get_vertexai_patcher get_openai_patcher().undo_patch() - mistral_patcher.undo_patch() - litellm_patcher.undo_patch() + get_mistral_patcher().undo_patch() + get_litellm_patcher().undo_patch() + get_anthropic_patcher().undo_patch() + get_groq_patcher().undo_patch() + get_instructor_patcher().undo_patch() + get_dspy_patcher().undo_patch() + get_cerebras_patcher().undo_patch() + get_cohere_patcher().undo_patch() + get_google_genai_patcher().undo_patch() + get_notdiamond_patcher().undo_patch() + get_vertexai_patcher().undo_patch() + llamaindex_patcher.undo_patch() langchain_patcher.undo_patch() - anthropic_patcher.undo_patch() - groq_patcher.undo_patch() - instructor_patcher.undo_patch() - dspy_patcher.undo_patch() - cerebras_patcher.undo_patch() - cohere_patcher.undo_patch() - google_genai_patcher.undo_patch() - notdiamond_patcher.undo_patch() - vertexai_patcher.undo_patch() From 5fc28f245e6ff655e96439a260256dd9f49e348b Mon Sep 17 00:00:00 2001 From: Josiah Lee Date: Tue, 17 Dec 2024 18:01:00 -0800 Subject: [PATCH 04/35] add better search function to llm dropdown (#3280) --- .../PlaygroundChat/LLMDropdown.tsx | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/LLMDropdown.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/LLMDropdown.tsx index fb0e280484a0..a15437de1b19 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/LLMDropdown.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/LLMDropdown.tsx @@ -20,20 +20,23 @@ export const LLMDropdown: React.FC = ({value, onChange}) => { label: LLM_PROVIDER_LABELS[provider], // filtering to the LLMs that are supported by that provider options: Object.keys(LLM_MAX_TOKENS) - .reduce>( - (acc, llm) => { - if (LLM_MAX_TOKENS[llm as LLMMaxTokensKey].provider === provider) { - acc.push({ - group: provider, - // add provider to the label if the LLM is not already prefixed with it - label: llm.includes(provider) ? llm : provider + '/' + llm, - value: llm, - }); - } - return acc; - }, - [] - ) + .reduce< + Array<{ + provider_label: string; + label: string; + value: string; + }> + >((acc, llm) => { + if (LLM_MAX_TOKENS[llm as LLMMaxTokensKey].provider === provider) { + acc.push({ + provider_label: LLM_PROVIDER_LABELS[provider], + // add provider to the label if the LLM is not already prefixed with it + label: llm.includes(provider) ? llm : provider + '/' + llm, + value: llm, + }); + } + return acc; + }, []) .sort((a, b) => a.label.localeCompare(b.label)), })); @@ -74,6 +77,14 @@ export const LLMDropdown: React.FC = ({value, onChange}) => { options={options} size="medium" isSearchable + filterOption={(option, inputValue) => { + const searchTerm = inputValue.toLowerCase(); + return ( + option.data.provider_label.toLowerCase().includes(searchTerm) || + option.data.label.toLowerCase().includes(searchTerm) || + option.data.value.toLowerCase().includes(searchTerm) + ); + }} /> ); From 6a093a4f2d8088e0d5e02c6ca2a5688cc017ac0d Mon Sep 17 00:00:00 2001 From: Josiah Lee Date: Tue, 17 Dec 2024 18:01:08 -0800 Subject: [PATCH 05/35] fix(weave): Prevent sending null message in playground (#3278) * Filter null messages, prevent sending null message * clean --- .../PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx | 9 +++++++-- .../PlaygroundChat/PlaygroundChatInput.tsx | 6 +++--- .../PlaygroundChat/useChatCompletionFunctions.tsx | 8 +++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx index b6b6e7c420d3..8fc02fea9b10 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx @@ -41,7 +41,6 @@ export const PlaygroundChat = ({ const {handleRetry, handleSend} = useChatCompletionFunctions( setPlaygroundStates, setIsLoading, - chatText, playgroundStates, entity, project, @@ -168,7 +167,13 @@ export const PlaygroundChat = ({ content: string, toolCallId?: string ) => { - handleSend(role, idx, content, toolCallId); + handleSend( + role, + chatText, + idx, + content, + toolCallId + ); }, setSelectedChoiceIndex: (choiceIndex: number) => setPlaygroundStateField( diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChatInput.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChatInput.tsx index cac631a8fcf8..d1a627fc4833 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChatInput.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChatInput.tsx @@ -10,8 +10,8 @@ type PlaygroundChatInputProps = { chatText: string; setChatText: (text: string) => void; isLoading: boolean; - onSend: (role: PlaygroundMessageRole) => void; - onAdd: (role: PlaygroundMessageRole, text: string) => void; + onSend: (role: PlaygroundMessageRole, chatText: string) => void; + onAdd: (role: PlaygroundMessageRole, chatText: string) => void; settingsTab: number | null; }; @@ -43,7 +43,7 @@ export const PlaygroundChatInput: React.FC = ({ }; const handleSend = (role: PlaygroundMessageRole) => { - onSend(role); + onSend(role, chatText); handleReset(); }; diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx index c73e5d429190..80e4a32d0add 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx @@ -13,7 +13,6 @@ import {clearTraceCall} from './useChatFunctions'; export const useChatCompletionFunctions = ( setPlaygroundStates: (states: PlaygroundState[]) => void, setIsLoading: (isLoading: boolean) => void, - chatText: string, playgroundStates: PlaygroundState[], entity: string, project: string, @@ -59,19 +58,22 @@ export const useChatCompletionFunctions = ( const handleSend = async ( role: PlaygroundMessageRole, + chatText: string, callIndex?: number, content?: string, toolCallId?: string ) => { try { setIsLoading(true); - const newMessage = createMessage(role, content || chatText, toolCallId); + const newMessageContent = content || chatText; + const newMessage = createMessage(role, newMessageContent, toolCallId); const updatedStates = playgroundStates.map((state, index) => { if (callIndex !== undefined && callIndex !== index) { return state; } const updatedState = appendChoiceToMessages(state); - if (updatedState.traceCall?.inputs?.messages) { + // If the new message is not empty, add it to the messages + if (newMessageContent && updatedState.traceCall?.inputs?.messages) { updatedState.traceCall.inputs.messages.push(newMessage); } return updatedState; From df066280696c1a0c01d56d3994be687ca8a6f770 Mon Sep 17 00:00:00 2001 From: Justin Tulk Date: Wed, 18 Dec 2024 09:27:55 -0800 Subject: [PATCH 06/35] chore(app): Fixing string wrapping bugs inside modified dropdown (#3273) --- .../elements/ModifiedDropdown.test.tsx | 46 +++++++++++++++++++ .../components/elements/ModifiedDropdown.tsx | 40 +++++++++++----- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/weave-js/src/common/components/elements/ModifiedDropdown.test.tsx b/weave-js/src/common/components/elements/ModifiedDropdown.test.tsx index 3557537cbe8a..89c0b2c5948f 100644 --- a/weave-js/src/common/components/elements/ModifiedDropdown.test.tsx +++ b/weave-js/src/common/components/elements/ModifiedDropdown.test.tsx @@ -52,6 +52,18 @@ describe('testing simple search', () => { value: '_step', key: '_step', }, + { + icon: 'wbic-ic-up-arrow', + text: 'Stepperoni', + value: '_stepperoni', + key: '_stepperoni', + }, + { + icon: 'wbic-ic-up-arrow', + text: '99', + value: 99, + key: '_99', + }, { icon: 'calendar', text: 'Relative Time (Wall)', @@ -137,6 +149,40 @@ describe('testing simple search', () => { expect(results.every(r => (r.value as string).includes('loss'))).toBe(true); }); + it('simpleSearch matches case-insensitive regex strings', () => { + const results = simpleSearch(options, 'LOSS', { + allowRegexSearch: true, + }); + expect(results.every(r => (r.value as string).includes('loss'))).toBe(true); + }); + + it('simpleSearch matches case-insensitive regex strings', () => { + const results = simpleSearch(options, 'tep$', { + allowRegexSearch: true, + }); + expect(results.length).toBe(1); + expect(results.every(r => (r.value as string).includes('_step'))).toBe( + true + ); + }); + + it('simpleSearch matches options with number values', () => { + const results = simpleSearch(options, '99$', { + allowRegexSearch: true, + }); + expect(results.length).toBe(1); + results.forEach(r => { + expect(r.value).toEqual(99); + }); + }); + + it('simpleSearch matches all results on * regex string', () => { + const results = simpleSearch(options, '*', { + allowRegexSearch: true, + }); + expect(results.length).toBe(options.length); + }); + it('simpleSearch can disallow matching regex patterns', () => { const results = simpleSearch(options, '.*s.*s.*'); expect(results.length).toBe(0); diff --git a/weave-js/src/common/components/elements/ModifiedDropdown.tsx b/weave-js/src/common/components/elements/ModifiedDropdown.tsx index 301abe035f75..02b69a98644c 100644 --- a/weave-js/src/common/components/elements/ModifiedDropdown.tsx +++ b/weave-js/src/common/components/elements/ModifiedDropdown.tsx @@ -45,9 +45,23 @@ type LabelCoord = { const ITEM_LIMIT_VALUE = '__item_limit'; +/** + * The functionality here is similar to `searchRegexFromQuery` in `panelbank.ts` + */ export function getAsValidRegex(s: string): RegExp | null { + let cleanS = s.trim(); + + // if the query is a single '*', match everything (even though * isn't technically a valid regex) + if (cleanS === '*') { + cleanS = '.*'; + } + + if (cleanS.length === 0) { + return null; + } + try { - return new RegExp(s); + return new RegExp(cleanS, 'i'); } catch (e) { return null; } @@ -64,14 +78,18 @@ export const simpleSearch = ( return _.chain(options) .filter(o => { - const text = JSON.stringify(o.text).toLowerCase(); - return regex ? regex.test(text) : _.includes(text, query.toLowerCase()); + const t = typeof o.text === 'string' ? o.text : JSON.stringify(o.text); + + return regex + ? regex.test(t) + : _.includes(t.toLowerCase(), query.toLowerCase()); }) .sortBy(o => { - const valJSON = typeof o.text === 'string' ? `"${query}"` : query; - return JSON.stringify(o.text).toLowerCase() === valJSON.toLowerCase() - ? 0 - : 1; + const oString = + typeof o.text === 'string' ? o.text : JSON.stringify(o.text); + const qString = typeof query === 'string' ? query : JSON.stringify(query); + + return oString.toLowerCase() === qString.toLowerCase() ? 0 : 1; }) .value(); }; @@ -148,10 +166,10 @@ const ModifiedDropdown: FC = React.memo( _.concat(currentOptions, search(propsOptions, query) as Option[]) ); } else { - const updatedOptions = currentOptions.concat( - simpleSearch(propsOptions, query, {allowRegexSearch}) as Option[] - ); - setOptions(updatedOptions); + const matchedOptions = simpleSearch(propsOptions, query, { + allowRegexSearch, + }) as Option[]; + setOptions([...currentOptions, ...matchedOptions]); } }, debounceTime || 400), [allowRegexSearch, debounceTime, multiple, propsOptions, search, value] From c9a5c09b2338106cc24c32544a08fbbfb15a9062 Mon Sep 17 00:00:00 2001 From: Josiah Lee Date: Wed, 18 Dec 2024 09:31:40 -0800 Subject: [PATCH 07/35] Add o1-12-17 to backend (#3283) --- weave/trace_server/costs/cost_checkpoint.json | 618 ++++++++++ .../model_providers/model_providers.json | 1067 ++++++++++++++++- .../model_providers/model_providers.py | 2 +- 3 files changed, 1685 insertions(+), 2 deletions(-) diff --git a/weave/trace_server/costs/cost_checkpoint.json b/weave/trace_server/costs/cost_checkpoint.json index d5aea5aeebad..9667822f4cfa 100644 --- a/weave/trace_server/costs/cost_checkpoint.json +++ b/weave/trace_server/costs/cost_checkpoint.json @@ -13,6 +13,12 @@ "input": 5e-06, "output": 1.5e-05, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "openai", + "input": 2.5e-06, + "output": 1e-05, + "created_at": "2024-12-18 09:00:21" } ], "gpt-4o-mini": [ @@ -1411,6 +1417,12 @@ "input": 7.8125e-08, "output": 3.125e-07, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 1.25e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" } ], "gemini-1.5-pro-002": [ @@ -1425,6 +1437,12 @@ "input": 7.8125e-08, "output": 3.125e-07, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 1.25e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" } ], "gemini-1.5-pro-001": [ @@ -1439,6 +1457,12 @@ "input": 7.8125e-08, "output": 3.125e-07, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 1.25e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" } ], "gemini-1.5-pro-preview-0514": [ @@ -1495,6 +1519,12 @@ "input": 4.688e-09, "output": 4.6875e-09, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 7.5e-08, + "output": 3e-07, + "created_at": "2024-12-18 09:00:21" } ], "gemini-1.5-flash-exp-0827": [ @@ -1523,6 +1553,12 @@ "input": 4.688e-09, "output": 4.6875e-09, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 7.5e-08, + "output": 3e-07, + "created_at": "2024-12-18 09:00:21" } ], "gemini-1.5-flash-001": [ @@ -1537,6 +1573,12 @@ "input": 4.688e-09, "output": 4.6875e-09, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 7.5e-08, + "output": 3e-07, + "created_at": "2024-12-18 09:00:21" } ], "gemini-1.5-flash-preview-0514": [ @@ -1551,6 +1593,12 @@ "input": 4.688e-09, "output": 4.6875e-09, "created_at": "2024-11-01 09:09:13" + }, + { + "provider": "vertex_ai-language-models", + "input": 7.5e-08, + "output": 4.6875e-09, + "created_at": "2024-12-18 09:00:21" } ], "gemini-pro-experimental": [ @@ -1751,6 +1799,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "text-multilingual-embedding-002": [ @@ -1759,6 +1813,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "textembedding-gecko": [ @@ -1767,6 +1827,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "textembedding-gecko-multilingual": [ @@ -1775,6 +1841,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "textembedding-gecko-multilingual@001": [ @@ -1783,6 +1855,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "textembedding-gecko@001": [ @@ -1791,6 +1869,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "textembedding-gecko@003": [ @@ -1799,6 +1883,12 @@ "input": 6.25e-09, "output": 0.0, "created_at": "2024-10-08 08:45:39" + }, + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" } ], "text-embedding-preview-0409": [ @@ -4656,5 +4746,533 @@ "output": 0.0, "created_at": "2024-11-01 09:09:13" } + ], + "gpt-4o-mini-audio-preview-2024-12-17": [ + { + "provider": "openai", + "input": 1.5e-07, + "output": 6e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "o1": [ + { + "provider": "openai", + "input": 1.5e-05, + "output": 6e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "o1-2024-12-17": [ + { + "provider": "openai", + "input": 1.5e-05, + "output": 6e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "gpt-4o-2024-11-20": [ + { + "provider": "openai", + "input": 2.5e-06, + "output": 1e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "gpt-4o-realtime-preview-2024-10-01": [ + { + "provider": "openai", + "input": 5e-06, + "output": 2e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "gpt-4o-realtime-preview": [ + { + "provider": "openai", + "input": 5e-06, + "output": 2e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "gpt-4o-realtime-preview-2024-12-17": [ + { + "provider": "openai", + "input": 5e-06, + "output": 2e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "gpt-4o-mini-realtime-preview": [ + { + "provider": "openai", + "input": 6e-07, + "output": 2.4e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "gpt-4o-mini-realtime-preview-2024-12-17": [ + { + "provider": "openai", + "input": 6e-07, + "output": 2.4e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "ft:gpt-4o-2024-11-20": [ + { + "provider": "openai", + "input": 3.75e-06, + "output": 1.5e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure/gpt-4o-2024-11-20": [ + { + "provider": "azure", + "input": 2.75e-06, + "output": 1.1e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure/global-standard/gpt-4o-2024-11-20": [ + { + "provider": "azure", + "input": 2.5e-06, + "output": 1e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/mistral-large-2407": [ + { + "provider": "azure_ai", + "input": 2e-06, + "output": 6e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/ministral-3b": [ + { + "provider": "azure_ai", + "input": 4e-08, + "output": 4e-08, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Llama-3.2-11B-Vision-Instruct": [ + { + "provider": "azure_ai", + "input": 3.7e-07, + "output": 3.7e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Llama-3.3-70B-Instruct": [ + { + "provider": "azure_ai", + "input": 7.1e-07, + "output": 7.1e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Llama-3.2-90B-Vision-Instruct": [ + { + "provider": "azure_ai", + "input": 2.04e-06, + "output": 2.04e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3.5-mini-instruct": [ + { + "provider": "azure_ai", + "input": 1.3e-07, + "output": 5.2e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3.5-vision-instruct": [ + { + "provider": "azure_ai", + "input": 1.3e-07, + "output": 5.2e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3.5-MoE-instruct": [ + { + "provider": "azure_ai", + "input": 1.6e-07, + "output": 6.4e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3-mini-4k-instruct": [ + { + "provider": "azure_ai", + "input": 1.3e-07, + "output": 5.2e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3-mini-128k-instruct": [ + { + "provider": "azure_ai", + "input": 1.3e-07, + "output": 5.2e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3-small-8k-instruct": [ + { + "provider": "azure_ai", + "input": 1.5e-07, + "output": 6e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3-small-128k-instruct": [ + { + "provider": "azure_ai", + "input": 1.5e-07, + "output": 6e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3-medium-4k-instruct": [ + { + "provider": "azure_ai", + "input": 1.7e-07, + "output": 6.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "azure_ai/Phi-3-medium-128k-instruct": [ + { + "provider": "azure_ai", + "input": 1.7e-07, + "output": 6.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.3-70b-versatile": [ + { + "provider": "groq", + "input": 5.9e-07, + "output": 7.9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.3-70b-specdec": [ + { + "provider": "groq", + "input": 5.9e-07, + "output": 9.9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.2-1b-preview": [ + { + "provider": "groq", + "input": 4e-08, + "output": 4e-08, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.2-3b-preview": [ + { + "provider": "groq", + "input": 6e-08, + "output": 6e-08, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.2-11b-text-preview": [ + { + "provider": "groq", + "input": 1.8e-07, + "output": 1.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.2-11b-vision-preview": [ + { + "provider": "groq", + "input": 1.8e-07, + "output": 1.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.2-90b-text-preview": [ + { + "provider": "groq", + "input": 9e-07, + "output": 9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "groq/llama-3.2-90b-vision-preview": [ + { + "provider": "groq", + "input": 9e-07, + "output": 9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "claude-3-5-haiku-20241022": [ + { + "provider": "anthropic", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "gemini-2.0-flash-exp": [ + { + "provider": "vertex_ai-language-models", + "input": 0.0, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-sonnet": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 3e-06, + "output": 1.5e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-5-sonnet": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 3e-06, + "output": 1.5e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-5-sonnet-v2": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 3e-06, + "output": 1.5e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-haiku": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 2.5e-07, + "output": 1.25e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-5-haiku": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-5-haiku@20241022": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "vertex_ai/claude-3-opus": [ + { + "provider": "vertex_ai-anthropic_models", + "input": 1.5e-05, + "output": 7.5e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "text-embedding-005": [ + { + "provider": "vertex_ai-embedding-models", + "input": 1e-07, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" + } + ], + "gemini/gemini-1.5-flash-8b": [ + { + "provider": "gemini", + "input": 0.0, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" + } + ], + "gemini/gemini-exp-1114": [ + { + "provider": "gemini", + "input": 0.0, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" + } + ], + "gemini/gemini-exp-1206": [ + { + "provider": "gemini", + "input": 0.0, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" + } + ], + "rerank-v3.5": [ + { + "provider": "cohere", + "input": 0.0, + "output": 0.0, + "created_at": "2024-12-18 09:00:21" + } + ], + "openrouter/anthropic/claude-3-5-haiku": [ + { + "provider": "openrouter", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "openrouter/anthropic/claude-3-5-haiku-20241022": [ + { + "provider": "openrouter", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "openrouter/qwen/qwen-2.5-coder-32b-instruct": [ + { + "provider": "openrouter", + "input": 1.8e-07, + "output": 1.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "amazon.nova-micro-v1:0": [ + { + "provider": "bedrock_converse", + "input": 3.5e-08, + "output": 1.4e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "amazon.nova-lite-v1:0": [ + { + "provider": "bedrock_converse", + "input": 6e-08, + "output": 2.4e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "amazon.nova-pro-v1:0": [ + { + "provider": "bedrock_converse", + "input": 8e-07, + "output": 3.2e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "anthropic.claude-3-5-haiku-20241022-v1:0": [ + { + "provider": "bedrock", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "us.anthropic.claude-3-5-haiku-20241022-v1:0": [ + { + "provider": "bedrock", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "eu.anthropic.claude-3-5-haiku-20241022-v1:0": [ + { + "provider": "bedrock", + "input": 1e-06, + "output": 5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "us.meta.llama3-1-8b-instruct-v1:0": [ + { + "provider": "bedrock", + "input": 2.2e-07, + "output": 2.2e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "us.meta.llama3-1-70b-instruct-v1:0": [ + { + "provider": "bedrock", + "input": 9.9e-07, + "output": 9.9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "us.meta.llama3-1-405b-instruct-v1:0": [ + { + "provider": "bedrock", + "input": 5.32e-06, + "output": 1.6e-05, + "created_at": "2024-12-18 09:00:21" + } + ], + "together_ai/meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo": [ + { + "provider": "together_ai", + "input": 1.8e-07, + "output": 1.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "together_ai/meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo": [ + { + "provider": "together_ai", + "input": 8.8e-07, + "output": 8.8e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "together_ai/meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo": [ + { + "provider": "together_ai", + "input": 3.5e-06, + "output": 3.5e-06, + "created_at": "2024-12-18 09:00:21" + } + ], + "deepinfra/meta-llama/Meta-Llama-3.1-405B-Instruct": [ + { + "provider": "deepinfra", + "input": 9e-07, + "output": 9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct": [ + { + "provider": "fireworks_ai", + "input": 9e-07, + "output": 9e-07, + "created_at": "2024-12-18 09:00:21" + } + ], + "databricks/meta-llama-3.3-70b-instruct": [ + { + "provider": "databricks", + "input": 1.00002e-06, + "output": 2.99999e-06, + "created_at": "2024-12-18 09:00:21" + } ] } \ No newline at end of file diff --git a/weave/trace_server/model_providers/model_providers.json b/weave/trace_server/model_providers/model_providers.json index c373c87f2d6f..e49c740ca187 100644 --- a/weave/trace_server/model_providers/model_providers.json +++ b/weave/trace_server/model_providers/model_providers.json @@ -1 +1,1066 @@ -{"gpt-4": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-audio-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-audio-preview-2024-10-01": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-mini": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-mini-2024-07-18": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "o1-mini": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "o1-mini-2024-09-12": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "o1-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "o1-preview-2024-09-12": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "chatgpt-4o-latest": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-2024-05-13": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-2024-08-06": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4o-2024-11-20": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-turbo-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-0314": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-0613": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-32k": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-32k-0314": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-32k-0613": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-turbo": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-turbo-2024-04-09": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-1106-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-0125-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-vision-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-4-1106-vision-preview": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo-0301": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo-0613": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo-1106": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo-0125": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo-16k": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "gpt-3.5-turbo-16k-0613": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-3.5-turbo": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-3.5-turbo-0125": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-3.5-turbo-1106": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-3.5-turbo-0613": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-4-0613": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-4o-2024-08-06": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-4o-2024-11-20": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "ft:gpt-4o-mini-2024-07-18": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-embedding-3-large": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-embedding-3-small": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-embedding-ada-002": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-embedding-ada-002-v2": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-moderation-stable": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-moderation-007": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "text-moderation-latest": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "256-x-256/dall-e-2": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "512-x-512/dall-e-2": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "1024-x-1024/dall-e-2": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "hd/1024-x-1792/dall-e-3": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "hd/1792-x-1024/dall-e-3": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "hd/1024-x-1024/dall-e-3": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "standard/1024-x-1792/dall-e-3": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "standard/1792-x-1024/dall-e-3": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "standard/1024-x-1024/dall-e-3": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "whisper-1": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "tts-1": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "tts-1-hd": {"litellm_provider": "openai", "api_key_name": "OPENAI_API_KEY"}, "claude-instant-1": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "xai/grok-beta": {"litellm_provider": "xai", "api_key_name": "XAI_API_KEY"}, "groq/llama-3.3-70b-versatile": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.3-70b-specdec": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama2-70b-4096": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama3-8b-8192": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.2-1b-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.2-3b-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.2-11b-text-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.2-11b-vision-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.2-90b-text-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.2-90b-vision-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama3-70b-8192": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.1-8b-instant": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.1-70b-versatile": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama-3.1-405b-reasoning": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/mixtral-8x7b-32768": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/gemma-7b-it": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/gemma2-9b-it": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama3-groq-70b-8192-tool-use-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "groq/llama3-groq-8b-8192-tool-use-preview": {"litellm_provider": "groq", "api_key_name": "GEMMA_API_KEY"}, "claude-instant-1.2": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-2": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-2.1": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-3-haiku-20240307": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-3-5-haiku-20241022": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-3-opus-20240229": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-3-sonnet-20240229": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-3-5-sonnet-20240620": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "claude-3-5-sonnet-20241022": {"litellm_provider": "anthropic", "api_key_name": "ANTHROPIC_API_KEY"}, "gemini/gemini-1.5-flash-002": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash-001": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash-latest": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash-8b": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash-8b-exp-0924": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-exp-1114": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-exp-1206": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash-exp-0827": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-flash-8b-exp-0827": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-pro": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-pro": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-pro-002": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-pro-001": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-pro-exp-0801": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-pro-exp-0827": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-1.5-pro-latest": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-pro-vision": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-gemma-2-27b-it": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "gemini/gemini-gemma-2-9b-it": {"litellm_provider": "gemini", "api_key_name": "GOOGLE_API_KEY"}, "ai21.j2-mid-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "ai21.j2-ultra-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "ai21.jamba-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.titan-text-lite-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.titan-text-express-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.titan-text-premier-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.titan-embed-text-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.titan-embed-text-v2:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.titan-embed-image-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "mistral.mistral-7b-instruct-v0:2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "mistral.mixtral-8x7b-instruct-v0:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "mistral.mistral-large-2402-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "mistral.mistral-large-2407-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "mistral.mistral-small-2402-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/mistral.mixtral-8x7b-instruct-v0:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/mistral.mixtral-8x7b-instruct-v0:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-3/mistral.mixtral-8x7b-instruct-v0:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/mistral.mistral-7b-instruct-v0:2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/mistral.mistral-7b-instruct-v0:2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-3/mistral.mistral-7b-instruct-v0:2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/mistral.mistral-large-2402-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/mistral.mistral-large-2402-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-3/mistral.mistral-large-2402-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "amazon.nova-micro-v1:0": {"litellm_provider": "bedrock_converse", "api_key_name": "BEDROCK_API_KEY"}, "amazon.nova-lite-v1:0": {"litellm_provider": "bedrock_converse", "api_key_name": "BEDROCK_API_KEY"}, "amazon.nova-pro-v1:0": {"litellm_provider": "bedrock_converse", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-3-sonnet-20240229-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-3-5-sonnet-20240620-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-3-5-sonnet-20241022-v2:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-3-haiku-20240307-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-3-5-haiku-20241022-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-3-opus-20240229-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.anthropic.claude-3-sonnet-20240229-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.anthropic.claude-3-5-sonnet-20240620-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.anthropic.claude-3-5-sonnet-20241022-v2:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.anthropic.claude-3-haiku-20240307-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.anthropic.claude-3-5-haiku-20241022-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.anthropic.claude-3-opus-20240229-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.anthropic.claude-3-sonnet-20240229-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.anthropic.claude-3-5-sonnet-20240620-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.anthropic.claude-3-5-sonnet-20241022-v2:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.anthropic.claude-3-haiku-20240307-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.anthropic.claude-3-5-haiku-20241022-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.anthropic.claude-3-opus-20240229-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/1-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/6-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/1-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/6-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/1-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/6-month-commitment/anthropic.claude-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/1-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/6-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/1-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/6-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/1-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/6-month-commitment/anthropic.claude-v2": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/1-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/6-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/1-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/6-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/1-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/6-month-commitment/anthropic.claude-v2:1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/1-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/6-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/1-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/6-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-2/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/1-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-central-1/6-month-commitment/anthropic.claude-instant-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "cohere.command-text-v14": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/*/1-month-commitment/cohere.command-text-v14": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/*/6-month-commitment/cohere.command-text-v14": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "cohere.command-light-text-v14": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/*/1-month-commitment/cohere.command-light-text-v14": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/*/6-month-commitment/cohere.command-light-text-v14": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "cohere.command-r-plus-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "cohere.command-r-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "cohere.embed-english-v3": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "cohere.embed-multilingual-v3": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama2-13b-chat-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama2-70b-chat-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-1/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-south-1/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ca-central-1/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-1/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-2/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/sa-east-1/meta.llama3-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-east-1/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/us-west-1/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ap-south-1/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/ca-central-1/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-1/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/eu-west-2/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "bedrock/sa-east-1/meta.llama3-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-1-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-1-8b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-1-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-1-70b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-1-405b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-1-405b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-2-1b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-2-1b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.meta.llama3-2-1b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-2-3b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-2-3b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "eu.meta.llama3-2-3b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-2-11b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-2-11b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "meta.llama3-2-90b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "us.meta.llama3-2-90b-instruct-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "512-x-512/50-steps/stability.stable-diffusion-xl-v0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "512-x-512/max-steps/stability.stable-diffusion-xl-v0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "max-x-max/50-steps/stability.stable-diffusion-xl-v0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "max-x-max/max-steps/stability.stable-diffusion-xl-v0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "1024-x-1024/50-steps/stability.stable-diffusion-xl-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "1024-x-1024/max-steps/stability.stable-diffusion-xl-v1": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "stability.sd3-large-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}, "stability.stable-image-ultra-v1:0": {"litellm_provider": "bedrock", "api_key_name": "BEDROCK_API_KEY"}} \ No newline at end of file +{ + "gpt-4": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-audio-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-audio-preview-2024-10-01": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-mini-audio-preview-2024-12-17": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-mini": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-mini-2024-07-18": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "o1": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "o1-mini": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "o1-mini-2024-09-12": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "o1-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "o1-preview-2024-09-12": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "o1-2024-12-17": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "chatgpt-4o-latest": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-2024-05-13": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-2024-08-06": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-2024-11-20": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-realtime-preview-2024-10-01": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-realtime-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-realtime-preview-2024-12-17": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-mini-realtime-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4o-mini-realtime-preview-2024-12-17": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-turbo-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-0314": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-0613": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-32k": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-32k-0314": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-32k-0613": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-turbo": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-turbo-2024-04-09": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-1106-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-0125-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-vision-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-4-1106-vision-preview": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo-0301": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo-0613": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo-1106": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo-0125": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo-16k": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "gpt-3.5-turbo-16k-0613": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-3.5-turbo": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-3.5-turbo-0125": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-3.5-turbo-1106": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-3.5-turbo-0613": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-4-0613": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-4o-2024-08-06": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-4o-2024-11-20": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "ft:gpt-4o-mini-2024-07-18": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-embedding-3-large": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-embedding-3-small": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-embedding-ada-002": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-embedding-ada-002-v2": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-moderation-stable": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-moderation-007": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "text-moderation-latest": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "256-x-256/dall-e-2": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "512-x-512/dall-e-2": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "1024-x-1024/dall-e-2": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "hd/1024-x-1792/dall-e-3": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "hd/1792-x-1024/dall-e-3": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "hd/1024-x-1024/dall-e-3": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "standard/1024-x-1792/dall-e-3": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "standard/1792-x-1024/dall-e-3": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "standard/1024-x-1024/dall-e-3": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "whisper-1": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "tts-1": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "tts-1-hd": { + "litellm_provider": "openai", + "api_key_name": "OPENAI_API_KEY" + }, + "claude-instant-1": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "xai/grok-beta": { + "litellm_provider": "xai", + "api_key_name": "XAI_API_KEY" + }, + "groq/llama-3.3-70b-versatile": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.3-70b-specdec": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama2-70b-4096": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama3-8b-8192": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.2-1b-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.2-3b-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.2-11b-text-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.2-11b-vision-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.2-90b-text-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.2-90b-vision-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama3-70b-8192": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.1-8b-instant": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.1-70b-versatile": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama-3.1-405b-reasoning": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/mixtral-8x7b-32768": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/gemma-7b-it": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/gemma2-9b-it": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama3-groq-70b-8192-tool-use-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "groq/llama3-groq-8b-8192-tool-use-preview": { + "litellm_provider": "groq", + "api_key_name": "GEMMA_API_KEY" + }, + "claude-instant-1.2": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-2": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-2.1": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-3-haiku-20240307": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-3-5-haiku-20241022": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-3-opus-20240229": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-3-sonnet-20240229": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-3-5-sonnet-20240620": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "claude-3-5-sonnet-20241022": { + "litellm_provider": "anthropic", + "api_key_name": "ANTHROPIC_API_KEY" + }, + "gemini/gemini-1.5-flash-002": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash-001": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash-latest": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash-8b": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash-8b-exp-0924": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-exp-1114": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-exp-1206": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash-exp-0827": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-flash-8b-exp-0827": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-pro": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-pro": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-pro-002": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-pro-001": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-pro-exp-0801": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-pro-exp-0827": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-1.5-pro-latest": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-pro-vision": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-gemma-2-27b-it": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "gemini/gemini-gemma-2-9b-it": { + "litellm_provider": "gemini", + "api_key_name": "GOOGLE_API_KEY" + }, + "ai21.j2-mid-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "ai21.j2-ultra-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "ai21.jamba-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.titan-text-lite-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.titan-text-express-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.titan-text-premier-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.titan-embed-text-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.titan-embed-text-v2:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.titan-embed-image-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "mistral.mistral-7b-instruct-v0:2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "mistral.mixtral-8x7b-instruct-v0:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "mistral.mistral-large-2402-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "mistral.mistral-large-2407-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "mistral.mistral-small-2402-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/mistral.mixtral-8x7b-instruct-v0:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/mistral.mixtral-8x7b-instruct-v0:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-3/mistral.mixtral-8x7b-instruct-v0:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/mistral.mistral-7b-instruct-v0:2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/mistral.mistral-7b-instruct-v0:2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-3/mistral.mistral-7b-instruct-v0:2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/mistral.mistral-large-2402-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/mistral.mistral-large-2402-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-3/mistral.mistral-large-2402-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.nova-micro-v1:0": { + "litellm_provider": "bedrock_converse", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.nova-lite-v1:0": { + "litellm_provider": "bedrock_converse", + "api_key_name": "BEDROCK_API_KEY" + }, + "amazon.nova-pro-v1:0": { + "litellm_provider": "bedrock_converse", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-3-sonnet-20240229-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-3-5-sonnet-20240620-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-3-5-sonnet-20241022-v2:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-3-haiku-20240307-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-3-5-haiku-20241022-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-3-opus-20240229-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.anthropic.claude-3-sonnet-20240229-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.anthropic.claude-3-5-sonnet-20240620-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.anthropic.claude-3-5-sonnet-20241022-v2:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.anthropic.claude-3-haiku-20240307-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.anthropic.claude-3-5-haiku-20241022-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.anthropic.claude-3-opus-20240229-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.anthropic.claude-3-sonnet-20240229-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.anthropic.claude-3-5-sonnet-20240620-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.anthropic.claude-3-5-sonnet-20241022-v2:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.anthropic.claude-3-haiku-20240307-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.anthropic.claude-3-5-haiku-20241022-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.anthropic.claude-3-opus-20240229-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/1-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/6-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/1-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/6-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/1-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/6-month-commitment/anthropic.claude-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/1-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/6-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/1-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/6-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/1-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/6-month-commitment/anthropic.claude-v2": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/1-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/6-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/1-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/6-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/1-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/6-month-commitment/anthropic.claude-v2:1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/1-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/6-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/1-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/6-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-2/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/1-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-northeast-1/6-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/1-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-central-1/6-month-commitment/anthropic.claude-instant-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "cohere.command-text-v14": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/*/1-month-commitment/cohere.command-text-v14": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/*/6-month-commitment/cohere.command-text-v14": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "cohere.command-light-text-v14": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/*/1-month-commitment/cohere.command-light-text-v14": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/*/6-month-commitment/cohere.command-light-text-v14": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "cohere.command-r-plus-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "cohere.command-r-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "cohere.embed-english-v3": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "cohere.embed-multilingual-v3": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama2-13b-chat-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama2-70b-chat-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-1/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-south-1/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ca-central-1/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-1/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-2/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/sa-east-1/meta.llama3-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-east-1/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/us-west-1/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ap-south-1/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/ca-central-1/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-1/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/eu-west-2/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "bedrock/sa-east-1/meta.llama3-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-1-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-1-8b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-1-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-1-70b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-1-405b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-1-405b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-2-1b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-2-1b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.meta.llama3-2-1b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-2-3b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-2-3b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "eu.meta.llama3-2-3b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-2-11b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-2-11b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "meta.llama3-2-90b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "us.meta.llama3-2-90b-instruct-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "512-x-512/50-steps/stability.stable-diffusion-xl-v0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "512-x-512/max-steps/stability.stable-diffusion-xl-v0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "max-x-max/50-steps/stability.stable-diffusion-xl-v0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "max-x-max/max-steps/stability.stable-diffusion-xl-v0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "1024-x-1024/50-steps/stability.stable-diffusion-xl-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "1024-x-1024/max-steps/stability.stable-diffusion-xl-v1": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "stability.sd3-large-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + }, + "stability.stable-image-ultra-v1:0": { + "litellm_provider": "bedrock", + "api_key_name": "BEDROCK_API_KEY" + } +} \ No newline at end of file diff --git a/weave/trace_server/model_providers/model_providers.py b/weave/trace_server/model_providers/model_providers.py index 1b967a890957..773ce34841c2 100644 --- a/weave/trace_server/model_providers/model_providers.py +++ b/weave/trace_server/model_providers/model_providers.py @@ -64,7 +64,7 @@ def main( ) os.makedirs(os.path.dirname(full_path), exist_ok=True) with open(full_path, "w") as f: - json.dump(providers, f) + json.dump(providers, f, indent=2) print( f"Updated model to model provider info file at: {full_path}. {len(providers)} models updated." ) From 5fd95bdd0a6fdba5bcadfb27bdc52daf5a8ee001 Mon Sep 17 00:00:00 2001 From: domphan-wandb Date: Wed, 18 Dec 2024 10:57:04 -0800 Subject: [PATCH 08/35] feat(weave_query): add ops to query weave traces from a query panel (#3269) * feat(weave_query): create api client for trace server * feat(weave_query): Create ops to fetch traces and traces types (#3270) --- weave-js/src/core/model/helpers.ts | 6 +- weave-js/src/core/ops/domain/project.ts | 78 ++++++++++++- weave-js/src/core/ops/traceTypes.ts | 25 +++++ .../weave_query/ops_domain/project_ops.py | 103 ++++++++++++++++++ .../weave_query/wandb_trace_server_api.py | 74 +++++++++++++ 5 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 weave-js/src/core/ops/traceTypes.ts create mode 100644 weave_query/weave_query/wandb_trace_server_api.py diff --git a/weave-js/src/core/model/helpers.ts b/weave-js/src/core/model/helpers.ts index 32b560ad4a6d..e0500d3b365b 100644 --- a/weave-js/src/core/model/helpers.ts +++ b/weave-js/src/core/model/helpers.ts @@ -897,10 +897,14 @@ export function isObjectTypeLike(t: any): t is ObjectType | Union { ); } -export function typedDict(propertyTypes: {[key: string]: Type}): TypedDictType { +export function typedDict( + propertyTypes: {[key: string]: Type}, + notRequiredKeys?: string[] +): TypedDictType { return { type: 'typedDict', propertyTypes, + notRequiredKeys, }; } diff --git a/weave-js/src/core/ops/domain/project.ts b/weave-js/src/core/ops/domain/project.ts index d8bbb1cdf649..ee3d14b655fe 100644 --- a/weave-js/src/core/ops/domain/project.ts +++ b/weave-js/src/core/ops/domain/project.ts @@ -1,7 +1,14 @@ import * as Urls from '../../_external/util/urls'; -import {hash, list} from '../../model'; +import {hash, list, typedDict, union} from '../../model'; import {docType} from '../../util/docs'; import * as OpKinds from '../opKinds'; +import { + traceFilterType, + traceLimitType, + traceOffsetType, + traceQueryType, + traceSortByType, +} from '../traceTypes'; import {connectionToNodes} from './util'; const makeProjectOp = OpKinds.makeTaggingStandardOp; @@ -297,3 +304,72 @@ export const opProjectRunQueues = makeProjectOp({ returnType: inputTypes => list('runQueue'), resolver: ({project}) => project.runQueues, }); + +const projectTracesArgTypes = { + ...projectArgTypes, + payload: union([ + 'none', + typedDict( + { + filter: traceFilterType, + limit: traceLimitType, + offset: traceOffsetType, + sort_by: traceSortByType, + query: traceQueryType, + }, + ['filter', 'limit', 'offset', 'sort_by', 'query'] + ), + ]), +}; + +const projectTracesArgTypesDescription = { + project: projectArgDescription, + payload: 'The payload object to the trace api', + 'payload.filter': `The filter object used when querying traces`, + 'payload.limit': `A number representing the limit for number of trace calls`, + 'payload.offset': `A number representing the offset for the number of trace calls`, + 'payload.sort_by': `An array with a dictionary with keys \`field\`() and \`direction\` ("asc"|"desc")`, + 'payload.query': `A dictionary to query data inspired by mongodb aggregation operators`, +}; + +export const opProjectTracesType = makeProjectOp({ + name: 'project-tracesType', + argTypes: projectTracesArgTypes, + description: `Returns the ${docType('list', { + plural: true, + })} for a ${docType('project')}`, + argDescriptions: projectTracesArgTypesDescription, + returnValueDescription: `The ${docType('list', { + plural: true, + })} for a ${docType('project')}`, + returnType: inputTypes => 'type', + resolver: ({project}) => project.traces, + hidden: true, +}); + +export const opProjectTraces = makeProjectOp({ + name: 'project-traces', + argTypes: projectTracesArgTypes, + description: `Returns the ${docType('list', { + plural: true, + })} of traces for a ${docType('project')}`, + argDescriptions: projectTracesArgTypesDescription, + returnValueDescription: `The ${docType('list', { + plural: true, + })} for a ${docType('project')}`, + returnType: inputTypes => list(typedDict({})), + resolver: ({project}) => project.traces, + hidden: true, + resolveOutputType: async ( + inputTypes, + node, + executableNode, + client, + stack + ) => { + const res = await client.query( + opProjectTracesType(executableNode.fromOp.inputs as any) + ); + return res; + }, +}); diff --git a/weave-js/src/core/ops/traceTypes.ts b/weave-js/src/core/ops/traceTypes.ts new file mode 100644 index 000000000000..9cfa2e756160 --- /dev/null +++ b/weave-js/src/core/ops/traceTypes.ts @@ -0,0 +1,25 @@ +import {dict, list, typedDict, union} from '../model'; + +const traceFilterPropertyTypes = { + trace_roots_only: union(['none', 'boolean']), + op_names: union(['none', list('string')]), + input_refs: union(['none', list('string')]), + output_refs: union(['none', list('string')]), + parent_ids: union(['none', list('string')]), + trace_ids: union(['none', list('string')]), + call_ids: union(['none', list('string')]), + wb_user_ids: union(['none', list('string')]), + wb_run_ids: union(['none', list('string')]), +}; + +export const traceFilterType = union([ + 'none', + typedDict(traceFilterPropertyTypes, Object.keys(traceFilterPropertyTypes)), +]); +export const traceLimitType = union(['none', 'number']); +export const traceOffsetType = union(['none', 'number']); +export const traceSortByType = union([ + 'none', + list(typedDict({field: 'string', direction: 'string'})), +]); +export const traceQueryType = union(['none', dict('any')]); diff --git a/weave_query/weave_query/ops_domain/project_ops.py b/weave_query/weave_query/ops_domain/project_ops.py index 0cfbaf051173..de4272fa8cef 100644 --- a/weave_query/weave_query/ops_domain/project_ops.py +++ b/weave_query/weave_query/ops_domain/project_ops.py @@ -3,6 +3,8 @@ from weave_query import errors from weave_query import weave_types as types +from weave_query import ops_arrow +from weave_query.wandb_trace_server_api import get_wandb_trace_api from weave_query.api import op from weave_query import input_provider from weave_query.gql_op_plugin import wb_gql_op_plugin @@ -259,3 +261,104 @@ def artifacts( for typeEdge in project["artifactTypes_100"]["edges"] for edge in typeEdge["node"]["artifactCollections_100"]["edges"] ] + +def _get_project_traces(project, payload): + project_id = f'{project["entity"]["name"]}/{project["name"]}' + filter = None + limit = None + offset = None + sort_by = None + query = None + if payload is not None: + filter = payload.get("filter") + limit = payload.get("limit") + offset = payload.get("offset") + sort_by = payload.get("sort_by") + query = payload.get("query") + trace_api = get_wandb_trace_api() + return trace_api.query_calls_stream(project_id, filter=filter, limit=limit, offset=offset, sort_by=sort_by, query=query) + +traces_filter_property_types = { + "op_names": types.optional(types.List(types.String())), + "input_refs": types.optional(types.List(types.String())), + "output_refs": types.optional(types.List(types.String())), + "parent_ids": types.optional(types.List(types.String())), + "trace_ids": types.optional(types.List(types.String())), + "call_ids": types.optional(types.List(types.String())), + "trace_roots_only": types.optional(types.Boolean()), + "wb_user_ids": types.optional(types.List(types.String())), + "wb_run_ids": types.optional(types.List(types.String())), +} + +traces_input_types = { + "project": wdt.ProjectType, + "payload": types.optional(types.TypedDict(property_types={ + "filter": types.optional(types.TypedDict(property_types=traces_filter_property_types, not_required_keys=set(traces_filter_property_types.keys()))), + "limit": types.optional(types.Number()), + "offset": types.optional(types.Number()), + "sort_by": types.optional(types.List(types.TypedDict(property_types={"field": types.String(), "direction": types.String()}))), + "query": types.optional(types.Dict()) + }, not_required_keys=set(['filter', 'limit', 'offset', 'sort_by', 'query']))) +} + +traces_output_type = types.TypedDict(property_types={ + "id": types.String(), + "project_id": types.String(), + "op_name": types.String(), + "display_name": types.optional(types.String()), + "trace_id": types.String(), + "parent_id": types.optional(types.String()), + "started_at": types.Timestamp(), + "attributes": types.Dict(types.String(), types.Any()), + "inputs": types.Dict(types.String(), types.Any()), + "ended_at": types.optional(types.Timestamp()), + "exception": types.optional(types.String()), + "output": types.optional(types.Any()), + "summary": types.optional(types.Any()), + "wb_user_id": types.optional(types.String()), + "wb_run_id": types.optional(types.String()), + "deleted_at": types.optional(types.Timestamp()) +}) + +@op( + name="project-tracesType", + input_type=traces_input_types, + output_type=types.TypeType(), + plugins=wb_gql_op_plugin( + lambda inputs, inner: """ + entity { + id + name + } + """ + ), + hidden=True +) +def traces_type(project, payload): + res = _get_project_traces(project, payload) + if res: + return types.TypeRegistry.type_of(res) + else: + return types.TypeRegistry.type_of([]) + +@op( + name="project-traces", + input_type=traces_input_types, + output_type=ops_arrow.ArrowWeaveListType(traces_output_type), + plugins=wb_gql_op_plugin( + lambda inputs, inner: """ + entity { + id + name + } + """ + ), + refine_output_type=traces_type, + hidden=True +) +def traces(project, payload): + res = _get_project_traces(project, payload) + if res: + return ops_arrow.to_arrow(res) + else: + return ops_arrow.to_arrow([]) diff --git a/weave_query/weave_query/wandb_trace_server_api.py b/weave_query/weave_query/wandb_trace_server_api.py new file mode 100644 index 000000000000..4af605a90a42 --- /dev/null +++ b/weave_query/weave_query/wandb_trace_server_api.py @@ -0,0 +1,74 @@ +# This is an experimental client api used to make requests to the +# Weave Trace Server +import typing +import requests +import json +from requests.auth import HTTPBasicAuth + +from weave_query import environment as weave_env +from weave_query import engine_trace, server_error_handling + +from weave_query.context_state import WandbApiContext, _wandb_api_context + +tracer = engine_trace.tracer() # type: ignore + +def _get_wandb_api_context() -> typing.Optional[WandbApiContext]: + return _wandb_api_context.get() + +class WandbTraceApi: + def __init__(self) -> None: + self.session = requests.Session() + + def query_calls_stream( + self, + project_id: str, + filter: typing.Optional[dict] = None, + limit: typing.Optional[int] = None, + offset: typing.Optional[int] = None, + sort_by: typing.Optional[list] = None, + query: typing.Optional[dict] = None, + ) -> typing.Any: + with tracer.trace("query_calls_stream"): + wandb_api_context = _get_wandb_api_context() + headers = {'content-type': 'application/json'} + auth = None + cookies = None + if wandb_api_context is not None: + headers = wandb_api_context.headers + cookies = wandb_api_context.cookies + if wandb_api_context.api_key is not None: + auth = HTTPBasicAuth("api", wandb_api_context.api_key) + if cookies: + headers["authorization"] = "Basic Og==" # base64 encoding of ":" + + url = f"{weave_env.weave_trace_server_url()}/calls/stream_query" + + payload = { + "project_id": project_id, + } + + if filter: + payload["filter"] = filter + if limit: + payload["limit"] = limit + if offset: + payload["offset"] = offset + if sort_by: + payload["sort_by"] = sort_by + if query: + payload["query"] = query + + with self.session.post( + url=url, headers=headers, auth=auth, cookies=cookies, json=payload + ) as r: + results = [] + if r.status_code == 200: + for line in r.iter_lines(): + if line: + results.append(json.loads(line)) + return results + else: + raise server_error_handling.WeaveInternalHttpException.from_code(r.status_code, "Weave Traces query failed") + +def get_wandb_trace_api() -> WandbTraceApi: + return WandbTraceApi() \ No newline at end of file From 36c17aba88f9eff8a1490ce2d9047af78f6899b6 Mon Sep 17 00:00:00 2001 From: Josiah Lee Date: Wed, 18 Dec 2024 12:06:14 -0800 Subject: [PATCH 09/35] feat(weave): run it n times for o1 models (#3286) * run it n times for o1 modles * pr comments --- weave/trace_server/llm_completion.py | 72 ++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/weave/trace_server/llm_completion.py b/weave/trace_server/llm_completion.py index bec4361c856f..e8ac86ffb33a 100644 --- a/weave/trace_server/llm_completion.py +++ b/weave/trace_server/llm_completion.py @@ -32,20 +32,54 @@ def lite_llm_completion( # This allows us to drop params that are not supported by the LLM provider litellm.drop_params = True + + if supports_n_times(inputs.model) or inputs.n == 1: + try: + res = litellm.completion( + **inputs.model_dump(exclude_none=True), + api_key=api_key, + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, + aws_region_name=aws_region_name, + ) + return tsi.CompletionsCreateRes(response=res.model_dump()) + except Exception as e: + error_message = str(e) + error_message = error_message.replace("litellm.", "") + return tsi.CompletionsCreateRes(response={"error": error_message}) + + # o1 models with n > 1 + results = [] try: - res = litellm.completion( - **inputs.model_dump(exclude_none=True), - api_key=api_key, - aws_access_key_id=aws_access_key_id, - aws_secret_access_key=aws_secret_access_key, - aws_region_name=aws_region_name, - ) - return tsi.CompletionsCreateRes(response=res.model_dump()) + # get n results + for i in range(inputs.n or 1): + results.append( + litellm.completion( + **inputs.model_dump(exclude_none=True), + api_key=api_key, + aws_access_key_id=aws_access_key_id, + aws_secret_access_key=aws_secret_access_key, + aws_region_name=aws_region_name, + ) + ) except Exception as e: error_message = str(e) error_message = error_message.replace("litellm.", "") return tsi.CompletionsCreateRes(response={"error": error_message}) + final_result = results[0] + for idx, result in enumerate(results): + if idx != 0: + # append choices + final_result.choices.append(result.choices[0]) + + # sum usage + final_result.usage = sum_dict_leaves( + [result.usage.model_dump() for result in results] + ) + + return tsi.CompletionsCreateRes(response=final_result.model_dump()) + def get_bedrock_credentials( model_name: str, @@ -88,3 +122,25 @@ def get_bedrock_credentials( ) return aws_access_key_id, aws_secret_access_key, aws_region_name + + +NO_N_TIMES_MODEL_NAMES = ("o1-mini", "o1-preview", "o1") + + +# if the model name contains any of these strings, we don't support n > 1 +def supports_n_times(model_name: str) -> bool: + return not any(x in model_name for x in NO_N_TIMES_MODEL_NAMES) + + +# copied from weave/trace/weave_client.py +def sum_dict_leaves(dicts: list[dict]) -> dict: + # dicts is a list of dictionaries, that may or may not + # have nested dictionaries. Sum all the leaves that match + result: dict = {} + for d in dicts: + for k, v in d.items(): + if isinstance(v, dict): + result[k] = sum_dict_leaves([result.get(k, {}), v]) + elif v is not None: + result[k] = result.get(k, 0) + v + return result From efed3f067884906edec2d0b33b4f4a300cb71159 Mon Sep 17 00:00:00 2001 From: Josiah Lee Date: Wed, 18 Dec 2024 12:27:17 -0800 Subject: [PATCH 10/35] add o1 to playground (#3285) --- .../pages/PlaygroundPage/llmMaxTokens.ts | 183 ++++++++++-------- 1 file changed, 98 insertions(+), 85 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/llmMaxTokens.ts b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/llmMaxTokens.ts index 123e8f34af24..a6ee834f5cfb 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/llmMaxTokens.ts +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/llmMaxTokens.ts @@ -7,6 +7,98 @@ export const LLM_MAX_TOKENS = { max_tokens: 16384, supports_function_calling: true, }, + 'gpt-3.5-turbo-0125': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-3.5-turbo-1106': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4-1106-preview': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4-32k-0314': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: false, + }, + 'gpt-4-turbo-2024-04-09': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4-turbo-preview': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4-turbo': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4o-2024-05-13': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4o-2024-08-06': { + provider: 'openai', + max_tokens: 16384, + supports_function_calling: true, + }, + 'gpt-4o-mini-2024-07-18': { + provider: 'openai', + max_tokens: 16384, + supports_function_calling: true, + }, + 'gpt-4o': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'gpt-4o-2024-11-20': { + provider: 'openai', + max_tokens: 4096, + supports_function_calling: true, + }, + 'o1-mini-2024-09-12': { + provider: 'openai', + max_tokens: 65536, + supports_function_calling: true, + }, + 'o1-mini': { + provider: 'openai', + max_tokens: 65536, + supports_function_calling: true, + }, + 'o1-preview-2024-09-12': { + provider: 'openai', + max_tokens: 32768, + supports_function_calling: true, + }, + 'o1-preview': { + provider: 'openai', + max_tokens: 32768, + supports_function_calling: true, + }, + 'o1-2024-12-17': { + provider: 'openai', + max_tokens: 100000, + supports_function_calling: true, + }, + + // Anthropic models 'claude-3-5-sonnet-20240620': { provider: 'anthropic', max_tokens: 8192, @@ -32,6 +124,8 @@ export const LLM_MAX_TOKENS = { max_tokens: 4096, supports_function_calling: true, }, + + // Gemini models 'gemini/gemini-1.5-flash-001': { provider: 'gemini', max_tokens: 8192, @@ -102,71 +196,8 @@ export const LLM_MAX_TOKENS = { max_tokens: 8192, supports_function_calling: true, }, - 'gpt-3.5-turbo-0125': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-3.5-turbo-1106': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4-1106-preview': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4-32k-0314': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: false, - }, - 'gpt-4-turbo-2024-04-09': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4-turbo-preview': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4-turbo': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4o-2024-05-13': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4o-2024-08-06': { - provider: 'openai', - max_tokens: 16384, - supports_function_calling: true, - }, - 'gpt-4o-mini-2024-07-18': { - provider: 'openai', - max_tokens: 16384, - supports_function_calling: true, - }, - 'gpt-4o': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, - 'gpt-4o-2024-11-20': { - provider: 'openai', - max_tokens: 4096, - supports_function_calling: true, - }, + + // Groq models 'groq/gemma-7b-it': { provider: 'groq', max_tokens: 8192, @@ -202,27 +233,8 @@ export const LLM_MAX_TOKENS = { max_tokens: 32768, supports_function_calling: true, }, - 'o1-mini-2024-09-12': { - provider: 'openai', - max_tokens: 65536, - supports_function_calling: true, - }, - 'o1-mini': { - provider: 'openai', - max_tokens: 65536, - supports_function_calling: true, - }, - 'o1-preview-2024-09-12': { - provider: 'openai', - max_tokens: 32768, - supports_function_calling: true, - }, - 'o1-preview': { - provider: 'openai', - max_tokens: 32768, - supports_function_calling: true, - }, + // Bedrock models 'ai21.j2-mid-v1': { provider: 'bedrock', max_tokens: 8191, @@ -369,6 +381,7 @@ export const LLM_MAX_TOKENS = { supports_function_calling: true, }, + // xAI models 'xai/grok-beta': { max_tokens: 131072, provider: 'xai', From a24512a058a0017d3da31757ceb47b255877357f Mon Sep 17 00:00:00 2001 From: Ishita Bindlish Date: Wed, 18 Dec 2024 14:19:02 -0800 Subject: [PATCH 11/35] chore(app): add endIcon prop to Tag (#3281) * add endIcon prop to Tag * lint --- weave-js/src/components/Tag/Tag.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/weave-js/src/components/Tag/Tag.tsx b/weave-js/src/components/Tag/Tag.tsx index 1704585dafe0..85ec9d8a6e2e 100644 --- a/weave-js/src/components/Tag/Tag.tsx +++ b/weave-js/src/components/Tag/Tag.tsx @@ -53,6 +53,7 @@ export type TagProps = { color?: TagColorName; showIcon?: boolean; iconName?: IconName; + endIconName?: IconName; // Wrapping the Tag in Tailwind can be a problem if the Tailwind wrapper is supplied higher up // and there is a need to position the Tag as a direct child for something like flexbox Wrapper?: React.ComponentType | null; @@ -64,6 +65,7 @@ export const Tag: FC = ({ color, showIcon = false, iconName, + endIconName, Wrapper = Tailwind, isInteractive = false, }) => { @@ -79,6 +81,7 @@ export const Tag: FC = ({ {label} + {endIconName && } ); if (Wrapper) { From 8ce826d763eefcafe21a8fa7349de372fabaef5b Mon Sep 17 00:00:00 2001 From: Griffin Tarpenning Date: Wed, 18 Dec 2024 14:56:51 -0800 Subject: [PATCH 12/35] chore(ui): fix spacing for annotation types in feedback grid (#3288) --- .../Browse3/feedback/FeedbackGridInner.tsx | 18 +++++++++++------- .../StructuredFeedback/humanAnnotationTypes.ts | 3 +++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/FeedbackGridInner.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/FeedbackGridInner.tsx index 15a4bad2262b..b8b2f4154c28 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/FeedbackGridInner.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/FeedbackGridInner.tsx @@ -9,6 +9,7 @@ import {Feedback} from '../pages/wfReactInterface/traceServerClientTypes'; import {StyledDataGrid} from '../StyledDataGrid'; import {FeedbackGridActions} from './FeedbackGridActions'; import {FeedbackTypeChip} from './FeedbackTypeChip'; +import {isHumanAnnotationType} from './StructuredFeedback/humanAnnotationTypes'; type FeedbackGridInnerProps = { feedback: Feedback[]; @@ -44,7 +45,10 @@ export const FeedbackGridInner = ({ {params.row.payload.emoji} ); } - if (params.row.feedback_type.startsWith('wandb.annotation.')) { + if (isHumanAnnotationType(params.row.feedback_type)) { + if (typeof params.row.payload.value === 'string') { + return ; + } return ( { - if ( - params.model.feedback_type !== 'wandb.reaction.1' && - params.model.feedback_type !== 'wandb.note.1' - ) { - return 'auto'; + if (isWandbFeedbackType(params.model.feedback_type)) { + return 38; } - return 38; + return 'auto'; }} columns={columns} disableRowSelectionOnClick /> ); }; + +const isWandbFeedbackType = (feedbackType: string) => + feedbackType.startsWith('wandb.'); diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/humanAnnotationTypes.ts b/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/humanAnnotationTypes.ts index 2b675e244dc1..ce28f3113fec 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/humanAnnotationTypes.ts +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/feedback/StructuredFeedback/humanAnnotationTypes.ts @@ -23,3 +23,6 @@ export type HumanAnnotationPayload = { }; export type HumanAnnotation = Feedback & {}; + +export const isHumanAnnotationType = (feedbackType: string) => + feedbackType.startsWith(HUMAN_ANNOTATION_BASE_TYPE); From 7d1d212705e5c6f6eb2da2a5f75eadeeffb23787 Mon Sep 17 00:00:00 2001 From: Josiah Lee Date: Wed, 18 Dec 2024 14:58:40 -0800 Subject: [PATCH 13/35] fix(weave): Unbreak editing and deleting choices (#3287) * unbreak deleting choices * fix bug * fix carousel view breaking when choice is deleted * fix editing * fix reerendering --- .../Home/Browse3/pages/ChatView/ChoiceView.tsx | 2 +- .../Browse3/pages/ChatView/ChoicesDrawer.tsx | 2 +- .../pages/ChatView/ChoicesViewCarousel.tsx | 17 ++++++++++++++--- .../ChatView/PlaygroundMessagePanelButtons.tsx | 7 +------ .../PlaygroundChat/PlaygroundChat.tsx | 2 +- .../useChatCompletionFunctions.tsx | 4 +++- .../pages/PlaygroundPage/PlaygroundPage.tsx | 8 +++----- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoiceView.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoiceView.tsx index e511d6fbf5cd..cca47eae5f86 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoiceView.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoiceView.tsx @@ -21,7 +21,7 @@ export const ChoiceView = ({ const {message} = choice; return (
{choices.map((c, index) => ( -
+
{index === selectedChoiceIndex ? ( diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoicesViewCarousel.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoicesViewCarousel.tsx index b19afb7c3f4f..8befed430096 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoicesViewCarousel.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/ChoicesViewCarousel.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import {Button} from '../../../../../Button'; import {ChoiceView} from './ChoiceView'; @@ -28,11 +28,22 @@ export const ChoicesViewCarousel = ({ setSelectedChoiceIndex(newStep); }; + useEffect(() => { + if (selectedChoiceIndex >= choices.length) { + setSelectedChoiceIndex(choices.length - 1); + } + }, [selectedChoiceIndex, choices, setSelectedChoiceIndex]); + + const choiceIndex = + selectedChoiceIndex >= choices.length + ? choices.length - 1 + : selectedChoiceIndex; + return (
diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/PlaygroundMessagePanelButtons.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/PlaygroundMessagePanelButtons.tsx index 9c286019409d..d4cd3a44c183 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/PlaygroundMessagePanelButtons.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ChatView/PlaygroundMessagePanelButtons.tsx @@ -67,12 +67,7 @@ export const PlaygroundMessagePanelButtons: React.FC< size="small" startIcon="pencil-edit" onClick={() => { - setEditorHeight( - contentRef?.current?.clientHeight - ? // Accounts for padding and save buttons - contentRef.current.clientHeight - 56 - : null - ); + setEditorHeight(contentRef?.current?.clientHeight ?? null); }} tooltip={ !hasContent ? 'We currently do not support editing functions' : 'Edit' diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx index 8fc02fea9b10..c3a30d67adf2 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/PlaygroundChat.tsx @@ -155,7 +155,7 @@ export const PlaygroundChat = ({ deleteMessage(idx, messageIndex, responseIndexes), editMessage: (messageIndex, newMessage) => editMessage(idx, messageIndex, newMessage), - deleteChoice: choiceIndex => + deleteChoice: (messageIndex, choiceIndex) => deleteChoice(idx, choiceIndex), addMessage: newMessage => addMessage(idx, newMessage), editChoice: (choiceIndex, newChoice) => diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx index 80e4a32d0add..23c30c7e5584 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundChat/useChatCompletionFunctions.tsx @@ -218,7 +218,9 @@ const appendChoiceToMessages = ( updatedState.traceCall.inputs.messages.push( updatedState.traceCall.output.choices[choiceIndex].message ); - } else { + } else if ( + updatedState.traceCall.output.choices[updatedState.selectedChoiceIndex] + ) { updatedState.traceCall.inputs.messages.push( updatedState.traceCall.output.choices[updatedState.selectedChoiceIndex] .message diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundPage.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundPage.tsx index 4cadba37db91..7358468ee5cc 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundPage.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/PlaygroundPage/PlaygroundPage.tsx @@ -108,11 +108,9 @@ export const PlaygroundPageInner = (props: PlaygroundPageProps) => { setPlaygroundStateFromTraceCall(callWithCosts.result.traceCall); } } - }, [ - callWithCosts.loading, - setPlaygroundStateFromTraceCall, - callWithCosts.result, - ]); + // Only set the call the first time the page loads, and we get the call + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [callWithCosts.loading]); useEffect(() => { setPlaygroundStates(prev => { From fcb51c3335f24667f9caa0d3918d425c2253e808 Mon Sep 17 00:00:00 2001 From: "Chris Van Pelt (CVP)" Date: Thu, 19 Dec 2024 16:00:22 -0800 Subject: [PATCH 14/35] feat(weave): Add mods page and menu item only for wandb admins (#3279) * Basic UI for mods * Pass along purl for wild demo purposes * Mod demo updates * Wire up secret setting, add mod visual indicator * gradient similar to streamlit * Added secret types * Fix mutation types * Use the wandb api host for our iframe * Wire up backend host * Make mods page scroll properly * Only show mods to admins * Fix TSC errors * Fix project sidebar deps * Fix bungled merge * Add grace period for startup * Try some debugging, increase retries * Fix formatting * Fix trailing newline * Enabling container logging * Use wget instead of curl as we dont have it in the container anymore * Fix shadow variable lint error --- .github/workflows/test.yaml | 16 +- wb_schema.gql | 21 ++ weave-js/src/common/hooks/useSecrets.ts | 121 ++++++ .../components/FancyPage/useProjectSidebar.ts | 27 +- .../PagePanelComponents/Home/Browse3.tsx | 18 + .../Home/Browse3/pages/ModsPage.tsx | 353 ++++++++++++++++++ weave-js/src/config.ts | 3 +- 7 files changed, 550 insertions(+), 9 deletions(-) create mode 100644 weave-js/src/common/hooks/useSecrets.ts create mode 100644 weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ModsPage.tsx diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 295b6ef89227..ab0a55fb384c 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -81,11 +81,16 @@ jobs: env: CI: 1 WANDB_ENABLE_TEST_CONTAINER: true + LOGGING_ENABLED: true ports: - '8080:8080' - '8083:8083' - '9015:9015' - options: --health-cmd "curl --fail http://localhost:8080/healthz || exit 1" --health-interval=5s --health-timeout=3s + options: >- + --health-cmd "wget -q -O /dev/null http://localhost:8080/healthz || exit 1" + --health-interval=5s + --health-timeout=3s + --health-start-period=10s outputs: tests_should_run: ${{ steps.test_check.outputs.tests_should_run }} steps: @@ -254,11 +259,16 @@ jobs: env: CI: 1 WANDB_ENABLE_TEST_CONTAINER: true + LOGGING_ENABLED: true ports: - '8080:8080' - '8083:8083' - '9015:9015' - options: --health-cmd "curl --fail http://localhost:8080/healthz || exit 1" --health-interval=5s --health-timeout=3s + options: >- + --health-cmd "wget -q -O /dev/null http://localhost:8080/healthz || exit 1" + --health-interval=5s + --health-timeout=3s + --health-start-period=10s weave_clickhouse: image: clickhouse/clickhouse-server ports: @@ -267,6 +277,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + - name: Enable debug logging + run: echo "ACTIONS_STEP_DEBUG=true" >> $GITHUB_ENV - name: Set up Python ${{ matrix.python-version-major }}.${{ matrix.python-version-minor }} uses: actions/setup-python@v5 with: diff --git a/wb_schema.gql b/wb_schema.gql index f326ab4d4872..13152c785475 100644 --- a/wb_schema.gql +++ b/wb_schema.gql @@ -104,10 +104,24 @@ type UpdateUserPayload { clientMutationId: String } +input InsertSecretInput { + entityName: String! + secretName: String! + @constraints(max: 255, pattern: "^[A-Za-z_][A-Za-z0-9_]*$") + secretValue: String! + clientMutationId: String +} + +type InsertSecretPayload { + success: Boolean! + clientMutationId: String +} + type Mutation { updateUser(input: UpdateUserInput!): UpdateUserPayload @audit deleteView(input: DeleteViewInput!): DeleteViewPayload upsertView(input: UpsertViewInput!): UpsertViewPayload @audit + insertSecret(input: InsertSecretInput!): InsertSecretPayload updateArtifactSequence( input: UpdateArtifactSequenceInput! ): UpdateArtifactCollectionPayload @@ -275,6 +289,12 @@ type RowType { row: JSON! } +type Secret { + entityId: Int! + name: String! + createdAt: DateTime! +} + type Entity implements Node { id: ID! name: String! @@ -296,6 +316,7 @@ type Entity implements Node { filters: JSONString collectionTypes: [ArtifactCollectionType!] ): ArtifactCollectionConnection + secrets: [Secret!]! } type EntityConnection { diff --git a/weave-js/src/common/hooks/useSecrets.ts b/weave-js/src/common/hooks/useSecrets.ts new file mode 100644 index 000000000000..8446be55dd73 --- /dev/null +++ b/weave-js/src/common/hooks/useSecrets.ts @@ -0,0 +1,121 @@ +/** + * This is a GraphQL approach to querying viewer information. + * There is a query engine based approach in useViewerUserInfo.ts. + */ + +import { + gql, + TypedDocumentNode, + useApolloClient, + useMutation, +} from '@apollo/client'; +import {useEffect, useState} from 'react'; + +const SECRETS_QUERY = gql` + query secrets($entityName: String!) { + entity(name: $entityName) { + id + secrets { + entityId + name + createdAt + } + } + } +`; + +const SECRETS_MUTATION = gql` + mutation insertSecret( + $entityName: String! + $secretName: String! + $secretValue: String! + ) { + insertSecret( + input: { + entityName: $entityName + secretName: $secretName + secretValue: $secretValue + } + ) { + success + } + } +` as TypedDocumentNode; + +type SecretResponseLoading = { + loading: true; + entityId: string; + secrets: string[]; +}; +type SecretResponseSuccess = { + loading: false; + entityId: string; + secrets: string[]; +}; +type SecretResponse = SecretResponseLoading | SecretResponseSuccess; + +export const useSecrets = ({ + entityName, +}: { + entityName: string; +}): SecretResponse => { + const [response, setResponse] = useState({ + loading: true, + entityId: '', + secrets: [], + }); + + const apolloClient = useApolloClient(); + + useEffect(() => { + let mounted = true; + apolloClient + .query({query: SECRETS_QUERY as any, variables: {entityName}}) + .then(result => { + if (!mounted) { + return; + } + const secretPayloads = result.data.entity?.secrets ?? []; + if (!secretPayloads) { + setResponse({ + loading: false, + entityId: '', + secrets: [], + }); + return; + } + const secrets = secretPayloads.map((secret: any) => secret.name).sort(); + setResponse({ + loading: false, + entityId: result.data.entity?.id ?? '', + secrets, + }); + }); + return () => { + mounted = false; + }; + }, [apolloClient, entityName]); + + return response; +}; + +interface InsertSecretResponse { + insertSecret: { + success: boolean; + }; +} + +type InsertSecretVariables = { + entityName: string; + secretName: string; + secretValue: string; +}; + +export const useInsertSecret = () => { + const [insertSecret] = useMutation< + InsertSecretResponse, + InsertSecretVariables + >(SECRETS_MUTATION); + + return insertSecret; +}; diff --git a/weave-js/src/components/FancyPage/useProjectSidebar.ts b/weave-js/src/components/FancyPage/useProjectSidebar.ts index 19dce4215df7..2bd8c5635d55 100644 --- a/weave-js/src/components/FancyPage/useProjectSidebar.ts +++ b/weave-js/src/components/FancyPage/useProjectSidebar.ts @@ -11,7 +11,8 @@ export const useProjectSidebar = ( hasWeaveData: boolean, hasTraceBackend: boolean = true, hasModelsAccess: boolean = true, - isLaunchActive: boolean = false + isLaunchActive: boolean = false, + isWandbAdmin: boolean = false ): FancyPageSidebarItem[] => { // Should show models sidebar items if we have models data or if we don't have a trace backend let showModelsSidebarItems = hasModelsData || !hasTraceBackend; @@ -34,6 +35,14 @@ export const useProjectSidebar = ( const isShowAll = isNoSidebarItems || isBothSidebarItems; return useMemo(() => { + const weaveOnlyMenu = [ + 'weave/leaderboards', + 'weave/operations', + 'weave/objects', + ]; + if (isWandbAdmin) { + weaveOnlyMenu.push('weave/mods'); + } const allItems = isLoading ? [] : [ @@ -178,6 +187,14 @@ export const useProjectSidebar = ( isShown: isWeaveOnly, iconName: IconNames.TypeNumberAlt, }, + { + type: 'button' as const, + name: 'Mods', + slug: 'weave/mods', + isShown: false, // Only shown in overflow menu + isDisabled: !isWandbAdmin, + iconName: IconNames.LayoutGrid, + }, { type: 'button' as const, name: 'Leaders', @@ -205,7 +222,7 @@ export const useProjectSidebar = ( type: 'menuPlaceholder' as const, key: 'moreWeaveOnly', isShown: isWeaveOnly, - menu: ['weave/leaderboards', 'weave/operations', 'weave/objects'], + menu: weaveOnlyMenu, }, { type: 'menuPlaceholder' as const, @@ -216,10 +233,7 @@ export const useProjectSidebar = ( 'weave/models', 'weave/datasets', 'weave/scorers', - 'weave/leaderboards', - 'weave/operations', - 'weave/objects', - ], + ].concat(weaveOnlyMenu), }, ]; @@ -252,5 +266,6 @@ export const useProjectSidebar = ( isModelsOnly, showWeaveSidebarItems, isLaunchActive, + isWandbAdmin, ]); }; diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3.tsx index 761fd5369309..c0192ddbe9f6 100644 --- a/weave-js/src/components/PagePanelComponents/Home/Browse3.tsx +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3.tsx @@ -71,6 +71,7 @@ import {SimplePageLayoutContext} from './Browse3/pages/common/SimplePageLayout'; import {CompareEvaluationsPage} from './Browse3/pages/CompareEvaluationsPage/CompareEvaluationsPage'; import {LeaderboardListingPage} from './Browse3/pages/LeaderboardPage/LeaderboardListingPage'; import {LeaderboardPage} from './Browse3/pages/LeaderboardPage/LeaderboardPage'; +import {ModsPage} from './Browse3/pages/ModsPage'; import {ObjectPage} from './Browse3/pages/ObjectPage'; import {ObjectVersionPage} from './Browse3/pages/ObjectVersionPage'; import { @@ -146,6 +147,7 @@ const tabOptions = [ 'leaderboards', 'boards', 'tables', + 'mods', 'scorers', ]; const tabs = tabOptions.join('|'); @@ -484,6 +486,11 @@ const Browse3ProjectRoot: FC<{ + {/* MODS */} + + + {/* PLAYGROUND */} { return ; }; +const ModsPageBinding = () => { + const params = useParamsDecoded(); + return ( + + ); +}; + const TablesPageBinding = () => { const params = useParamsDecoded(); diff --git a/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ModsPage.tsx b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ModsPage.tsx new file mode 100644 index 000000000000..05d6da871c02 --- /dev/null +++ b/weave-js/src/components/PagePanelComponents/Home/Browse3/pages/ModsPage.tsx @@ -0,0 +1,353 @@ +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Card from '@mui/material/Card'; +import CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; +import Drawer from '@mui/material/Drawer'; +import Grid from '@mui/material/Grid2'; +import TextField from '@mui/material/TextField'; +import { + useInsertSecret, + useSecrets, +} from '@wandb/weave/common/hooks/useSecrets'; +import {TargetBlank} from '@wandb/weave/common/util/links'; +import React, {useCallback, useEffect, useMemo, useState} from 'react'; +import {useHistory} from 'react-router'; +import {Link} from 'react-router-dom'; + +import {SimplePageLayout} from './common/SimplePageLayout'; + +type Mod = { + id: string; + name: string; + description: string; + secrets: string[]; +}; + +type ModCategoryType = 'Labeling' | 'Analysis' | 'Demos'; + +type ModCategories = { + [key in ModCategoryType]: Mod[]; +}; + +const modCats: ModCategories = { + Labeling: [ + { + id: 'labeling/html', + name: 'HTML Labeler', + description: 'Label generated HTML against your own criteria', + secrets: ['WANDB_API_KEY', 'OPENAI_API_KEY'], + }, + ], + Analysis: [ + { + id: 'embedding-classifier', + name: 'Embedding Classifier', + description: + 'Classify your traces by embedding them and have an LLM label the clusters', + secrets: ['WANDB_API_KEY', 'OPENAI_API_KEY'], + }, + { + id: 'cost-dashboard', + name: 'Cost Dashboard', + description: 'A dashboard showing your project LLM costs over time', + secrets: ['WANDB_API_KEY'], + }, + ], + Demos: [ + { + id: 'welcome', + name: 'Welcome', + description: 'A simple welcome mod', + secrets: ['WANDB_API_KEY'], + }, + { + id: 'openui', + name: 'OpenUI', + description: 'Generate UIs from images or text descriptions', + secrets: ['WANDB_API_KEY', 'OPENAI_API_KEY', 'ANTHROPIC_API_KEY'], + }, + { + id: 'gist', + name: 'Gist', + description: 'Load a gist that contains a streamlit app.py file', + secrets: ['WANDB_API_KEY'], + }, + ], +}; + +const ModCategory: React.FC<{ + category: ModCategoryType; + mods: Mod[]; + entity: string; + project: string; +}> = ({category, mods, entity, project}) => { + return ( + +
+ {category} +
+ +
+ ); +}; + +const ModCards: React.FC<{mods: Mod[]; entity: string; project: string}> = ({ + mods, + entity, + project, +}) => { + const searchParams = new URLSearchParams(window.location.search); + const [gistId, setGistId] = useState(''); + + const purl = + searchParams.get('purl') || + (gistId !== '' ? encodeURIComponent(`pkg:gist/${gistId}`) : ''); + return ( + + {mods.map(mod => ( + + + +
{mod.name}
+

{mod.description}

+
+ + {mod.id === 'gist' && ( + setGistId(e.target.value)} + /> + )} + + +
+
+ ))} +
+ ); +}; + +const ModFrame: React.FC<{entity: string; project: string; modId: string}> = ({ + entity, + project, + modId, +}) => { + const searchParams = new URLSearchParams(window.location.search); + const purl = searchParams.get('purl'); + return ( +