olca 0.2.31__tar.gz → 0.2.33__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: olca
3
- Version: 0.2.31
3
+ Version: 0.2.33
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
@@ -9,20 +9,36 @@ from fusewill_utils import (
9
9
  create_prompt,
10
10
  update_prompt,
11
11
  delete_dataset,
12
- get_trace_by_id
12
+ get_trace_by_id,
13
+ open_trace_in_browser,
14
+ print_traces,
15
+ print_trace
13
16
  )
14
17
  import dotenv
15
18
  import json
19
+ import sys, termios, tty
16
20
  #dotenv.load_dotenv()
17
21
 
22
+ def get_single_char_input():
23
+ fd = sys.stdin.fileno()
24
+ old_settings = termios.tcgetattr(fd)
25
+ try:
26
+ tty.setraw(fd)
27
+ ch = sys.stdin.read(1)
28
+ finally:
29
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
30
+ return ch
31
+
18
32
  def main():
19
33
  parser = argparse.ArgumentParser(description="Langfuse CLI Wrapper")
20
34
  subparsers = parser.add_subparsers(dest="command", help="Available commands")
21
35
 
22
36
  # list_traces command
23
- parser_list = subparsers.add_parser('list_traces', help='List traces')
37
+ parser_list = subparsers.add_parser('list_traces', help='List traces',aliases=['lt'])
24
38
  parser_list.add_argument('--limit', type=int, default=100, help='Number of traces to fetch')
25
39
  parser_list.add_argument('--output_dir', type=str, default='../output/traces', help='Directory to save traces')
40
+ parser_list.add_argument('-C','--comments', action='store_true', help='Show comments from the traces', default=False)
41
+ parser_list.add_argument('-W','--browse-interact', action='store_true', help='Ask user to open each trace in browser')
26
42
 
27
43
  # create_dataset command
28
44
  parser_create_dataset = subparsers.add_parser('create_dataset', help='Create a new dataset')
@@ -76,8 +92,29 @@ def main():
76
92
 
77
93
  args = parser.parse_args()
78
94
 
79
- if args.command == 'list_traces':
80
- list_traces(limit=args.limit, output_dir=args.output_dir)
95
+ if args.command == 'list_traces' or args.command == 'lt':
96
+ show_comments_flag = args.comments if args.comments else False
97
+ traces = list_traces(
98
+ limit=args.limit,
99
+ output_dir=args.output_dir
100
+ )
101
+ if not args.browse_interact:
102
+ print_traces(traces, show_comments=show_comments_flag)
103
+ else:
104
+ for trace in traces.data:
105
+ print_trace(trace, show_comments=show_comments_flag)
106
+ print("Open this trace in browser (Y/N/Q)? ", end='', flush=True)
107
+ try:
108
+ resp = get_single_char_input().lower()
109
+ except KeyboardInterrupt:
110
+ print("\nExiting.")
111
+ sys.exit(0)
112
+ print(resp) # Echo the character
113
+ if resp == 'y':
114
+ open_trace_in_browser(trace.id)
115
+ elif resp == 'q':
116
+ print("Quitting.")
117
+ break
81
118
  elif args.command == 'create_dataset':
82
119
  metadata = json.loads(args.metadata)
83
120
  create_dataset(name=args.name, description=args.description, metadata=metadata)
@@ -121,6 +158,7 @@ def main():
121
158
  print(f"Trace ID: {trace.id}, Name: {trace.name}")
122
159
  else:
123
160
  parser.print_help()
161
+ exit(1)
124
162
 
125
163
  if __name__ == '__main__':
126
164
  main()
@@ -2,12 +2,13 @@ import os
2
2
  import sys
3
3
  import json
4
4
  import dotenv
5
+ import webbrowser
5
6
 
6
7
  # Load .env from the current working directory
7
8
  dotenv.load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))
8
9
 
9
10
  # Try loading from home directory if variables are still not set
10
- if not os.environ.get("LANGFUSE_PUBLIC_KEY") or not os.environ.get("LANGFUSE_SECRET_KEY"):
11
+ if not os.environ.get("LANGFUSE_PUBLIC_KEY") or not os.environ.get("LANGFUSE_SECRET_KEY") or not os.environ.get("LANGFUSE_HOST"):
11
12
  dotenv.load_dotenv(dotenv_path=os.path.expanduser("~/.env"))
12
13
 
13
14
  # Final check before exiting
@@ -16,6 +17,8 @@ if not os.environ.get("LANGFUSE_PUBLIC_KEY"):
16
17
  missing_vars.append("LANGFUSE_PUBLIC_KEY")
17
18
  if not os.environ.get("LANGFUSE_SECRET_KEY"):
18
19
  missing_vars.append("LANGFUSE_SECRET_KEY")
20
+ if not os.environ.get("LANGFUSE_HOST"):
21
+ missing_vars.append("LANGFUSE_HOST")
19
22
 
20
23
  if missing_vars:
21
24
  print(f"Error: {', '.join(missing_vars)} not found.")
@@ -28,17 +31,49 @@ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
28
31
  import json
29
32
 
30
33
  import dotenv
34
+ _DEBUG_=False
35
+ if _DEBUG_:
36
+ print(os.environ.get("LANGFUSE_PUBLIC_KEY"))
37
+ print(os.environ.get("LANGFUSE_SECRET_KEY"))
38
+ print(os.environ.get("LANGFUSE_HOST"))
31
39
 
