Skip to content

Commit

Permalink
Merge branch 'main' into feat-bedrock-converse
Browse files Browse the repository at this point in the history
  • Loading branch information
FloRul authored Sep 17, 2024
2 parents e446ad3 + b32f620 commit f1b68e6
Show file tree
Hide file tree
Showing 17 changed files with 1,390 additions and 33 deletions.
17 changes: 16 additions & 1 deletion integrations/cohere/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
# Changelog

## [unreleased]
## [integrations/cohere-v2.0.0] - 2024-09-16

### 🚀 Features

- Update Anthropic/Cohere for tools use (#790)
- Update Cohere default LLMs, add examples and update unit tests (#838)
- Cohere LLM - adjust token counting meta to match OpenAI format (#1086)

### 🐛 Bug Fixes

- Lints in `cohere-haystack` (#995)

### 🧪 Testing

- Do not retry tests in `hatch run test` command (#954)

### ⚙️ Miscellaneous Tasks

- Retry tests to reduce flakyness (#836)
- Update ruff invocation to include check parameter (#853)

### Docs

- Update CohereChatGenerator docstrings (#958)
- Update CohereGenerator docstrings (#960)

## [integrations/cohere-v1.1.1] - 2024-06-12

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def run(self, messages: List[ChatMessage], generation_kwargs: Optional[Dict[str,
if finish_response.meta.billed_units:
tokens_in = finish_response.meta.billed_units.input_tokens or -1
tokens_out = finish_response.meta.billed_units.output_tokens or -1
chat_message.meta["usage"] = tokens_in + tokens_out
chat_message.meta["usage"] = {"prompt_tokens": tokens_in, "completion_tokens": tokens_out}
chat_message.meta.update(
{
"model": self.model,
Expand Down Expand Up @@ -220,11 +220,13 @@ def _build_message(self, cohere_response):
message = ChatMessage.from_assistant(cohere_response.tool_calls[0].json())
elif cohere_response.text:
message = ChatMessage.from_assistant(content=cohere_response.text)
total_tokens = cohere_response.meta.billed_units.input_tokens + cohere_response.meta.billed_units.output_tokens
message.meta.update(
{
"model": self.model,
"usage": total_tokens,
"usage": {
"prompt_tokens": cohere_response.meta.billed_units.input_tokens,
"completion_tokens": cohere_response.meta.billed_units.output_tokens,
},
"index": 0,
"finish_reason": cohere_response.finish_reason,
"documents": cohere_response.documents,
Expand Down
7 changes: 7 additions & 0 deletions integrations/cohere/tests/test_cohere_chat_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ def test_live_run(self):
assert len(results["replies"]) == 1
message: ChatMessage = results["replies"][0]
assert "Paris" in message.content
assert "usage" in message.meta
assert "prompt_tokens" in message.meta["usage"]
assert "completion_tokens" in message.meta["usage"]

@pytest.mark.skipif(
not os.environ.get("COHERE_API_KEY", None) and not os.environ.get("CO_API_KEY", None),
Expand Down Expand Up @@ -210,6 +213,10 @@ def __call__(self, chunk: StreamingChunk) -> None:
assert callback.counter > 1
assert "Paris" in callback.responses

assert "usage" in message.meta
assert "prompt_tokens" in message.meta["usage"]
assert "completion_tokens" in message.meta["usage"]

@pytest.mark.skipif(
not os.environ.get("COHERE_API_KEY", None) and not os.environ.get("CO_API_KEY", None),
reason="Export an env var called COHERE_API_KEY/CO_API_KEY containing the Cohere API key to run this test.",
Expand Down
6 changes: 5 additions & 1 deletion integrations/langfuse/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog

## [unreleased]
## [integrations/langfuse-v0.4.0] - 2024-09-17

### 🚀 Features

- Langfuse - support generation span for more LLMs (#1087)

### 🚜 Refactor

Expand Down
31 changes: 29 additions & 2 deletions integrations/langfuse/example/chat.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
import os

# See README.md for more information on how to set up the environment variables
# before running this script

# In addition to setting the environment variables, you need to install the following packages:
# pip install cohere-haystack anthropic-haystack
os.environ["HAYSTACK_CONTENT_TRACING_ENABLED"] = "true"

from haystack import Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.generators.chat import HuggingFaceAPIChatGenerator, OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.utils.auth import Secret
from haystack.utils.hf import HFGenerationAPIType

from haystack_integrations.components.connectors.langfuse import LangfuseConnector
from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator
from haystack_integrations.components.generators.cohere import CohereChatGenerator

os.environ["HAYSTACK_CONTENT_TRACING_ENABLED"] = "true"

selected_chat_generator = "openai"

generators = {
"openai": OpenAIChatGenerator,
"anthropic": AnthropicChatGenerator,
"hf_api": lambda: HuggingFaceAPIChatGenerator(
api_type=HFGenerationAPIType.SERVERLESS_INFERENCE_API,
api_params={"model": "mistralai/Mixtral-8x7B-Instruct-v0.1"},
token=Secret.from_token(os.environ["HF_API_KEY"]),
),
"cohere": CohereChatGenerator,
}

selected_chat_generator = generators[selected_chat_generator]()

if __name__ == "__main__":

pipe = Pipeline()
pipe.add_component("tracer", LangfuseConnector("Chat example"))
pipe.add_component("prompt_builder", ChatPromptBuilder())
pipe.add_component("llm", OpenAIChatGenerator(model="gpt-3.5-turbo"))
pipe.add_component("llm", selected_chat_generator)

pipe.connect("prompt_builder.prompt", "llm.messages")

Expand Down
2 changes: 2 additions & 0 deletions integrations/langfuse/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ dependencies = [
"pytest",
"pytest-rerunfailures",
"haystack-pydoc-tools",
"anthropic-haystack",
"cohere-haystack"
]
[tool.hatch.envs.default.scripts]
test = "pytest {args:tests}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,22 @@
import langfuse

HAYSTACK_LANGFUSE_ENFORCE_FLUSH_ENV_VAR = "HAYSTACK_LANGFUSE_ENFORCE_FLUSH"
_SUPPORTED_GENERATORS = ["AzureOpenAIGenerator", "OpenAIGenerator"]
_SUPPORTED_CHAT_GENERATORS = ["AzureOpenAIChatGenerator", "OpenAIChatGenerator"]
_SUPPORTED_GENERATORS = [
"AzureOpenAIGenerator",
"OpenAIGenerator",
"AnthropicGenerator",
"HuggingFaceAPIGenerator",
"HuggingFaceLocalGenerator",
"CohereGenerator",
]
_SUPPORTED_CHAT_GENERATORS = [
"AzureOpenAIChatGenerator",
"OpenAIChatGenerator",
"AnthropicChatGenerator",
"HuggingFaceAPIChatGenerator",
"HuggingFaceLocalChatGenerator",
"CohereChatGenerator",
]
_ALL_SUPPORTED_GENERATORS = _SUPPORTED_GENERATORS + _SUPPORTED_CHAT_GENERATORS


Expand Down
55 changes: 31 additions & 24 deletions integrations/langfuse/tests/test_tracing.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import os

# don't remove (or move) this env var setting from here, it's needed to turn tracing on
os.environ["HAYSTACK_CONTENT_TRACING_ENABLED"] = "true"

from urllib.parse import urlparse

import pytest
from urllib.parse import urlparse
import requests

from requests.auth import HTTPBasicAuth
from haystack import Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from requests.auth import HTTPBasicAuth

from haystack_integrations.components.connectors.langfuse import LangfuseConnector
from haystack.components.generators.chat import OpenAIChatGenerator

from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator
from haystack_integrations.components.generators.cohere import CohereChatGenerator

# don't remove (or move) this env var setting from here, it's needed to turn tracing on
os.environ["HAYSTACK_CONTENT_TRACING_ENABLED"] = "true"


@pytest.mark.integration
@pytest.mark.skipif(
not os.environ.get("LANGFUSE_SECRET_KEY", None) and not os.environ.get("LANGFUSE_PUBLIC_KEY", None),
reason="Export an env var called LANGFUSE_SECRET_KEY and LANGFUSE_PUBLIC_KEY containing Langfuse credentials.",
@pytest.mark.parametrize(
"llm_class, env_var, expected_trace",
[
(OpenAIChatGenerator, "OPENAI_API_KEY", "OpenAI"),
(AnthropicChatGenerator, "ANTHROPIC_API_KEY", "Anthropic"),
(CohereChatGenerator, "COHERE_API_KEY", "Cohere"),
],
)
def test_tracing_integration():
def test_tracing_integration(llm_class, env_var, expected_trace):
if not all([os.environ.get("LANGFUSE_SECRET_KEY"), os.environ.get("LANGFUSE_PUBLIC_KEY"), os.environ.get(env_var)]):
pytest.skip(f"Missing required environment variables: LANGFUSE_SECRET_KEY, LANGFUSE_PUBLIC_KEY, or {env_var}")

pipe = Pipeline()
pipe.add_component("tracer", LangfuseConnector(name="Chat example", public=True)) # public so anyone can verify run
pipe.add_component("tracer", LangfuseConnector(name=f"Chat example - {expected_trace}", public=True))
pipe.add_component("prompt_builder", ChatPromptBuilder())
pipe.add_component("llm", OpenAIChatGenerator(model="gpt-3.5-turbo"))

pipe.add_component("llm", llm_class())
pipe.connect("prompt_builder.prompt", "llm.messages")

messages = [
Expand All @@ -39,17 +43,20 @@ def test_tracing_integration():
response = pipe.run(data={"prompt_builder": {"template_variables": {"location": "Berlin"}, "template": messages}})
assert "Berlin" in response["llm"]["replies"][0].content
assert response["tracer"]["trace_url"]

url = "https://cloud.langfuse.com/api/public/traces/"
trace_url = response["tracer"]["trace_url"]
parsed_url = urlparse(trace_url)
# trace id is the last part of the path (after the last '/')
uuid = os.path.basename(parsed_url.path)
uuid = os.path.basename(urlparse(trace_url).path)

try:
# GET request with Basic Authentication on the Langfuse API
response = requests.get(
url + uuid, auth=HTTPBasicAuth(os.environ.get("LANGFUSE_PUBLIC_KEY"), os.environ.get("LANGFUSE_SECRET_KEY"))
url + uuid, auth=HTTPBasicAuth(os.environ["LANGFUSE_PUBLIC_KEY"], os.environ["LANGFUSE_SECRET_KEY"])
)

assert response.status_code == 200, f"Failed to retrieve data from Langfuse API: {response.status_code}"

# check if the trace contains the expected LLM name
assert expected_trace in str(response.content)
# check if the trace contains the expected generation span
assert "GENERATION" in str(response.content)
except requests.exceptions.RequestException as e:
assert False, f"Failed to retrieve data from Langfuse API: {e}"
pytest.fail(f"Failed to retrieve data from Langfuse API: {e}")
1 change: 1 addition & 0 deletions integrations/snowflake/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## [integrations/snowflake-v0.0.1] - 2024-09-06
23 changes: 23 additions & 0 deletions integrations/snowflake/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# snowflake-haystack

[![PyPI - Version](https://img.shields.io/pypi/v/snowflake-haystack.svg)](https://pypi.org/project/snowflake-haystack)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/snowflake-haystack.svg)](https://pypi.org/project/snowflake-haystack)

-----

**Table of Contents**

- [Installation](#installation)
- [License](#license)

## Installation

```console
pip install snowflake-haystack
```
## Examples
You can find a code example showing how to use the Retriever under the `example/` folder of this repo.

## License

`snowflake-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
Loading

0 comments on commit f1b68e6

Please sign in to comment.