olca 0.2.60__py3-none-any.whl → 0.2.61__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
olca/fusewill_cli.py CHANGED
@@ -120,6 +120,37 @@ def main():
120
120
  parser_import.add_argument('--format', choices=['json','csv'], default='json', help='Import format')
121
121
  parser_import.add_argument('--input', type=str, required=True, help='Input file path to read from')
122
122
 
123
+ # list_sessions command
124
+ parser_list_sessions = subparsers.add_parser('list_sessions', help='List sessions', aliases=['lss'])
125
+ parser_list_sessions.add_argument('-L','--limit', type=int, default=100, help='Number of sessions to fetch')
126
+ parser_list_sessions.add_argument('--start_date', type=str, help='Start date in ISO format (e.g., 2024-01-01)')
127
+ parser_list_sessions.add_argument('--end_date', type=str, help='End date in ISO format (e.g., 2024-12-31)')
128
+ parser_list_sessions.add_argument('--format', choices=['json','csv'], default='json', help='Output format (json or csv)')
129
+ parser_list_sessions.add_argument('-o','--output', type=str, help='Optional output file path')
130
+
131
+ # get_session command
132
+ parser_get_session = subparsers.add_parser('get_session', help='Get a session by ID', aliases=['gsess'])
133
+ parser_get_session.add_argument('session_id', help='Session ID')
134
+ parser_get_session.add_argument('-o','--output', type=str, help='Output file path (JSON or CSV)')
135
+
136
+ # get_media command
137
+ parser_get_media = subparsers.add_parser('get_media', help='Retrieve media details')
138
+ parser_get_media.add_argument('media_id', help='Media ID')
139
+
140
+ # get_upload_url command
141
+ parser_upload_url = subparsers.add_parser('get_upload_url', help='Get a presigned upload URL')
142
+ parser_upload_url.add_argument('trace_id', help='Trace ID')
143
+ parser_upload_url.add_argument('--content_type', required=True, help='Content-Type of the media')
144
+ parser_upload_url.add_argument('--content_length', type=int, required=True, help='Size of the media in bytes')
145
+
146
+ # get_daily_metrics command
147
+ parser_daily_metrics = subparsers.add_parser('get_daily_metrics', help='Fetch daily metrics', aliases=['gdm'])
148
+ parser_daily_metrics.add_argument('--trace_name', type=str, help='Optional trace name filter')
149
+ parser_daily_metrics.add_argument('--user_id', type=str, help='Optional user ID filter')
150
+ parser_daily_metrics.add_argument('--tags', nargs='*', help='Optional tags for filtering')
151
+ parser_daily_metrics.add_argument('--from_timestamp', type=str, help='Start date in ISO format')
152
+ parser_daily_metrics.add_argument('--to_timestamp', type=str, help='End date in ISO format')
153
+
123
154
  args = parser.parse_args()
124
155
 
125
156
  if args.command == 'list_traces' or args.command == 'lt':
@@ -241,6 +272,71 @@ def main():
241
272
  fu.export_traces(format=args.format, output_path=output_path, start_date=args.start_date, end_date=args.end_date)
242
273
  elif args.command == 'import_traces' or args.command == 'it':
243
274
  fu.import_traces(format=args.format, input_path=args.input)