32
- langfuse = Langfuse()
40
+ langfuse = Langfuse(
41
+ public_key=os.environ.get("LANGFUSE_PUBLIC_KEY"),
42
+ secret_key=os.environ.get("LANGFUSE_SECRET_KEY"),
43
+ host=os.environ.get("LANGFUSE_HOST")
44
+ )
33
45
 
34
- def list_traces(limit=100, output_dir="../output/traces"):
46
+ def open_trace_in_browser(trace_id):
47
+ base_url = os.environ.get("LANGFUSE_HOST")
48
+ project_id = os.environ.get("LANGFUSE_PROJECT_ID")
49
+ if not base_url or not project_id:
50
+ print("Missing LANGFUSE_HOST or LANGFUSE_PROJECT_ID")
51
+ return
52
+ full_url = f"{base_url}/project/{project_id}/traces/{trace_id}"
53
+ print(f"Opening {full_url}")
54
+ webbrowser.open(full_url)
55
+
56
+ def print_trace(trace, show_comments=False):
57
+ 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
+ print(f"<Input><CDATA[[\n{trace.input}\n]]></Input>")
59
+ print(f"<Output><CDATA[[\n{trace.output}\n]]></Output>")
60
+ print(f"<Metadata>{trace.metadata}</Metadata>")
61
+ if trace.scores:
62
+ print("<Scores>")
63
+ for score in trace.scores:
64
+ print(f"{score}")
65
+ print("</Scores>")
66
+ if show_comments and hasattr(trace, "comments"):
67
+ print(f"<Comments>\n{trace.comments}\n</Comments>")
68
+ print("</Trace>")
69
+
70
+ def print_traces(traces, show_comments=False):
71
+ for trace in traces.data:
72
+ print_trace(trace, show_comments)
73
+
74
+ def list_traces(limit=100, output_dir="../output/traces", show_comments=False):
35
75
  traces = langfuse.get_traces(limit=limit)
36
76
  os.makedirs(output_dir, exist_ok=True)
37
- for trace in traces.data:
38
- print(f"-----Trace ID: {trace.id}--Name: {trace.name}----------")
39
- print(f"<output>{trace.output}</output>")
40
- print(f"<Metadata>{trace.metadata}</Metadata>")
41
- print("---")
42
77
  return traces
43
78
 
44
79
  def list_traces_by_score(score_name, min_value=None, max_value=None, limit=100):
@@ -62,11 +97,16 @@ def add_score_to_a_trace(trace_id, generation_id, name, value, data_type="NUMERI
62
97
  comment=comment
63
98
  )
64
99
 
65
- def create_score(name, data_type, description=""):
66
- langfuse.create_score(
100
+ def create_score(name, data_type, description="", possible_values=None, min_value=None, max_value=None):
101
+ langfuse.score(
67
102
  name=name,
103
+ value="", # Provide a placeholder value
68
104
  data_type=data_type,
69
- description=description
105
+ description=description,
106
+ # For categorical:
107
+ **({"possible_values": possible_values} if data_type == "CATEGORICAL" and possible_values else {}),
108
+ # For numeric:
109
+ **({"min_value": min_value, "max_value": max_value} if data_type == "NUMERIC" and min_value is not None and max_value is not None else {})
70
110
  )
71
111
 
72
112
  def score_exists(name):
@@ -177,11 +177,11 @@ def main():
177
177
  if args.yes:
178
178
  pass
179
179
  else:
180
- generate_config_example()
180
+ initialize_config_file()
181
181
  return
182
182
 
183
183
  if not os.path.exists(olca_config_file):
184
- generate_config_example()
184
+ initialize_config_file()
185
185
  return
186
186
 
187
187
  config = load_config(olca_config_file)
@@ -269,6 +269,9 @@ def main():
269
269
  else:
270
270
  tools = load_tools( selected_tools, allow_dangerous_tools=True)
271
271
 
272
+ if human_switch:
273
+ user_input = user_input + " Dont forget to USE THE HUMAN-IN-THE-LOOP TOOL"
274
+ system_instructions= system_instructions + ". Use the human-in-the-loop tool"
272
275
 
273
276
  # Define the graph
274
277
  graph = create_react_agent(model, tools=tools)
@@ -297,7 +300,7 @@ def setup_required_directories(system_instructions, user_input):
297
300
  #We dont want to stop the program if it could not create the extra directories but we want to ensure common olca directories exist
298
301
  ensure_directories_exist()
299
302
 
300
- def generate_config_example():
303
+ def initialize_config_file():
301
304
  try:
302
305
  default_system_instructions = "You are interacting using the human tool addressing carefully what the user is asking."
303
306
  default_user_input = "Interact with me to write a story using the 3 act structure that we will save in ./story/ - Make sure you interact with me and wont quit."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: olca
3
- Version: 0.2.31
3
+ Version: 0.2.33
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
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "olca"
10
- version = "0.2.31"
10
+ version = "0.2.33"
11
11
 
12
12
  description = "A Python package for experimental usage of Langchain and Human-in-the-Loop"
13
13
  readme = "README.md"
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='olca',
5
- version = "0.2.31",
5
+ version = "0.2.33",
6
6
  author='Jean GUillaume ISabelle',
7
7
  author_email='jgi@jgwill.com',
8
8
  description='A Python package for experimenting with Langchain agent and interactivity in Terminal modalities.',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes