olca 0.2.34__py3-none-any.whl → 0.2.36__py3-none-any.whl

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.
olca/fusewill_cli.py CHANGED
@@ -1,3 +1,4 @@
1
+ from ast import alias
1
2
  import os
2
3
  import sys
3
4
  sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
@@ -12,7 +13,8 @@ from fusewill_utils import (
12
13
  get_trace_by_id,
13
14
  open_trace_in_browser,
14
15
  print_traces,
15
- print_trace
16
+ print_trace,
17
+ list_traces_by_score # Ensure the updated function is imported
16
18
  )
17
19
  import dotenv
18
20
  import json
@@ -30,24 +32,24 @@ def get_single_char_input():
30
32
  return ch
31
33
 
32
34
  def main():
33
- parser = argparse.ArgumentParser(description="Langfuse CLI Wrapper")
35
+ parser = argparse.ArgumentParser(description="FuseWill Langfuse CLI Wrapper")
34
36
  subparsers = parser.add_subparsers(dest="command", help="Available commands")
35
37
 
36
38
  # list_traces command
37
39
  parser_list = subparsers.add_parser('list_traces', help='List traces',aliases=['lt'])
38
- parser_list.add_argument('--limit', type=int, default=100, help='Number of traces to fetch')
40
+ parser_list.add_argument('-L','--limit', type=int, default=100, help='Number of traces to fetch')
39
41
  parser_list.add_argument('--output_dir', type=str, default='../output/traces', help='Directory to save traces')
40
42
  parser_list.add_argument('-C','--comments', action='store_true', help='Show comments from the traces', default=False)
41
43
  parser_list.add_argument('-W','--browse-interact', action='store_true', help='Ask user to open each trace in browser')
42
44
 
43
45
  # create_dataset command
44
- parser_create_dataset = subparsers.add_parser('create_dataset', help='Create a new dataset')
46
+ parser_create_dataset = subparsers.add_parser('create_dataset', help='Create a new dataset',aliases=['cd'])
45
47
  parser_create_dataset.add_argument('name', help='Name of the dataset')
46
- parser_create_dataset.add_argument('--description', default='', help='Description of the dataset')
47
- parser_create_dataset.add_argument('--metadata', type=str, default='{}', help='Metadata in JSON format')
48
+ parser_create_dataset.add_argument('-D','--description', default='', help='Description of the dataset')
49
+ parser_create_dataset.add_argument('-M','--metadata', type=str, default='{}', help='Metadata in JSON format')
48
50
 
49
51
  # create_prompt command
50
- parser_create_prompt = subparsers.add_parser('create_prompt', help='Create a new prompt')
52
+ parser_create_prompt = subparsers.add_parser('create_prompt', help='Create a new prompt',aliases=['cp'])
51
53
  parser_create_prompt.add_argument('name', help='Name of the prompt')
52
54
  parser_create_prompt.add_argument('prompt_text', help='Prompt text')
53
55
  parser_create_prompt.add_argument('--model_name', default='gpt-4o-mini', help='Model name')
@@ -56,7 +58,7 @@ def main():
56
58
  parser_create_prompt.add_argument('--supported_languages', nargs='*', default=[], help='Supported languages')
57
59
 
58
60
  # update_prompt command
59
- parser_update_prompt = subparsers.add_parser('update_prompt', help='Update an existing prompt')
61
+ parser_update_prompt = subparsers.add_parser('update_prompt', help='Update an existing prompt',aliases=['up'])
60
62
  parser_update_prompt.add_argument('name', help='Name of the prompt')
61
63
  parser_update_prompt.add_argument('new_prompt_text', help='New prompt text')
62
64
 
@@ -65,11 +67,11 @@ def main():
65
67
  parser_delete_dataset.add_argument('name', help='Name of the dataset')
66
68
 
67
69
  # get_trace_by_id command
68
- parser_get_trace = subparsers.add_parser('get_trace_by_id', help='Get a trace by ID')
70
+ parser_get_trace = subparsers.add_parser('get_trace_by_id', help='Get a trace by ID',aliases=['gt'])
69
71
  parser_get_trace.add_argument('trace_id', help='Trace ID')
70
72
 
71
73
  # new_score command
72
- parser_new_score = subparsers.add_parser('new_score', help='Create a new score')
74
+ parser_new_score = subparsers.add_parser('new_score', help='Create a new score',aliases=['ns'])
73
75
  parser_new_score.add_argument('name', help='Score name')
74
76
  parser_new_score.add_argument('data_type', help='Data type of the score')
75
77
  parser_new_score.add_argument('--description', default='', help='Description of the score')
@@ -84,11 +86,11 @@ def main():
84
86
  parser_add_score.add_argument('--comment', default='', help='Comment for the score')
