langfuse-haystack 0.0.2__tar.gz → 0.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langfuse-haystack
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/langfuse#readme
5
5
  Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
6
6
  Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/langfuse
@@ -0,0 +1,33 @@
1
+ import os
2
+
3
+ os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com"
4
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
5
+ os.environ["HAYSTACK_CONTENT_TRACING_ENABLED"] = "true"
6
+
7
+ from haystack.components.builders import DynamicChatPromptBuilder
8
+ from haystack.components.generators.chat import OpenAIChatGenerator
9
+ from haystack.dataclasses import ChatMessage
10
+ from haystack import Pipeline
11
+ from haystack.utils import Secret
12
+
13
+ from haystack_integrations.components.others.langfuse import LangfuseComponent
14
+
15
+
16
+ if __name__ == "__main__":
17
+
18
+ pipe = Pipeline()
19
+ pipe.add_component("tracer", LangfuseComponent("Chat example"))
20
+ pipe.add_component("prompt_builder", DynamicChatPromptBuilder())
21
+ pipe.add_component("llm", OpenAIChatGenerator(model="gpt-3.5-turbo"))
22
+
23
+ pipe.connect("prompt_builder.prompt", "llm.messages")
24
+
25
+ messages = [
26
+ ChatMessage.from_system("Always respond in German even if some input data is in other languages."),
27
+ ChatMessage.from_user("Tell me about {{location}}"),
28
+ ]
29
+
30
+ response = pipe.run(
31
+ data={"prompt_builder": {"template_variables": {"location": "Berlin"}, "prompt_source": messages}}
32
+ )
33
+ print(response["llm"]["replies"][0])
@@ -0,0 +1,3 @@
1
+ from .component import LangfuseComponent
2
+
3
+ __all__ = ["LangfuseComponent"]
@@ -4,8 +4,6 @@ from haystack_integrations.tracing.langfuse import LangfuseTracer
4
4
 
5
5
  from langfuse import Langfuse
6
6
 
7
- # from langfuse.openai import openai # noqa
8
-
9
7
 
10
8
  @component
11
9
  class LangfuseComponent:
@@ -23,9 +23,17 @@ class LangfuseSpan(Span):
23
23
  return
24
24
 
25
25
  if key.endswith(".input"):
26
- self._span.update(input=value)
26
+ if "messages" in value:
27
+ messages = [m.to_openai_format() for m in value["messages"]]
28
+ self._span.update(input=messages)
29
+ else:
30
+ self._span.update(input=value)
27
31
  elif key.endswith(".output"):
28
- self._span.update(output=value)
32
+ if "replies" in value:
33
+ replies = [m.to_openai_format() for m in value["replies"]]
34
+ self._span.update(output=replies)
35
+ else:
36
+ self._span.update(output=value)
29
37
 
30
38
  self._data[key] = value
31
39
 
@@ -46,11 +54,9 @@ class LangfuseTracer(Tracer):
46
54
  def trace(self, operation_name: str, tags: Optional[Dict[str, Any]] = None) -> Iterator[Span]:
47
55
  tags = tags or {}
48
56
  span_name = tags.get("haystack.component.name", operation_name)
49
- is_generation = False
50
57
 
51
- if tags.get("haystack.component.type") in ["OpenAIGenerator"]:
58
+ if tags.get("haystack.component.type") in ["OpenAIGenerator", "OpenAIChatGenerator"]:
52
59
  span = LangfuseSpan(self.current_span().raw_span().generation(name=span_name))
53
- is_generation = True
54
60
  else:
55
61
  span = LangfuseSpan(self.current_span().raw_span().span(name=span_name))
56
62
 
@@ -59,13 +65,18 @@ class LangfuseTracer(Tracer):
59
65
 
60
66
  yield span
61
67
 
62
- if is_generation:
68
+ if tags.get("haystack.component.type") == "OpenAIGenerator":
63
69
  meta = span._data.get("haystack.component.output", {}).get("meta")
64
70
  if meta:
65
71
  # Haystack returns one meta dict for each message, but the 'usage' value
66
72
  # is always the same, let's just pick the first item
67
73
  m = meta[0]
68
74
  span._span.update(usage=m.get("usage"), model=m.get("model"))
75
+ elif tags.get("haystack.component.type") == "OpenAIChatGenerator":
76
+ replies = span._data.get("haystack.component.output", {}).get("replies")
77
+ if replies:
78
+ meta = replies[0].meta
79
+ span._span.update(usage=meta.get("usage"), model=meta.get("model"))
69
80
 
70
81
  span.raw_span().end()
71
82
  self._context.pop()
@@ -1,3 +0,0 @@
1
- from .langfuse import LangfuseComponent
2
-
3
- __all__ = ["LangfuseComponent"]