olca 0.2.63__py3-none-any.whl → 0.2.64__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_utils.py +96 -14
- olca/oiv.py +145 -0
- {olca-0.2.63.dist-info → olca-0.2.64.dist-info}/METADATA +1 -1
- {olca-0.2.63.dist-info → olca-0.2.64.dist-info}/RECORD +8 -7
- {olca-0.2.63.dist-info → olca-0.2.64.dist-info}/entry_points.txt +1 -0
- {olca-0.2.63.dist-info → olca-0.2.64.dist-info}/LICENSE +0 -0
- {olca-0.2.63.dist-info → olca-0.2.64.dist-info}/WHEEL +0 -0
- {olca-0.2.63.dist-info → olca-0.2.64.dist-info}/top_level.txt +0 -0
olca/fusewill_utils.py
CHANGED
|
@@ -123,7 +123,7 @@ def list_traces_by_score(score_name, min_value=None, max_value=None, limit=100):
|
|
|
123
123
|
return filtered_traces
|
|
124
124
|
|
|
125
125
|
def add_score_to_a_trace(trace_id, generation_id, name, value, data_type="NUMERIC", comment=""):
|
|
126
|
-
langfuse.score(
|
|
126
|
+
result_add_score_to_a_trace=langfuse.score(
|
|
127
127
|
trace_id=trace_id,
|
|
128
128
|
observation_id=generation_id,
|
|
129
129
|
name=name,
|
|
@@ -131,11 +131,16 @@ def add_score_to_a_trace(trace_id, generation_id, name, value, data_type="NUMERI
|
|
|
131
131
|
data_type=data_type,
|
|
132
132
|
comment=comment
|
|
133
133
|
)
|
|
134
|
+
return result_add_score_to_a_trace
|
|
134
135
|
|
|
135
136
|
def create_score(name, data_type, description="", possible_values=None, min_value=None, max_value=None):
|
|
136
|
-
|
|
137
|
+
placeholder_value = ""
|
|
138
|
+
if data_type.upper() == "BOOLEAN":
|
|
139
|
+
placeholder_value = "1"
|
|
140
|
+
|
|
141
|
+
resulting_score = langfuse.score(
|
|
137
142
|
name=name,
|
|
138
|
-
value=
|
|
143
|
+
value=placeholder_value,
|
|
139
144
|
data_type=data_type,
|
|
140
145
|
description=description,
|
|
141
146
|
# For categorical:
|
|
@@ -143,11 +148,17 @@ def create_score(name, data_type, description="", possible_values=None, min_valu
|
|
|
143
148
|
# For numeric:
|
|
144
149
|
**({"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 {})
|
|
145
150
|
)
|
|
151
|
+
return resulting_score
|
|
146
152
|
|
|
147
153
|
def score_exists(name):
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
"""
|
|
155
|
+
Check if a score with the given name exists by calling list_scores().
|
|
156
|
+
"""
|
|
157
|
+
scores = list_scores()
|
|
158
|
+
if not scores or scores.get('meta', {}).get('totalItems', 0) == 0:
|
|
159
|
+
return False
|
|
160
|
+
for sc in scores:
|
|
161
|
+
if sc.get("name") == name:
|
|
151
162
|
return True
|
|
152
163
|
return False
|
|
153
164
|
|
|
@@ -265,7 +276,7 @@ def fetch_all_traces(start_date=None, end_date=None):
|
|
|
265
276
|
|
|
266
277
|
def export_traces(format='json', output_path=None, start_date=None, end_date=None):
|
|
267
278
|
"""
|
|
268
|
-
Export traces
|
|
279
|
+
Export traces along with their full score details.
|
|
269
280
|
"""
|
|
270
281
|
try:
|
|
271
282
|
all_traces = fetch_all_traces(start_date=start_date, end_date=end_date)
|
|
@@ -277,9 +288,23 @@ def export_traces(format='json', output_path=None, start_date=None, end_date=Non
|
|
|
277
288
|
if output_dir and not os.path.exists(output_dir):
|
|
278
289
|
os.makedirs(output_dir)
|
|
279
290
|
|
|
291
|
+
all_scores=list_scores()
|
|
292
|
+
exported_data = []
|
|
293
|
+
for t in all_traces:
|
|
294
|
+
# fetch full score details
|
|
295
|
+
score_details = []
|
|
296
|
+
if t.scores:
|
|
297
|
+
for s_id in t.scores:
|
|
298
|
+
s_detail = get_score_by_id(s_id)
|
|
299
|
+
if s_detail:
|
|
300
|
+
score_details.append(s_detail)
|
|
301
|
+
t_dict = t.__dict__
|
|
302
|
+
t_dict["score_details"] = score_details
|
|
303
|
+
exported_data.append(t_dict)
|
|
304
|
+
|
|
280
305
|
if format == 'json':
|
|
281
306
|
with open(output_path, 'w') as f:
|
|
282
|
-
json.dump(
|
|
307
|
+
json.dump(exported_data, f, indent=2, default=str)
|
|
283
308
|
elif format == 'csv':
|
|
284
309
|
import csv
|
|
285
310
|
fieldnames = ['id', 'name', 'input', 'output', 'createdAt']
|
|
@@ -299,7 +324,7 @@ def export_traces(format='json', output_path=None, start_date=None, end_date=Non
|
|
|
299
324
|
# Sort traces by createdAt to ensure the oldest date is first
|
|
300
325
|
all_traces.sort(key=lambda x: x.createdAt)
|
|
301
326
|
first_trace_date = datetime.datetime.fromisoformat(all_traces[0].createdAt.replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M:%S')
|
|
302
|
-
last_trace_date = datetime.datetime.fromisoformat(all_traces[-1].
|
|
327
|
+
last_trace_date = datetime.datetime.fromisoformat(all_traces[-1].createdAt.replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M:%S')
|
|
303
328
|
print(f"Traces exported to {output_path}. Total traces exported: {len(all_traces)}")
|
|
304
329
|
print(f"Date range: {first_trace_date} to {last_trace_date}")
|
|
305
330
|
else:
|
|
@@ -307,9 +332,29 @@ def export_traces(format='json', output_path=None, start_date=None, end_date=Non
|
|
|
307
332
|
except Exception as e:
|
|
308
333
|
print(f"Error exporting traces: {e}")
|
|
309
334
|
|
|
335
|
+
def create_new_trace(name, input_text, output_text, session_id=None, metadata=None, timestamp=None):
|
|
336
|
+
"""
|
|
337
|
+
Creates a new trace with an optional timestamp.
|
|
338
|
+
"""
|
|
339
|
+
parsed_timestamp = None
|
|
340
|
+
if timestamp:
|
|
341
|
+
try:
|
|
342
|
+
parsed_timestamp = datetime.datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
|
|
343
|
+
except ValueError:
|
|
344
|
+
pass
|
|
345
|
+
trace_created=langfuse.trace(
|
|
346
|
+
name=name,
|
|
347
|
+
input=input_text,
|
|
348
|
+
output=output_text,
|
|
349
|
+
session_id=session_id,
|
|
350
|
+
metadata=metadata,
|
|
351
|
+
timestamp=parsed_timestamp
|
|
352
|
+
)
|
|
353
|
+
return trace_created
|
|
354
|
+
|
|
310
355
|
def import_traces(format='json', input_path=None):
|
|
311
356
|
"""
|
|
312
|
-
Import traces
|
|
357
|
+
Import traces. If any score doesn't exist, create it and attach it to the trace.
|
|
313
358
|
"""
|
|
314
359
|
if not input_path:
|
|
315
360
|
print("No input file provided for importing traces.")
|
|
@@ -327,14 +372,51 @@ def import_traces(format='json', input_path=None):
|
|
|
327
372
|
for row in reader:
|
|
328
373
|
data.append(row)
|
|
329
374
|
|
|
375
|
+
if isinstance(data, dict):
|
|
376
|
+
data = [data]
|
|
377
|
+
|
|
330
378
|
# Create new traces in Langfuse from data
|
|
331
379
|
for item in data:
|
|
332
|
-
|
|
380
|
+
trace_timestamp = item.get('timestamp') or item.get('createdAt')
|
|
381
|
+
new_trace = create_new_trace(
|
|
333
382
|
name=item.get('name', 'Imported Trace'),
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
383
|
+
input_text=item.get('input', ''),
|
|
384
|
+
output_text=item.get('output', ''),
|
|
385
|
+
session_id=item.get('session_id'),
|
|
386
|
+
metadata=item.get('metadata'),
|
|
387
|
+
timestamp=trace_timestamp
|
|
337
388
|
)
|
|
389
|
+
# handle imported scores
|
|
390
|
+
for s_detail in item.get("score_details", []):
|
|
391
|
+
score_name = s_detail["name"]
|
|
392
|
+
score_value = str(s_detail.get("value", "0"))
|
|
393
|
+
score_data_type = s_detail.get("dataType", "NUMERIC")
|
|
394
|
+
score_comment = s_detail.get("comment", "")
|
|
395
|
+
score_description = s_detail.get("description", "")
|
|
396
|
+
score_possible_values = s_detail.get("possible_values")
|
|
397
|
+
minimum_score_value = s_detail.get("min_value")
|
|
398
|
+
max_score_value = s_detail.get("max_value")
|
|
399
|
+
if not score_exists(score_name):
|
|
400
|
+
resulting_score=create_score(
|
|
401
|
+
name=score_name,
|
|
402
|
+
data_type=score_data_type,
|
|
403
|
+
description=score_description,
|
|
404
|
+
possible_values=score_possible_values,
|
|
405
|
+
min_value=minimum_score_value,
|
|
406
|
+
max_value=max_score_value
|
|
407
|
+
|
|
408
|
+
)
|
|
409
|
+
result_add_score_to_a_trace=add_score_to_a_trace(
|
|
410
|
+
trace_id=new_trace.id,
|
|
411
|
+
generation_id=None, # Replace as needed if your data includes observation IDs
|
|
412
|
+
name=score_name,
|
|
413
|
+
value=score_value,
|
|
414
|
+
data_type=score_data_type,
|
|
415
|
+
comment=score_comment
|
|
416
|
+
)
|
|
417
|
+
print(f"Added score {score_name} to trace {new_trace.id}")
|
|
418
|
+
print(result_add_score_to_a_trace)
|
|
419
|
+
|
|
338
420
|
print(f"Imported {len(data)} traces from {input_path}")
|
|
339
421
|
except Exception as e:
|
|
340
422
|
print(f"Error importing traces: {e}")
|
olca/oiv.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/bin/env python
|
|
2
|
+
#@STCGoal Create an agent callable with command line
|
|
3
|
+
#@STCIssue The original script was not callable from the command line.
|
|
4
|
+
|
|
5
|
+
from langchain import hub
|
|
6
|
+
from langchain.agents import AgentExecutor, create_react_agent
|
|
7
|
+
from langchain_community.agent_toolkits.load_tools import load_tools
|
|
8
|
+
from langchain_openai import ChatOpenAI
|
|
9
|
+
import argparse
|
|
10
|
+
import os
|
|
11
|
+
import json
|
|
12
|
+
import tlid
|
|
13
|
+
import warnings
|
|
14
|
+
|
|
15
|
+
warnings.filterwarnings("ignore", message="The function `loads` is in beta. It is actively being worked on, so the API may change.")
|
|
16
|
+
DEBUG_MODE=False
|
|
17
|
+
|
|
18
|
+
prompt=None
|
|
19
|
+
def _create_agent_tools(tool_name = "arxiv",temperature = 0.0,tool_hub_tag = "jgwill/react",chatbot_model = "gpt-4o-mini"):
|
|
20
|
+
global prompt
|
|
21
|
+
|
|
22
|
+
llm = ChatOpenAI(temperature=temperature,name=chatbot_model)
|
|
23
|
+
|
|
24
|
+
tools = load_tools(
|
|
25
|
+
[tool_name],
|
|
26
|
+
)
|
|
27
|
+
if DEBUG_MODE:
|
|
28
|
+
|
|
29
|
+
print("Tools:")
|
|
30
|
+
print(tools)
|
|
31
|
+
print("--------------")
|
|
32
|
+
prompt = hub.pull(tool_hub_tag)
|
|
33
|
+
|
|
34
|
+
if DEBUG_MODE:
|
|
35
|
+
print("prompt:")
|
|
36
|
+
print(prompt)
|
|
37
|
+
print("--------------")
|
|
38
|
+
|
|
39
|
+
agent = create_react_agent(llm, tools, prompt)
|
|
40
|
+
|
|
41
|
+
if DEBUG_MODE:
|
|
42
|
+
print("Agent:")
|
|
43
|
+
print(agent)
|
|
44
|
+
print("--------------")
|
|
45
|
+
return tools,agent
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def create_agent_executor(tools, agent) -> AgentExecutor:
|
|
49
|
+
return AgentExecutor(agent=agent, tools=tools, verbose=True,handle_parsing_errors=True)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# tools, agent=_create_agent_tools()
|
|
55
|
+
|
|
56
|
+
# agent_executor=create_agent_executor(tools, agent)
|
|
57
|
+
def ask_agent(input_request, agent_executor=None,tool_hub_tag = "jgwill/react",chatbot_model = "gpt-4o-mini"):
|
|
58
|
+
if agent_executor is None:
|
|
59
|
+
tools, agent = _create_agent_tools(tool_hub_tag=tool_hub_tag)
|
|
60
|
+
agent_executor = create_agent_executor(tools, agent)
|
|
61
|
+
|
|
62
|
+
resp = agent_executor.invoke(
|
|
63
|
+
{
|
|
64
|
+
"input": input_request,
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return resp
|
|
69
|
+
|
|
70
|
+
def serialize_response_to_json(resp):
|
|
71
|
+
return json.dumps(resp)
|
|
72
|
+
|
|
73
|
+
def serialize_response_to_json_file(resp, filename):
|
|
74
|
+
json_str=serialize_response_to_json(resp)
|
|
75
|
+
with open(filename, 'w') as f:
|
|
76
|
+
f.write(json_str)
|
|
77
|
+
|
|
78
|
+
def serialize_response_to_markdown(o):
|
|
79
|
+
output=o["output"]["output"]
|
|
80
|
+
string_md="# Output\n"
|
|
81
|
+
#string_md+=f"## Model\n{o['model']}\n"
|
|
82
|
+
#string_md+=f"## Prompt\n{o['prompt']['prompt']}\n"
|
|
83
|
+
string_md+=f"## Input\n{o['input']}\n"
|
|
84
|
+
string_md+=f"## Output\n{output}\n"
|
|
85
|
+
return string_md
|
|
86
|
+
|
|
87
|
+
def serialize_response_to_markdown_file(o, filename):
|
|
88
|
+
string_md=serialize_response_to_markdown(o)
|
|
89
|
+
with open(filename, 'w') as f:
|
|
90
|
+
f.write(string_md)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def main():
|
|
94
|
+
global prompt
|
|
95
|
+
args = parse_cli_arguments()
|
|
96
|
+
|
|
97
|
+
input_request = args.input
|
|
98
|
+
tool_hub_tag = "jgwill/react" if args.hub_tag is None else args.hub_tag
|
|
99
|
+
resp = ask_agent(input_request,tool_hub_tag=tool_hub_tag,chatbot_model=args.chatbot_model)
|
|
100
|
+
outdir=os.path.join(os.getcwd(),"output")
|
|
101
|
+
os.makedirs(outdir, exist_ok=True)
|
|
102
|
+
out_filename = f"{args.prefix}output-{tlid.get_minutes()}.json"
|
|
103
|
+
outfile=os.path.join(outdir,out_filename)
|
|
104
|
+
o={}
|
|
105
|
+
prompt_dict = {
|
|
106
|
+
"prompt": str(prompt)
|
|
107
|
+
}
|
|
108
|
+
o["model"]=args.chatbot_model
|
|
109
|
+
o["prompt"]=prompt_dict
|
|
110
|
+
o["input"]=input_request
|
|
111
|
+
o["output"]=resp
|
|
112
|
+
serialize_response_to_json_file(o, outfile)
|
|
113
|
+
serialize_response_to_markdown_file(o, outfile.replace(".json",".md"))
|
|
114
|
+
VERBOSE_RESULT=False
|
|
115
|
+
if VERBOSE_RESULT:
|
|
116
|
+
print("==================================")
|
|
117
|
+
print(input_request)
|
|
118
|
+
print("============RESPONSE============")
|
|
119
|
+
print(resp)
|
|
120
|
+
print("==================================")
|
|
121
|
+
print("=============INPUT Request=====================")
|
|
122
|
+
print(input_request)
|
|
123
|
+
print("==================================")
|
|
124
|
+
print("============OUTPUT============")
|
|
125
|
+
output=resp["output"]
|
|
126
|
+
print(output)
|
|
127
|
+
|
|
128
|
+
def parse_cli_arguments():
|
|
129
|
+
parser = argparse.ArgumentParser(description='Process Input request for pattern search.')
|
|
130
|
+
parser.add_argument('-I','--input', type=str,
|
|
131
|
+
help='an input request for the searched article')
|
|
132
|
+
##--hub_tag
|
|
133
|
+
parser.add_argument('-H','-ht','--hub_tag', type=str,
|
|
134
|
+
help='The hub tag for the process',default="jgwill/react")
|
|
135
|
+
#--chatbot_model
|
|
136
|
+
parser.add_argument('-M','-m','--chatbot_model', type=str,
|
|
137
|
+
help='a chatbot model for the processing',default="gpt-4o-mini")
|
|
138
|
+
#--prefix
|
|
139
|
+
parser.add_argument('-P','-p','--prefix', type=str,
|
|
140
|
+
help='a file prefix for output',default="arxiv-")
|
|
141
|
+
args = parser.parse_args()
|
|
142
|
+
return args
|
|
143
|
+
|
|
144
|
+
if __name__ == "__main__":
|
|
145
|
+
main()
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
|
|
2
2
|
olca/fusewill_cli.py,sha256=7etgdpM64-jXGLlALG7PtwICAzoLKYGMBRvHf5nMLic,17119
|
|
3
|
-
olca/fusewill_utils.py,sha256=
|
|
3
|
+
olca/fusewill_utils.py,sha256=sNCe4LhpSaEOY5olMxW1nTv7CKiT__dc2lGomelE6mY,18207
|
|
4
|
+
olca/oiv.py,sha256=sROQHF_WWfvfzLB3SF7nWXdsfHc-91cs6VMO0CWctJc,4613
|
|
4
5
|
olca/olcacli.py,sha256=oftilrp9v0QOV5tJeb6o8nwO54gjjlwWVfDU5JpoXJc,10758
|
|
5
6
|
olca/olcahelper.py,sha256=s9KwEYAJCbnKSXIsj5HCL-OHxkSsmL08ZBgoluxmP1s,3828
|
|
6
7
|
olca/prompts.py,sha256=q7lvDZ8n_K6ea2nu3K5R2fgBgQYrCIEjh0cA9fUlMFI,3697
|
|
7
8
|
olca/tracing.py,sha256=GSuXIKmIMQ9V2gLkKcin142Z2QpyS6obsnj8Tf-1zHc,1621
|
|
8
9
|
olca/utils.py,sha256=zM94HDMDYF95Yd9ubeOK6vuepbQN4kDFh0rTvaVFagI,912
|
|
9
|
-
olca-0.2.
|
|
10
|
-
olca-0.2.
|
|
11
|
-
olca-0.2.
|
|
12
|
-
olca-0.2.
|
|
13
|
-
olca-0.2.
|
|
14
|
-
olca-0.2.
|
|
10
|
+
olca-0.2.64.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
|
|
11
|
+
olca-0.2.64.dist-info/METADATA,sha256=OPT9xkKpp-1Magcty7csGAuYWn-E-n0awVya_S3ooic,25808
|
|
12
|
+
olca-0.2.64.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
13
|
+
olca-0.2.64.dist-info/entry_points.txt,sha256=W2UkinpMZYsCLH54must9ahwbzCRl-rekcZ7rL5u3wA,123
|
|
14
|
+
olca-0.2.64.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
|
|
15
|
+
olca-0.2.64.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|