275
+ elif args.command == 'list_sessions' or args.command == 'lss':
276
+ sessions = fu.list_sessions(
277
+ limit=args.limit,
278
+ start_date=args.start_date,
279
+ end_date=args.end_date
280
+ )
281
+
282
+ if not sessions:
283
+ print("No sessions found.")
284
+ else:
285
+ if not args.output:
286
+ # Print to standard output
287
+ for s in sessions:
288
+ print(s)
289
+ else:
290
+ # Ensure output file extension matches --format
291
+ output_path = args.output
292
+ if not output_path.endswith(f".{args.format}"):
293
+ output_path += f".{args.format}"
294
+
295
+ if args.format == 'csv':
296
+ import csv
297
+ with open(output_path, 'w', newline='') as f:
298
+ writer = csv.DictWriter(f, fieldnames=sessions[0].keys())
299
+ writer.writeheader()
300
+ for s in sessions:
301
+ writer.writerow(s)
302
+ else: # default to JSON
303
+ import json
304
+ with open(output_path, 'w') as f:
305
+ json.dump(sessions, f, indent=2)
306
+
307
+ print(f"Sessions written to {os.path.realpath(output_path)}")
308
+ elif args.command == 'get_session' or args.command == 'gsess':
309
+ session = fu.get_session(args.session_id)
310
+ if session:
311
+ if args.output:
312
+ if args.output.endswith('.csv'):
313
+ import csv
314
+ with open(args.output, 'w', newline='') as f:
315
+ writer = csv.DictWriter(f, fieldnames=session.keys())
316
+ writer.writeheader()
317
+ writer.writerow(session)
318
+ print(f"Session written to {os.path.realpath(args.output)}")
319
+ else:
320
+ import json
321
+ with open(args.output, 'w') as f:
322
+ json.dump(session, f, indent=2)
323
+ print(f"Session written to {os.path.realpath(args.output)}")
324
+ else:
325
+ print(session)
326
+ else:
327
+ print(f"No session found for ID {args.session_id}")
328
+ elif args.command == 'get_media':
329
+ fu.get_media(args.media_id)
330
+ elif args.command == 'get_upload_url':
331
+ fu.get_upload_url(args.trace_id, args.content_type, args.content_length)
332
+ elif args.command == 'get_daily_metrics' or args.command == 'gdm':
333
+ fu.get_daily_metrics(
334
+ trace_name=args.trace_name,
335
+ user_id=args.user_id,
336
+ tags=args.tags,
337
+ from_timestamp=args.from_timestamp,
338
+ to_timestamp=args.to_timestamp
339
+ )
244
340
  else:
245
341
  parser.print_help()
246
342
  exit(1)
olca/fusewill_utils.py CHANGED
@@ -299,7 +299,7 @@ def export_traces(format='json', output_path=None, start_date=None, end_date=Non
299
299
  # Sort traces by createdAt to ensure the oldest date is first
300
300
  all_traces.sort(key=lambda x: x.createdAt)
301
301
  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].createdAt.replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M:%S')
302
+ last_trace_date = datetime.datetime.fromisoformat(all_traces[-1].CreatedAt.replace('Z', '+00:00')).strftime('%Y-%m-%d %H:%M:%S')
303
303
  print(f"Traces exported to {output_path}. Total traces exported: {len(all_traces)}")
304
304
  print(f"Date range: {first_trace_date} to {last_trace_date}")
305
305
  else:
@@ -337,4 +337,81 @@ def import_traces(format='json', input_path=None):
337
337
  )
338
338
  print(f"Imported {len(data)} traces from {input_path}")
339
339
  except Exception as e:
340
- print(f"Error importing traces: {e}")
340
+ print(f"Error importing traces: {e}")
341
+
342
+ def list_sessions(limit=100, start_date=None, end_date=None):
343
+ """
344
+ List all sessions with optional date filtering.
345
+ Retrieves multiple pages so we don't miss older sessions.
346
+ """
347
+ base_url = os.environ.get("LANGFUSE_HOST")
348
+ public_key = os.environ.get("LANGFUSE_PUBLIC_KEY")
349
+ secret_key = os.environ.get("LANGFUSE_SECRET_KEY")
350
+ url = f"{base_url}/api/public/sessions"
351
+ sessions = []
352
+ page = 1
353
+ while True:
354
+ params = {
355
+ "page": page,
356
+ "limit": limit
357
+ }
358
+ if start_date:
359
+ params["fromTimestamp"] = datetime.datetime.fromisoformat(start_date).isoformat() + 'Z'
360
+ if end_date:
361
+ params["toTimestamp"] = datetime.datetime.fromisoformat(end_date).isoformat() + 'Z'
362
+
363
+ try:
364
+ response = requests.get(url, auth=(public_key, secret_key), params=params)
365
+ response.raise_for_status()
366
+ data = response.json()
367
+ except Exception as e:
368
+ print(f"Error retrieving sessions: {e}")
369
+ break
370
+
371
+ if "data" not in data or len(data["data"]) == 0:
372
+ break
373
+
374
+ sessions.extend(data["data"])
375
+ if len(data["data"]) < limit:
376
+ break
377
+ page += 1
378
+
379
+ return sessions
380
+
381
+ def get_session(session_id):
382
+ """
383
+ Get details of a specific session including its traces.
384
+ """
385
+ base_url = os.environ.get("LANGFUSE_HOST")
386
+ public_key = os.environ.get("LANGFUSE_PUBLIC_KEY")
387
+ secret_key = os.environ.get("LANGFUSE_SECRET_KEY")
388
+ url = f"{base_url}/api/public/sessions/{session_id}"
389
+
390
+ try:
391
+ response = requests.get(url, auth=(public_key, secret_key))
392
+ response.raise_for_status()
393
+ return response.json()
394
+ except Exception as e:
395
+ print(f"Error retrieving session {session_id}: {e}")
396
+ return None
397
+
398
+ def get_upload_url(trace_id, content_type, content_length):
399
+ """
400
+ Get a presigned URL for media upload.
401
+ """
402
+ # TODO: Implement API call to POST /media
403
+ pass
404
+
405
+ def get_media(media_id):
406
+ """
407
+ Retrieve media record details.
408
+ """
409
+ # TODO: Implement API call to GET /media/{mediaId}
410
+ pass
411
+
412
+ def get_daily_metrics(trace_name=None, user_id=None, tags=None, from_timestamp=None, to_timestamp=None):
413
+ """
414
+ Get daily metrics with optional filtering.
415
+ """
416
+ # TODO: Implement API call to GET /metrics/daily with query params
417
+ pass
olca/olcacli.py CHANGED
@@ -1,6 +1,7 @@
1
1
  #%%
