olca 0.2.60__tar.gz → 0.2.62__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.60
3
+ Version: 0.2.62
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
 
@@ -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)
@@ -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
@@ -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
@@ -55,7 +56,7 @@ dotenv.load_dotenv()
55
56
  # First we initialize the model we want to use.
56
57
  from json import load
57
58
  from langchain_openai import ChatOpenAI,OpenAI
58
- from langchain.agents import AgentExecutor, create_react_agent
59
+ #from langchain.agents import AgentExecutor, create_react_agent
59
60
 
60
61
  from langchain_community.agent_toolkits.load_tools import load_tools
61
62
 
@@ -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,34 @@ 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
+
243
+ elif provider == "openai":
244
+ from langchain_openai import ChatOpenAI
245
+ model = ChatOpenAI(model=base_model, temperature=0)
246
+ else:
247
+ # default fallback
248
+ from langchain_openai import ChatOpenAI
249
+ model = ChatOpenAI(model=model_name, temperature=0)
250
+
225
251
  print("System Instructions:", system_instructions)
226
252
  print("User Input:", user_input)
227
- print("Model Name:", model_name)
228
253
  print("Recursion Limit:", recursion_limit)
229
254
  print("Trace:", tracing_enabled)
255
+ print("Model Name:", model_name)
230
256
 
231
- model = ChatOpenAI(model=model_name, temperature=0)
232
257
  selected_tools = ["terminal"]
233
258
 
259
+ disable_system_append = _parse_args().disable_system_append
260
+
234
261
  human_switch = args.human
235
262
  #look in olca_config.yaml for human: true
236
263
  if "human" in config:
@@ -240,6 +267,7 @@ def main():
240
267
  selected_tools.append("human")
241
268
 
242
269
  if args.math:
270
+ from langchain_openai import OpenAI
243
271
  math_llm = OpenAI()
244
272
  selected_tools.append("llm-math")
245
273
  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.62
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
 
@@ -8,8 +8,10 @@ requests
8
8
  markdown
9
9
  langchain
10
10
  langchain-openai
11
+ langchain-ollama
11
12
  langchain-experimental
12
13
  click
13
14
  langgraph
14
15
  langfuse
15
16
  pytz
17
+ google.generativeai
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "olca"
10
- version = "0.2.60"
10
+ version = "0.2.62"
11
11
 
12
12
  description = "A Python package for experimental usage of Langchain and Human-in-the-Loop"
13
13
  readme = "README.md"
@@ -27,11 +27,13 @@ dependencies = [
27
27
  "markdown",
28
28
  "langchain",
29
29
  "langchain-openai",
30
+ "langchain-ollama",
30
31
  "langchain-experimental",
31
32
  "click",
32
33
  "langgraph",
33
34
  "langfuse",
34
35
  "pytz",
36
+ "google.generativeai",
35
37
  ]
36
38
  classifiers = [
37
39
  "Programming Language :: Python :: 3",
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='olca',
5
- version = "0.2.60",
5
+ version = "0.2.62",
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
File without changes
File without changes
File without changes