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 +22 -19
- olca/fusewill_utils.py +23 -5
- olca/olcacli.py +16 -17
- olca/tracing.py +38 -0
- {olca-0.2.34.dist-info → olca-0.2.36.dist-info}/METADATA +1 -1
- olca-0.2.36.dist-info/RECORD +11 -0
- olca-0.2.34.dist-info/RECORD +0 -10
- {olca-0.2.34.dist-info → olca-0.2.36.dist-info}/LICENSE +0 -0
- {olca-0.2.34.dist-info → olca-0.2.36.dist-info}/WHEEL +0 -0
- {olca-0.2.34.dist-info → olca-0.2.36.dist-info}/entry_points.txt +0 -0
- {olca-0.2.34.dist-info → olca-0.2.36.dist-info}/top_level.txt +0 -0
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
|
-
|
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
|
65
|
-
|
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
|
85
|
-
|
86
|
-
|
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
|
-
#
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
-
|
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
|
@@ -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,,
|
olca-0.2.34.dist-info/RECORD
DELETED
@@ -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
|
File without changes
|
File without changes
|