85
87
 
86
88
  # list_traces_by_score command
87
- parser_list_by_score = subparsers.add_parser('list_traces_by_score', help='List traces by score')
89
+ parser_list_by_score = subparsers.add_parser('list_traces_by_score', help='List traces by score', aliases=['ltbs','lbys','lts'])
88
90
  parser_list_by_score.add_argument('score_name', help='Score name')
89
91
  parser_list_by_score.add_argument('--min_value', type=float, help='Minimum score value')
90
92
  parser_list_by_score.add_argument('--max_value', type=float, help='Maximum score value')
91
- parser_list_by_score.add_argument('--limit', type=int, default=100, help='Number of traces to fetch')
93
+ parser_list_by_score.add_argument('-L','--limit', type=int, default=100, help='Number of traces to fetch')
92
94
 
93
95
  args = parser.parse_args()
94
96
 
@@ -115,7 +117,7 @@ def main():
115
117
  elif resp == 'q':
116
118
  print("Quitting.")
117
119
  break
118
- elif args.command == 'create_dataset':
120
+ elif args.command == 'create_dataset' or args.command == 'cd':
119
121
  metadata = json.loads(args.metadata)
120
122
  create_dataset(name=args.name, description=args.description, metadata=metadata)
121
123
  elif args.command == 'create_prompt':
@@ -127,16 +129,16 @@ def main():
127
129
  labels=args.labels,
128
130
  supported_languages=args.supported_languages
129
131
  )
130
- elif args.command == 'update_prompt':
132
+ elif args.command == 'update_prompt' or args.command == 'up':
131
133
  update_prompt(name=args.name, new_prompt_text=args.new_prompt_text)
132
134
  elif args.command == 'delete_dataset':
133
135
  delete_dataset(name=args.name)
134
- elif args.command == 'get_trace_by_id':
136
+ elif args.command == 'get_trace_by_id' or args.command == 'gt' :
135
137
  trace = get_trace_by_id(trace_id=args.trace_id)
136
138
  print(trace)
137
- elif args.command == 'new_score':
139
+ elif args.command == 'new_score' or args.command == 'ns':
138
140
  fu.create_score(name=args.name, data_type=args.data_type, description=args.description)
139
- elif args.command == 'add_score_to_trace':
141
+ elif args.command == 'add_score_to_trace' or args.command == 's2t':
140
142
  if not fu.score_exists(name=args.name):
141
143
  fu.create_score(name=args.name, data_type=args.data_type)
142
144
  fu.add_score_to_a_trace(
@@ -147,7 +149,7 @@ def main():
147
149
  data_type=args.data_type,
148
150
  comment=args.comment
149
151
  )
150
- elif args.command == 'list_traces_by_score':
152
+ elif args.command == 'list_traces_by_score' or args.command == 'ltbs' or args.command == 'lbys' or args.command == 'lts':
151
153
  traces = fu.list_traces_by_score(
152
154
  score_name=args.score_name,
153
155
  min_value=args.min_value,
@@ -155,7 +157,8 @@ def main():
155
157
  limit=args.limit
156
158
  )
157
159
  for trace in traces:
158
- print(f"Trace ID: {trace.id}, Name: {trace.name}")
160
+ print_trace(trace)
161
+ #print(f"Trace ID: {trace.id}, Name: {trace.name}")
159
162
  else:
160
163
  parser.print_help()
161
164
  exit(1)
olca/fusewill_utils.py CHANGED
@@ -3,6 +3,7 @@ import sys
3
3
  import json
4
4
  import dotenv
5
5
  import webbrowser
6
+ import requests # Add this import
6
7
 
7
8
  # Load .env from the current working directory
8
9
  dotenv.load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))
@@ -53,6 +54,20 @@ def open_trace_in_browser(trace_id):
53
54
  print(f"Opening {full_url}")
54
55
  webbrowser.open(full_url)
55
56
 
57
+ def get_score_by_id(score_id):
58
+ """Retrieve score details by score ID."""
59
+ base_url = os.environ.get("LANGFUSE_HOST")
60
+ public_key = os.environ.get("LANGFUSE_PUBLIC_KEY")
61
+ secret_key = os.environ.get("LANGFUSE_SECRET_KEY")
62
+ url = f"{base_url}/api/public/scores/{score_id}"
63
+ try:
64
+ response = requests.get(url, auth=(public_key, secret_key))
65
+ response.raise_for_status()
66
+ return response.json()
67
+ except Exception as e:
68
+ print(f"Error retrieving score {score_id}: {e}")
69
+ return None
70
+
56
71
  def print_trace(trace, show_comments=False):
57
72
  print(f"<Trace \n\tat=\"{trace.createdAt}\" \n\tid=\"{trace.id}\" \n\tname=\"{trace.name}\" \n\tsession_id=\"{trace.session_id}\" \n\tprojectId=\"{trace.projectId}\" >")
58
73
  print(f"<Input><CDATA[[\n{trace.input}\n]]></Input>")
@@ -61,8 +76,10 @@ def print_trace(trace, show_comments=False):
61
76
  print(f"<Metadata>{trace.metadata}</Metadata>")
62
77
  if trace.scores:
63
78
  print("<Scores>")
64
- for score in trace.scores:
65
- print(f"{score}")
79
+ for score_id in trace.scores:
80
+ score = get_score_by_id(score_id)
81
+ if score:
82
+ print(f"<Score name=\"{score['name']}\" value=\"{score['value']}\" data_type=\"{score['dataType']}\" />")
66
83
  print("</Scores>")
67
84
  if show_comments and hasattr(trace, "comments"):
68
85
  print(f"<Comments>\n{trace.comments}\n</Comments>")
@@ -81,9 +98,10 @@ def list_traces_by_score(score_name, min_value=None, max_value=None, limit=100):
81
98
  traces = langfuse.get_traces(limit=limit)
82
99
  filtered_traces = []
83
100
  for trace in traces.data:
84
- for score in trace.scores:
85
- if score.name == score_name:
86
- if (min_value is None or score.value >= min_value) and (max_value is None or score.value <= max_value):
101
+ for score_id in trace.scores:
102
+ score = get_score_by_id(score_id)
103
+ if score and score.get('name') == score_name:
104
+ if (min_value is None or score.get('value') >= min_value) and (max_value is None or score.get('value') <= max_value):
87
105
  filtered_traces.append(trace)
88
106
  break
89
107
  return filtered_traces
olca/olcacli.py CHANGED
@@ -166,6 +166,8 @@ def _parse_args():
166
166
  parser.add_argument("-y", "--yes", action="store_true", help="Accept the new file olca.yml")
167
167
  return parser.parse_args()
168
168
 
169
+ from olca.tracing import TracingManager
170
+
169
171
  def main():
170
172
  args = _parse_args()
171
173
  olca_config_file = 'olca.yml'
@@ -186,21 +188,14 @@ def main():
186
188
 
187
189
  config = load_config(olca_config_file)
188
190
 
189
- # Check for tracing flag in config and CLI
190
- tracing_enabled = config.get('tracing', False) or args.tracing or os.getenv("LANGCHAIN_TRACING_V2") == "true"
191
- if tracing_enabled:
192
- os.environ["LANGCHAIN_TRACING_V2"] = "true"
193
- if not os.getenv("LANGCHAIN_API_KEY"):
194
- print("Error: LANGCHAIN_API_KEY environment variable is required for tracing. Please set it up at : https://smith.langchain.com/settings")
195
- exit(1)
196
- # Initialize LangSmith client
197
- import langsmith
198
- LANGSMITH_API_KEY = os.getenv("LANGSMITH_API_KEY")
199
- LANGCHAIN_API_KEY = os.getenv("LANGCHAIN_API_KEY")
200
- if not LANGSMITH_API_KEY and not LANGCHAIN_API_KEY:
201
- print("Error: LANGSMITH_API_KEY or LANGCHAIN_API_KEY environment variable is not set.")
202
- exit(1)
203
- client = langsmith.Client(api_key=LANGSMITH_API_KEY or LANGCHAIN_API_KEY)
191
+ # Initialize tracing
192
+ tracing_manager = TracingManager(config)
193
+ callbacks = tracing_manager.get_callbacks()
194
+
195
+ # Remove old tracing setup
196
+ tracing_enabled = config.get('tracing', False) or args.tracing
197
+ if tracing_enabled and not callbacks:
198
+ print("Warning: Tracing enabled but no handlers configured")
204
199
 
205
200
  try:
206
201
 
@@ -286,7 +281,10 @@ def main():
286
281
 
287
282
 
288
283
  try:
289
- print_stream(graph.stream(inputs, stream_mode="values"))
284
+ graph_config = {"callbacks": callbacks} if callbacks else {}
285
+ if recursion_limit:
286
+ graph_config["recursion_limit"] = recursion_limit
287
+ print_stream(graph.stream(inputs, config=graph_config))
290
288
  except GraphRecursionError as e:
291
289
  #print(f"Error: {e}")
292
290
  print("Recursion limit reached. Please increase the 'recursion_limit' in the olca_config.yaml file.")
@@ -317,7 +315,8 @@ def initialize_config_file():
317
315
  "recursion_limit": int(input("recursion_limit [12]: ") or default_recursion_limit),