2
2
  import os
3
- from click import prompt
3
+ import sys
4
+ sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
4
5
  import dotenv
5
6
  from langchain import hub
6
7
  import argparse
@@ -153,6 +154,18 @@ def _parse_args():
153
154
  parser.add_argument("-y", "--yes", action="store_true", help="Accept the new file olca.yml")
154
155
  return parser.parse_args()
155
156
 
157
+ def parse_model_uri(uri: str):
158
+ # Example: "ollama://llama2@localhost"
159
+ if "://" not in uri:
160
+ return "openai", uri, None # default provider is openai
161
+ provider, rest = uri.split("://", 1)
162
+ host = None
163
+ if "@" in rest:
164
+ base_model, host = rest.split("@", 1)
165
+ else:
166
+ base_model = rest
167
+ return provider, base_model, host
168
+
156
169
  def main():
157
170
  args = _parse_args()
158
171
  olca_config_file = 'olca.yml'
@@ -217,20 +230,33 @@ def main():
217
230
  system_instructions = config.get('system_instructions', '')
218
231
  user_input = config.get('user_input', '')
219
232
  default_model_id = "gpt-4o-mini"
220
- model_name = config.get('model_name', default_model_id)
221
233
  recursion_limit = config.get('recursion_limit', 15)
222
234
  disable_system_append = _parse_args().disable_system_append
223
-
224
235
  # Use the system_instructions and user_input in your CLI logic
236
+ model_name = config.get('model_name', default_model_id)
237
+ provider, base_model, host = parse_model_uri(model_name)
238
+
239
+ if provider == "ollama":
240
+ from langchain_ollama import OllamaLLM
241
+ model = OllamaLLM(model=base_model, base_url=host if host else None)
242
+ elif provider == "openai":
243
+ from langchain_openai import ChatOpenAI
244
+ model = ChatOpenAI(model=base_model, temperature=0)
245
+ else:
246
+ # default fallback
247
+ from langchain_openai import ChatOpenAI
248
+ model = ChatOpenAI(model=model_name, temperature=0)
249
+
225
250
  print("System Instructions:", system_instructions)
226
251
  print("User Input:", user_input)
227
- print("Model Name:", model_name)
228
252
  print("Recursion Limit:", recursion_limit)
229
253
  print("Trace:", tracing_enabled)
254
+ print("Model Name:", model_name)
230
255
 
231
- model = ChatOpenAI(model=model_name, temperature=0)
232
256
  selected_tools = ["terminal"]
233
257
 
258
+ disable_system_append = _parse_args().disable_system_append
259
+
234
260
  human_switch = args.human
235
261
  #look in olca_config.yaml for human: true
236
262
  if "human" in config:
@@ -240,6 +266,7 @@ def main():
240
266
  selected_tools.append("human")
241
267
 
242
268
  if args.math:
269
+ from langchain_openai import OpenAI
243
270
  math_llm = OpenAI()
244
271
  selected_tools.append("llm-math")
245
272
  if human_switch:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: olca
3
- Version: 0.2.60
3
+ Version: 0.2.61
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
@@ -361,11 +361,13 @@ Requires-Dist: requests
361
361
  Requires-Dist: markdown
362
362
  Requires-Dist: langchain
363
363
  Requires-Dist: langchain-openai
364
+ Requires-Dist: langchain-ollama
364
365
  Requires-Dist: langchain-experimental
365
366
  Requires-Dist: click
366
367
  Requires-Dist: langgraph
367
368
  Requires-Dist: langfuse
368
369
  Requires-Dist: pytz
370
+ Requires-Dist: google.generativeai
369
371
 
370
372
  # oLCa
371
373
 
@@ -0,0 +1,14 @@
1
+ olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
2
+ olca/fusewill_cli.py,sha256=7etgdpM64-jXGLlALG7PtwICAzoLKYGMBRvHf5nMLic,17119
3
+ olca/fusewill_utils.py,sha256=LEKEDboyCm14_yvypE6lTed9j_uJN4K8vVdvYi6JoJs,14903
4
+ olca/olcacli.py,sha256=w9yo2BSX9b2t6_rljAmYJTbyLCQ6LRfXqLxi8sWb6FQ,11181
5
+ olca/olcahelper.py,sha256=WdN6-K-N7-HnB9L_px6TsDKWiTXIusZM2I1d0GNQnFs,3322
6
+ olca/prompts.py,sha256=q7lvDZ8n_K6ea2nu3K5R2fgBgQYrCIEjh0cA9fUlMFI,3697
7
+ olca/tracing.py,sha256=GSuXIKmIMQ9V2gLkKcin142Z2QpyS6obsnj8Tf-1zHc,1621
8
+ olca/utils.py,sha256=zM94HDMDYF95Yd9ubeOK6vuepbQN4kDFh0rTvaVFagI,912
9
+ olca-0.2.61.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
10
+ olca-0.2.61.dist-info/METADATA,sha256=ABqdy467xpsMFu7jwU1Ac74htUamHpWleksX4nwsWFY,25398
11
+ olca-0.2.61.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
12
+ olca-0.2.61.dist-info/entry_points.txt,sha256=AhP5FMv6vnOq9C76V_vxRVIO50smnZXG4RIY47oD2_U,103
13
+ olca-0.2.61.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
14
+ olca-0.2.61.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- olca/__init__.py,sha256=3QyLLAys_KiiDIe-cfO_7QyY7di_qCaCS-sVziW2BOw,23
2
- olca/fusewill_cli.py,sha256=muFBmWm1HPWrcpEGLEH4YMInEw9fIrWxb1aO5yr07n8,12156
3
- olca/fusewill_utils.py,sha256=BnNovYOzfNodhO-CoJYTX2uNonFeV1e88YwZYO1B-UM,12487
4
- olca/olcacli.py,sha256=NGYxZw_kYI9y9DmXu5dk02S_UOqVw05FWlzQ2gjXv00,10214
5
- olca/olcahelper.py,sha256=WdN6-K-N7-HnB9L_px6TsDKWiTXIusZM2I1d0GNQnFs,3322
6
- olca/prompts.py,sha256=q7lvDZ8n_K6ea2nu3K5R2fgBgQYrCIEjh0cA9fUlMFI,3697
7
- olca/tracing.py,sha256=GSuXIKmIMQ9V2gLkKcin142Z2QpyS6obsnj8Tf-1zHc,1621
8
- olca/utils.py,sha256=zM94HDMDYF95Yd9ubeOK6vuepbQN4kDFh0rTvaVFagI,912
9
- olca-0.2.60.dist-info/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
10
- olca-0.2.60.dist-info/METADATA,sha256=lBFrltW-p-YUMASGo12IOTjPJ1XLD2ulRRG_NNx2vH0,25331
11
- olca-0.2.60.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
12
- olca-0.2.60.dist-info/entry_points.txt,sha256=AhP5FMv6vnOq9C76V_vxRVIO50smnZXG4RIY47oD2_U,103
13
- olca-0.2.60.dist-info/top_level.txt,sha256=bGDtAReS-xlS0F6MM-DyD0IQUqjNdWmgemnM3vNtrpI,5
14
- olca-0.2.60.dist-info/RECORD,,
File without changes
File without changes