lollms-client 0.32.1__py3-none-any.whl → 1.0.0__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.

Potentially problematic release.


This version of lollms-client might be problematic. Click here for more details.

Files changed (73) hide show
  1. lollms_client/__init__.py +1 -1
  2. lollms_client/llm_bindings/azure_openai/__init__.py +6 -10
  3. lollms_client/llm_bindings/claude/__init__.py +4 -7
  4. lollms_client/llm_bindings/gemini/__init__.py +3 -7
  5. lollms_client/llm_bindings/grok/__init__.py +3 -7
  6. lollms_client/llm_bindings/groq/__init__.py +4 -7
  7. lollms_client/llm_bindings/hugging_face_inference_api/__init__.py +4 -6
  8. lollms_client/llm_bindings/litellm/__init__.py +15 -6
  9. lollms_client/llm_bindings/llamacpp/__init__.py +214 -388
  10. lollms_client/llm_bindings/lollms/__init__.py +24 -14
  11. lollms_client/llm_bindings/lollms_webui/__init__.py +6 -12
  12. lollms_client/llm_bindings/mistral/__init__.py +58 -29
  13. lollms_client/llm_bindings/ollama/__init__.py +6 -11
  14. lollms_client/llm_bindings/open_router/__init__.py +45 -14
  15. lollms_client/llm_bindings/openai/__init__.py +7 -14
  16. lollms_client/llm_bindings/openllm/__init__.py +12 -12
  17. lollms_client/llm_bindings/pythonllamacpp/__init__.py +1 -1
  18. lollms_client/llm_bindings/tensor_rt/__init__.py +8 -13
  19. lollms_client/llm_bindings/transformers/__init__.py +14 -6
  20. lollms_client/llm_bindings/vllm/__init__.py +16 -12
  21. lollms_client/lollms_core.py +296 -487
  22. lollms_client/lollms_discussion.py +436 -78
  23. lollms_client/lollms_llm_binding.py +223 -11
  24. lollms_client/lollms_mcp_binding.py +33 -2
  25. lollms_client/mcp_bindings/local_mcp/__init__.py +3 -2
  26. lollms_client/mcp_bindings/remote_mcp/__init__.py +6 -5
  27. lollms_client/mcp_bindings/standard_mcp/__init__.py +3 -5
  28. lollms_client/stt_bindings/lollms/__init__.py +6 -8
  29. lollms_client/stt_bindings/whisper/__init__.py +2 -4
  30. lollms_client/stt_bindings/whispercpp/__init__.py +15 -16
  31. lollms_client/tti_bindings/dalle/__init__.py +29 -28
  32. lollms_client/tti_bindings/diffusers/__init__.py +25 -21
  33. lollms_client/tti_bindings/gemini/__init__.py +215 -0
  34. lollms_client/tti_bindings/lollms/__init__.py +8 -9
  35. lollms_client-1.0.0.dist-info/METADATA +1214 -0
  36. lollms_client-1.0.0.dist-info/RECORD +69 -0
  37. {lollms_client-0.32.1.dist-info → lollms_client-1.0.0.dist-info}/top_level.txt +0 -2
  38. examples/article_summary/article_summary.py +0 -58
  39. examples/console_discussion/console_app.py +0 -266
  40. examples/console_discussion.py +0 -448
  41. examples/deep_analyze/deep_analyse.py +0 -30
  42. examples/deep_analyze/deep_analyze_multiple_files.py +0 -32
  43. examples/function_calling_with_local_custom_mcp.py +0 -250
  44. examples/generate_a_benchmark_for_safe_store.py +0 -89
  45. examples/generate_and_speak/generate_and_speak.py +0 -251
  46. examples/generate_game_sfx/generate_game_fx.py +0 -240
  47. examples/generate_text_with_multihop_rag_example.py +0 -210
  48. examples/gradio_chat_app.py +0 -228
  49. examples/gradio_lollms_chat.py +0 -259
  50. examples/internet_search_with_rag.py +0 -226
  51. examples/lollms_chat/calculator.py +0 -59
  52. examples/lollms_chat/derivative.py +0 -48
  53. examples/lollms_chat/test_openai_compatible_with_lollms_chat.py +0 -12
  54. examples/lollms_discussions_test.py +0 -155
  55. examples/mcp_examples/external_mcp.py +0 -267
  56. examples/mcp_examples/local_mcp.py +0 -171
  57. examples/mcp_examples/openai_mcp.py +0 -203
  58. examples/mcp_examples/run_remote_mcp_example_v2.py +0 -290
  59. examples/mcp_examples/run_standard_mcp_example.py +0 -204
  60. examples/simple_text_gen_test.py +0 -173
  61. examples/simple_text_gen_with_image_test.py +0 -178
  62. examples/test_local_models/local_chat.py +0 -9
  63. examples/text_2_audio.py +0 -77
  64. examples/text_2_image.py +0 -144
  65. examples/text_2_image_diffusers.py +0 -274
  66. examples/text_and_image_2_audio.py +0 -59
  67. examples/text_gen.py +0 -30
  68. examples/text_gen_system_prompt.py +0 -29
  69. lollms_client-0.32.1.dist-info/METADATA +0 -854
  70. lollms_client-0.32.1.dist-info/RECORD +0 -101
  71. test/test_lollms_discussion.py +0 -368
  72. {lollms_client-0.32.1.dist-info → lollms_client-1.0.0.dist-info}/WHEEL +0 -0
  73. {lollms_client-0.32.1.dist-info → lollms_client-1.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,240 +0,0 @@
1
- # lollms_client/examples/game_sfx_generation/generate_game_sfx.py
2
- from pathlib import Path
3
- import time
4
- import argparse # For command-line arguments
5
-
6
- # Ensure pygame is installed for this example
7
- try:
8
- import pipmaster as pm
9
- pm.ensure_packages(["pygame"])
10
- import pygame
11
- PYGAME_AVAILABLE = True
12
- except ImportError:
13
- print("Pygame not found or pipmaster failed. Please install it manually: pip install pygame")
14
- PYGAME_AVAILABLE = False
15
- except Exception as e:
16
- print(f"Could not ensure pygame: {e}")
17
- PYGAME_AVAILABLE = False
18
-
19
-
20
- from lollms_client import LollmsClient # Removed LollmsDiscussion, LollmsMessage as not used
21
- from ascii_colors import ASCIIColors, trace_exception
22
-
23
- # --- Configuration ---
24
- # Output directory for generated sound effects
25
- SFX_OUTPUT_DIR = Path(__file__).parent / "sfx_output"
26
- SFX_OUTPUT_DIR.mkdir(exist_ok=True)
27
-
28
- # Sound effect descriptions. Note: 'duration' is more relevant for audiocraft.
29
- # Bark's duration is more implicit based on prompt content.
30
- SOUND_EFFECTS_TO_GENERATE = [
31
- {
32
- "filename": "sfx_crunch",
33
- "prompt": "Sound effect of a single, sharp, dry crunch, like stepping on a crisp autumn leaf or a piece of dry wood breaking.",
34
- "duration": 1, # audiocraft specific
35
- "bark_params": {"fine_temperature": 0.4, "coarse_temperature": 0.6} # Example bark specific
36
- },
37
- {
38
- "filename": "sfx_death_electronic",
39
- "prompt": "Short, impactful electronic death sound effect for a video game character, like a quick digital zap or a brief power-down sound.",
40
- "duration": 1.5,
41
- "bark_params": {"voice_preset": None} # Try without preset for more raw SFX
42
- },
43
- {
44
- "filename": "sfx_powerup_positive",
45
- "prompt": "Bright, positive, short power-up collection sound effect, like a magical chime, a sparkling shimmer, or an uplifting notification. [SFX]",
46
- "duration": 1.5
47
- },
48
- {
49
- "filename": "sfx_laser_shot",
50
- "prompt": "Sound effect of a futuristic laser gun firing a single shot, a quick 'pew' sound. [SFX: laser pew]",
51
- "duration": 0.5
52
- },
53
- {
54
- "filename": "sfx_coin_collect",
55
- "prompt": "Classic video game coin collection sound effect, a short, metallic, cheerful 'ding' or 'jingle'. [SFX: coin]",
56
- "duration": 0.7
57
- }
58
- ]
59
-
60
- def generate_sfx(lollms_client: LollmsClient, sfx_info: dict) -> Path | None:
61
- """Generates a single sound effect using the LollmsClient's TTM binding."""
62
- filename_stem = sfx_info["filename"]
63
- prompt = sfx_info["prompt"]
64
-
65
- # Default output format
66
- output_format = "wav" # WAV is generally best for SFX in pygame
67
- output_path = SFX_OUTPUT_DIR / f"{filename_stem}_{lollms_client.ttm.binding_name}.{output_format}" # Add binding name to filename
68
-
69
- ASCIIColors.cyan(f"\nGenerating SFX using '{lollms_client.ttm.binding_name}': '{filename_stem}'")
70
- ASCIIColors.info(f"Prompt: '{prompt[:60]}...'")
71
-
72
-
73
- if not lollms_client.ttm:
74
- ASCIIColors.error("TTM (Text-to-Music/Sound) binding is not available in LollmsClient.")
75
- return None
76
-
77
- ttm_params = {"progress": True} # Common param for both
78
-
79
- if lollms_client.ttm.binding_name == "audiocraft":
80
- ttm_params["duration"] = sfx_info.get("duration", 1.0)
81
- ttm_params["temperature"] = sfx_info.get("audiocraft_temperature", 1.0)
82
- ttm_params["cfg_coef"] = sfx_info.get("audiocraft_cfg_coef", 3.0)
83
- ASCIIColors.info(f"AudioCraft Params: duration={ttm_params['duration']}, temp={ttm_params['temperature']}, cfg={ttm_params['cfg_coef']}")
84
- elif lollms_client.ttm.binding_name == "bark":
85
- # Bark duration is implicit. Parameters are different.
86
- bark_specific_params = sfx_info.get("bark_params", {})
87
- ttm_params["voice_preset"] = bark_specific_params.get("voice_preset", None) # None might be good for SFX
88
- ttm_params["fine_temperature"] = bark_specific_params.get("fine_temperature", 0.5)
89
- ttm_params["coarse_temperature"] = bark_specific_params.get("coarse_temperature", 0.7)
90
- ASCIIColors.info(f"Bark Params: preset={ttm_params['voice_preset']}, fine_temp={ttm_params['fine_temperature']}, coarse_temp={ttm_params['coarse_temperature']}")
91
- else:
92
- ASCIIColors.warning(f"Unknown TTM binding '{lollms_client.ttm.binding_name}'. Using generic parameters.")
93
-
94
-
95
- try:
96
- music_bytes = lollms_client.ttm.generate_music(prompt=prompt, **ttm_params)
97
-
98
- if music_bytes:
99
- with open(output_path, "wb") as f:
100
- f.write(music_bytes)
101
- ASCIIColors.green(f"SFX '{filename_stem}' ({lollms_client.ttm.binding_name}) saved to: {output_path}")
102
- return output_path
103
- else:
104
- ASCIIColors.warning(f"SFX generation for '{filename_stem}' ({lollms_client.ttm.binding_name}) returned empty bytes.")
105
- return None
106
- except Exception as e:
107
- ASCIIColors.error(f"Error generating SFX '{filename_stem}' ({lollms_client.ttm.binding_name}): {e}")
108
- trace_exception(e)
109
- return None
110
-
111
- def main():
112
- parser = argparse.ArgumentParser(description="Generate game sound effects using LOLLMS TTM bindings.")
113
- parser.add_argument(
114
- "--ttm_binding",
115
- type=str,
116
- choices=["audiocraft", "bark"],
117
- default="bark", # Default to audiocraft
118
- help="The TTM binding to use for generation."
119
- )
120
- parser.add_argument(
121
- "--audiocraft_model",
122
- type=str,
123
- default="facebook/musicgen-small",
124
- help="Hugging Face model ID for AudioCraft (e.g., facebook/musicgen-small, facebook/musicgen-melody)."
125
- )
126
- parser.add_argument(
127
- "--bark_model",
128
- type=str,
129
- default="suno/bark-small",
130
- help="Hugging Face model ID for Bark (e.g., suno/bark-small, suno/bark)."
131
- )
132
- parser.add_argument(
133
- "--device",
134
- type=str,
135
- default=None, # Auto-detect
136
- choices=["cpu", "cuda", "mps", None],
137
- help="Device to run the TTM model on (cpu, cuda, mps, or auto-detect)."
138
- )
139
- args = parser.parse_args()
140
-
141
- ASCIIColors.red(f"--- LOLLMS Game SFX Generation Example (Using: {args.ttm_binding}) ---")
142
-
143
- ttm_binding_config = {"device": args.device} # Common device config
144
- if args.ttm_binding == "audiocraft":
145
- ttm_binding_config["model_name"] = args.audiocraft_model
146
- ttm_binding_config["output_format"] = "wav" # Audiocraft binding defaults to wav for bytes
147
- elif args.ttm_binding == "bark":
148
- ttm_binding_config["model_name"] = args.bark_model
149
- # Bark binding currently outputs WAV by default for bytes
150
- else:
151
- ASCIIColors.error(f"Unsupported TTM binding: {args.ttm_binding}")
152
- return
153
-
154
- try:
155
- ASCIIColors.magenta(f"Initializing LollmsClient with {args.ttm_binding} for TTM...")
156
- lollms_client = LollmsClient(
157
- binding_name="lollms", # Can be a dummy if only using TTM
158
- ttm_binding_name=args.ttm_binding,
159
- ttm_binding_config=ttm_binding_config
160
- )
161
- ASCIIColors.green("LollmsClient initialized.")
162
- except Exception as e:
163
- ASCIIColors.error(f"Failed to initialize LollmsClient: {e}")
164
- trace_exception(e)
165
- return
166
-
167
- if not lollms_client.ttm:
168
- ASCIIColors.error(f"{args.ttm_binding.capitalize()} TTM binding could not be loaded. Exiting.")
169
- return
170
-
171
- generated_sfx_paths = {}
172
- for sfx_info_item in SOUND_EFFECTS_TO_GENERATE:
173
- sfx_path = generate_sfx(lollms_client, sfx_info_item)
174
- if sfx_path:
175
- generated_sfx_paths[sfx_info_item["filename"]] = {
176
- "path": sfx_path,
177
- "binding": args.ttm_binding # Store which binding generated it
178
- }
179
- time.sleep(0.5) # Small delay
180
-
181
- ASCIIColors.red("\n--- SFX Generation Complete ---")
182
- if not generated_sfx_paths:
183
- ASCIIColors.warning("No sound effects were successfully generated.")
184
- return
185
-
186
- if not PYGAME_AVAILABLE:
187
- ASCIIColors.warning("Pygame is not available. Skipping sound playback demo.")
188
- ASCIIColors.info(f"Generated SFX can be found in: {SFX_OUTPUT_DIR.resolve()}")
189
- return
190
-
191
- ASCIIColors.magenta("\n--- Pygame SFX Playback Demo ---")
192
- pygame.mixer.init()
193
- game_sounds = {}
194
- sfx_playback_order = [] # To map number keys to sounds
195
-
196
- for filename_stem, sfx_data in generated_sfx_paths.items():
197
- path = sfx_data["path"]
198
- binding_used = sfx_data["binding"]
199
- playback_name = f"{filename_stem} ({binding_used})"
200
- try:
201
- sound = pygame.mixer.Sound(str(path))
202
- game_sounds[playback_name] = sound
203
- sfx_playback_order.append(playback_name)
204
- ASCIIColors.green(f"Loaded '{path.name}' into pygame as '{playback_name}'.")
205
- except pygame.error as e:
206
- ASCIIColors.warning(f"Could not load sound '{path.name}' into pygame: {e}")
207
-
208
- if not game_sounds:
209
- ASCIIColors.warning("No sounds loaded into pygame. Exiting demo.")
210
- return
211
-
212
- print("\nInstructions:")
213
- for i, sfx_name_to_play in enumerate(sfx_playback_order):
214
- print(f" Press key '{i+1}' to play: {sfx_name_to_play}")
215
- print(" Press 'Q' to quit the demo.")
216
-
217
- pygame.display.set_mode((400, 200))
218
- pygame.display.set_caption(f"SFX Player ({args.ttm_binding.capitalize()})")
219
-
220
- running = True
221
- while running:
222
- for event in pygame.event.get():
223
- if event.type == pygame.QUIT: running = False
224
- if event.type == pygame.KEYDOWN:
225
- if event.key == pygame.K_q: running = False
226
- for i in range(len(sfx_playback_order)):
227
- if event.key == getattr(pygame, f"K_{i+1}", None): # Check if K_i+1 exists
228
- sfx_name_to_play = sfx_playback_order[i]
229
- if sfx_name_to_play in game_sounds:
230
- ASCIIColors.cyan(f"Playing: {sfx_name_to_play}")
231
- game_sounds[sfx_name_to_play].play()
232
- break
233
- pygame.time.Clock().tick(30)
234
-
235
- pygame.quit()
236
- ASCIIColors.red("--- Demo Finished ---")
237
- ASCIIColors.info(f"Generated SFX are in: {SFX_OUTPUT_DIR.resolve()}")
238
-
239
- if __name__ == "__main__":
240
- main()
@@ -1,210 +0,0 @@
1
- from lollms_client import LollmsClient, MSG_TYPE
2
- from ascii_colors import ASCIIColors, trace_exception
3
- from typing import List, Dict, Any, Optional, Callable
4
- import json
5
- from pathlib import Path
6
-
7
- # --- Mock RAG Implementation ---
8
- # In a real application, this would interact with your vector database (Pinecone, ChromaDB, FAISS, etc.)
9
- # and use a real sentence transformer for vectorization.
10
-
11
- MOCK_KNOWLEDGE_BASE = {
12
- "python_basics.md": [
13
- {"chunk_id": 1, "text": "Python is a high-level, interpreted programming language known for its readability and versatility. It was created by Guido van Rossum and first released in 1991."},
14
- {"chunk_id": 2, "text": "Key features of Python include dynamic typing, automatic memory management (garbage collection), and a large standard library. It supports multiple programming paradigms, such as procedural, object-oriented, and functional programming."},
15
- {"chunk_id": 3, "text": "Common applications of Python include web development (e.g., Django, Flask), data science (e.g., Pandas, NumPy, Scikit-learn), machine learning, artificial intelligence, automation, and scripting."},
16
- ],
17
- "javascript_info.js": [
18
- {"chunk_id": 1, "text": "JavaScript is a scripting language primarily used for front-end web development to create interactive effects within web browsers. It is also used in back-end development (Node.js), mobile app development, and game development."},
19
- {"chunk_id": 2, "text": "JavaScript is dynamically typed, prototype-based, and multi-paradigm. Along with HTML and CSS, it is one of the core technologies of the World Wide Web."},
20
- {"chunk_id": 3, "text": "Popular JavaScript frameworks and libraries include React, Angular, Vue.js for front-end, and Express.js for Node.js back-end applications."},
21
- ],
22
- "ai_concepts.txt": [
23
- {"chunk_id": 1, "text": "Artificial Intelligence (AI) refers to the simulation of human intelligence in machines that are programmed to think like humans and mimic their actions. The term may also be applied to any machine that exhibits traits associated with a human mind such as learning and problem-solving."},
24
- {"chunk_id": 2, "text": "Machine Learning (ML) is a subset of AI that provides systems the ability to automatically learn and improve from experience without being explicitly programmed. Deep Learning (DL) is a further subset of ML based on artificial neural networks with representation learning."},
25
- {"chunk_id": 3, "text": "Retrieval Augmented Generation (RAG) is an AI framework for improving the quality of LLM-generated responses by grounding the model on external sources of knowledge to supplement the LLM’s internal representation of information."},
26
- ]
27
- }
28
-
29
- def mock_rag_query_function(
30
- query_text: str,
31
- vectorizer_name: Optional[str] = None, # Ignored in mock
32
- top_k: int = 3,
33
- min_similarity_percent: float = 0.0 # Ignored in mock, simple keyword match
34
- ) -> List[Dict[str, Any]]:
35
- """
36
- A mock RAG query function.
37
- Performs a simple keyword search in the MOCK_KNOWLEDGE_BASE.
38
- """
39
- ASCIIColors.magenta(f" [MOCK RAG] Querying with: '{query_text}', top_k={top_k}")
40
- results = []
41
- query_lower = query_text.lower()
42
-
43
- all_chunks = []
44
- for file_path, chunks_in_file in MOCK_KNOWLEDGE_BASE.items():
45
- for chunk_data in chunks_in_file:
46
- all_chunks.append({"file_path": file_path, **chunk_data})
47
-
48
- # Simple keyword matching and scoring (very basic)
49
- scored_chunks = []
50
- for chunk_info in all_chunks:
51
- score = 0
52
- for keyword in query_lower.split():
53
- if keyword in chunk_info["text"].lower() and len(keyword)>2: # Basic relevance
54
- score += 1
55
- if "python" in query_lower and "python" in chunk_info["file_path"].lower(): score+=5
56
- if "javascript" in query_lower and "javascript" in chunk_info["file_path"].lower(): score+=5
57
- if "ai" in query_lower and "ai" in chunk_info["file_path"].lower(): score+=3
58
-
59
-
60
- if score > 0 : # Only include if some keywords match
61
- # Simulate similarity percentage (higher score = higher similarity)
62
- similarity = min(100.0, score * 20.0 + 40.0) # Arbitrary scaling
63
- if similarity >= min_similarity_percent:
64
- scored_chunks.append({
65
- "file_path": chunk_info["file_path"],
66
- "chunk_text": chunk_info["text"],
67
- "similarity_percent": similarity,
68
- "_score_for_ranking": score # Internal score for sorting
69
- })
70
-
71
- # Sort by internal score (descending) and take top_k
72
- scored_chunks.sort(key=lambda x: x["_score_for_ranking"], reverse=True)
73
- results = [
74
- {"file_path": c["file_path"], "chunk_text": c["chunk_text"], "similarity_percent": c["similarity_percent"]}
75
- for c in scored_chunks[:top_k]
76
- ]
77
- ASCIIColors.magenta(f" [MOCK RAG] Found {len(results)} relevant chunks.")
78
- return results
79
-
80
- # --- Streaming Callback for RAG and LLM ---
81
- def rag_streaming_callback(
82
- chunk: str,
83
- msg_type: MSG_TYPE,
84
- metadata: Optional[Dict] = None,
85
- turn_history: Optional[List] = None # history of this specific RAG turn
86
- ) -> bool:
87
- """
88
- Handles various stages of RAG and final LLM generation.
89
- """
90
- metadata = metadata or {}
91
- turn_history = turn_history or [] # Should be populated by LollmsClient
92
-
93
- if msg_type == MSG_TYPE.MSG_TYPE_CHUNK: # Final answer chunks
94
- ASCIIColors.success(chunk, end="", flush=True)
95
- elif msg_type == MSG_TYPE.MSG_TYPE_STEP_START:
96
- step_type = metadata.get("type", "step")
97
- hop = metadata.get("hop", "")
98
- info = metadata.get("query", chunk) if step_type == "rag_query_generation" or step_type == "rag_retrieval" else chunk
99
- ASCIIColors.yellow(f"\n>> RAG Step Start (Hop {hop}): {step_type} - Info: {str(info)[:100]}...", flush=True)
100
- elif msg_type == MSG_TYPE.MSG_TYPE_STEP_END:
101
- step_type = metadata.get("type", "step")
102
- hop = metadata.get("hop", "")
103
- num_chunks = metadata.get("num_chunks", "")
104
- query = metadata.get("query", "")
105
- decision = metadata.get("decision", "")
106
-
107
- info_str = ""
108
- if step_type == "rag_query_generation" and query: info_str = f"Generated Query: {query}"
109
- elif step_type == "rag_retrieval": info_str = f"Retrieved {num_chunks} chunks"
110
- elif step_type == "rag_llm_decision": info_str = f"LLM Decision: {json.dumps(decision)}"
111
- elif step_type == "final_answer_generation": info_str = "Final answer generation complete."
112
- else: info_str = chunk
113
-
114
- ASCIIColors.green(f"\n<< RAG Step End (Hop {hop}): {step_type} - {info_str}", flush=True)
115
- elif msg_type == MSG_TYPE.MSG_TYPE_EXCEPTION:
116
- ASCIIColors.error(f"\nError in RAG stream: {chunk}", flush=True)
117
-
118
- # You can inspect turn_history here if needed:
119
- # ASCIIColors.debug(f"Current RAG Turn History: {turn_history}")
120
- return True
121
-
122
- # --- Main Example ---
123
- if __name__ == "__main__":
124
- ASCIIColors.red("--- Multi-Hop RAG Example with LollmsClient ---")
125
-
126
- # LLM Configuration (use a model good at instruction following and JSON)
127
- # Ensure your Ollama server is running and has this model pulled.
128
- LLM_BINDING_NAME = "ollama"
129
- LLM_MODEL_NAME = "qwen3:4b" # or llama3, phi3 etc.
130
- # LLM_MODEL_NAME = "qwen2:1.5b" # Smaller model for quicker tests, but might struggle with complex JSON
131
-
132
- try:
133
- lc = LollmsClient(
134
- binding_name=LLM_BINDING_NAME,
135
- model_name=LLM_MODEL_NAME,
136
- temperature=0.1, # Default temp for final answer if not overridden
137
- # Other LollmsClient params as needed
138
- )
139
- ASCIIColors.green(f"LollmsClient initialized with LLM: {LLM_BINDING_NAME}/{LLM_MODEL_NAME}")
140
-
141
- # --- Test Case 1: Classic RAG (max_rag_hops = 0) ---
142
- ASCIIColors.cyan("\n\n--- Test Case 1: Classic RAG (max_rag_hops = 0) ---")
143
- classic_rag_prompt = "What are the key features of Python?"
144
- ASCIIColors.blue(f"User Prompt: {classic_rag_prompt}")
145
-
146
- classic_rag_result = lc.generate_text_with_rag(
147
- prompt=classic_rag_prompt,
148
- rag_query_function=mock_rag_query_function,
149
- # rag_query_text=None, # Will use `prompt` for query
150
- max_rag_hops=0,
151
- rag_top_k=2, # Get 2 best chunks
152
- rag_min_similarity_percent=50.0,
153
- streaming_callback=rag_streaming_callback,
154
- n_predict=1024 # Max tokens for final answer
155
- )
156
- print("\n--- End of Classic RAG ---")
157
- ASCIIColors.magenta("\nClassic RAG Final Output:")
158
- print(json.dumps(classic_rag_result, indent=2))
159
-
160
-
161
- # --- Test Case 2: Multi-Hop RAG (max_rag_hops = 1) ---
162
- ASCIIColors.cyan("\n\n--- Test Case 2: Multi-Hop RAG (max_rag_hops = 1) ---")
163
- multihop_prompt_1 = "Compare Python and JavaScript for web development based on their common applications and core technologies."
164
- ASCIIColors.blue(f"User Prompt: {multihop_prompt_1}")
165
-
166
- multihop_rag_result_1 = lc.generate_text_with_rag(
167
- prompt=multihop_prompt_1,
168
- rag_query_function=mock_rag_query_function,
169
- # rag_query_text="Python web development applications", # Optional: provide an initial query
170
- max_rag_hops=1, # Allow one hop for LLM to refine search or decide
171
- rag_top_k=2,
172
- rag_min_similarity_percent=60.0,
173
- streaming_callback=rag_streaming_callback,
174
- n_predict=1024,
175
- rag_hop_query_generation_temperature=0.1, # Focused query gen
176
- )
177
- print("\n--- End of Multi-Hop RAG (1 hop) ---")
178
- ASCIIColors.magenta("\nMulti-Hop RAG (1 hop) Final Output:")
179
- print(json.dumps(multihop_rag_result_1, indent=2))
180
-
181
-
182
- # --- Test Case 3: Multi-Hop RAG (max_rag_hops = 2) - LLM might decide it has enough earlier ---
183
- ASCIIColors.cyan("\n\n--- Test Case 3: Multi-Hop RAG (max_rag_hops = 2) ---")
184
- multihop_prompt_2 = "Explain Retrieval Augmented Generation (RAG) and its relation to Machine Learning."
185
- ASCIIColors.blue(f"User Prompt: {multihop_prompt_2}")
186
-
187
- multihop_rag_result_2 = lc.generate_text_with_rag(
188
- prompt=multihop_prompt_2,
189
- rag_query_function=mock_rag_query_function,
190
- max_rag_hops=2, # Allow up to two refinement hops
191
- rag_top_k=1, # Get only the best chunk per hop to force more specific queries
192
- rag_min_similarity_percent=50.0,
193
- streaming_callback=rag_streaming_callback,
194
- n_predict=300
195
- )
196
- print("\n--- End of Multi-Hop RAG (up to 2 hops) ---")
197
- ASCIIColors.magenta("\nMulti-Hop RAG (up to 2 hops) Final Output:")
198
- print(json.dumps(multihop_rag_result_2, indent=2))
199
-
200
-
201
- except ValueError as ve:
202
- ASCIIColors.error(f"Initialization or RAG parameter error: {ve}")
203
- trace_exception(ve)
204
- except ConnectionRefusedError:
205
- ASCIIColors.error(f"Connection refused. Is the Ollama server ({LLM_BINDING_NAME}) running?")
206
- except Exception as e:
207
- ASCIIColors.error(f"An unexpected error occurred: {e}")
208
- trace_exception(e)
209
-
210
- ASCIIColors.red("\n--- Multi-Hop RAG Example Finished ---")