318
316
  "temperature": float(input("temperature [0]: ") or default_temperature),
319
317
  "human": input("human [true]: ").lower() in ["true", "yes", "y", "1", ""] or use_default_human_input,
320
- "tracing": input("tracing [true]: ").lower() in ["true", "yes", "y", "1", ""] or use_default_tracing
318
+ "tracing": input("tracing [true]: ").lower() in ["true", "yes", "y", "1", ""] or use_default_tracing,
319
+ "tracing_providers": ["langsmith", "langfuse"]
321
320
  }
322
321
 
323
322
  user_system_instructions = input(f"system_instructions [{default_system_instructions}]: ")
olca/tracing.py ADDED
@@ -0,0 +1,38 @@
1
+ import os
2
+ from langfuse.callback import CallbackHandler as LangfuseCallbackHandler
3
+
4
+ class TracingManager:
5
+ def __init__(self, config):
6
+ self.config = config
7
+ self.handlers = []
8
+ self.initialize_tracing()
9
+
10
+ def initialize_tracing(self):
11
+ tracing_enabled = self.config.get('tracing', False)
12
+ providers = self.config.get('tracing_providers', ['langsmith'])
13
+
14
+ if not tracing_enabled:
15
+ return
16
+
17
+ if 'langsmith' in providers:
18
+ self._setup_langsmith()
19
+
20
+ if 'langfuse' in providers:
21
+ handler = self._setup_langfuse()
22
+ if handler:
23
+ self.handlers.append(handler)
24
+
25
+ def _setup_langsmith(self):
26
+ api_key = os.getenv("LANGCHAIN_API_KEY") or os.getenv("LANGSMITH_API_KEY")
27
+ if api_key:
28
+ os.environ["LANGCHAIN_TRACING_V2"] = "true"
29
+
30
+ def _setup_langfuse(self):
31
+ if not (os.getenv("LANGFUSE_PUBLIC_KEY") and os.getenv("LANGFUSE_SECRET_KEY")):
32
+ print("Warning: LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY not set for Langfuse tracing")
33
+ return None
34
+
35
+ return LangfuseCallbackHandler()
36
+
37
+ def get_callbacks(self):
38
+ return self.handlers if self.handlers else None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: olca
3
- Version: 0.2.34
3
+ Version: 0.2.36
4
4
  Summary: A Python package for experimental usage of Langchain and Human-in-the-Loop
5
5
  Home-page: https://github.com/jgwill/olca
6
6
  Author: Jean GUillaume ISabelle
@@ -0,0 +1,11 @@
1
+ olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
2
+ olca/fusewill_cli.py,sha256=Gf8CaYs7Uo4NH8QfgRNYalpmSUo047p9rzdkvIABHi8,7872
3
+ olca/fusewill_utils.py,sha256=IOIElqWCIsNzePlS1FZa5_35vySYLwbMUGW6UhNefIc,6065
4
+ olca/olcacli.py,sha256=MBWanmGn1vWiy0S2lhe_dJc7u-B14n3ywA7lEP4qttM,14578
5
+ olca/tracing.py,sha256=A6K9K_mhCPS1_NncFv2-7hbeMkqfKT3XgUCERusbIYE,1248
6
+ olca-0.2.36.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
7
+ olca-0.2.36.dist-info/METADATA,sha256=ovFeWWj5Xn2It7PqskYfvDNCSW0MjjO9bTKhb3y8DyY,25311
8
+ olca-0.2.36.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
9
+ olca-0.2.36.dist-info/entry_points.txt,sha256=AhP5FMv6vnOq9C76V_vxRVIO50smnZXG4RIY47oD2_U,103
10
+ olca-0.2.36.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
11
+ olca-0.2.36.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
2
- olca/fusewill_cli.py,sha256=-hq-uCQfx9Tkb8TTTJNgQS7hgigS9XDaNBL9CKAouMU,7415
3
- olca/fusewill_utils.py,sha256=qh_ZGx9hV18wrdPM6ofXNFqyP51TeuoUeeTWfWIG1y8,5251
4
- olca/olcacli.py,sha256=s-dqJRE6xqQLG_qSwp8prahRV3vZNueEaK7OXgmU9wc,14885
5
- olca-0.2.34.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
6
- olca-0.2.34.dist-info/METADATA,sha256=a453tzxvh71r4zn0ikUB-J9q-Btp2D3y3LRfDIGlCCU,25311
7
- olca-0.2.34.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
8
- olca-0.2.34.dist-info/entry_points.txt,sha256=AhP5FMv6vnOq9C76V_vxRVIO50smnZXG4RIY47oD2_U,103
9
- olca-0.2.34.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
10
- olca-0.2.34.dist-info/RECORD,,
File without changes
File without changes