Pnaomi commited on
Commit
b880264
·
verified ·
1 Parent(s): 5899800

Upload lifer_app.py

Browse files
Files changed (1) hide show
  1. lifer_app.py +429 -0
lifer_app.py ADDED
@@ -0,0 +1,429 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import json
3
+ import os
4
+ import sys
5
+ import logging
6
+ from typing import Dict, List, Any, Optional
7
+ import requests
8
+ from dotenv import load_dotenv
9
+
10
+ # Configure logging
11
+ logging.basicConfig(
12
+ level=logging.INFO,
13
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
14
+ )
15
+ logger = logging.getLogger(__name__)
16
+
17
+ # Load environment variables for API keys
18
+ load_dotenv()
19
+ ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
20
+ if not ANTHROPIC_API_KEY:
21
+ logger.warning("Anthropic API key not found. You'll need to provide it in the app.")
22
+
23
+ class LifeNavigatorPromptEngineer:
24
+ """
25
+ A class to engineer and manage prompts for the Life Navigator AI assistant using Claude 3.7 Sonnet.
26
+ """
27
+
28
+ def __init__(self, api_key=None, model_endpoint: str = "https://api.anthropic.com/v1/messages"):
29
+ """
30
+ Initialize the prompt engineer with Claude model endpoint.
31
+
32
+ Args:
33
+ api_key: Anthropic API key
34
+ model_endpoint: API endpoint for the model
35
+ """
36
+ self.api_key = api_key
37
+ self.model_endpoint = model_endpoint
38
+ self.model_name = "claude-3-7-sonnet-20250219"
39
+ self.base_prompt = self._create_base_prompt()
40
+
41
+ def _create_base_prompt(self) -> Dict[str, Any]:
42
+ """
43
+ Create the base prompt structure for the Life Navigator assistant.
44
+
45
+ Returns:
46
+ Dict containing the structured prompt
47
+ """
48
+ return {
49
+ "assistantIdentity": {
50
+ "name": "Life Navigator",
51
+ "expertise": "Comprehensive knowledge spanning life sciences, technology, philosophy, psychology, and spiritual traditions",
52
+ "training": "Full breadth of human wisdom from ancient texts to cutting-edge research"
53
+ },
54
+
55
+ "coreCapabilities": [
56
+ "Integrate knowledge across disciplines to provide holistic insights",
57
+ "Identify root causes rather than merely addressing symptoms",
58
+ "Synthesize scientific evidence with wisdom traditions",
59
+ "Provide highly concentrated, high-leverage strategic guidance",
60
+ "Express complex concepts with exceptional clarity and precision"
61
+ ],
62
+
63
+ "userCharacteristics": {
64
+ "cognition": "Exceptional (179+ IQ)",
65
+ "progressPattern": "Superhuman advancement from minimal strategic input",
66
+ "learningStyle": "Optimal response to condensed, high-level conceptual frameworks",
67
+ "cognitiveProcessing": "Extrapolates extensive applications from concise directives",
68
+ "preference": "Strategically crafted remedial sentences and phrases of maximum leverage"
69
+ },
70
+
71
+ "responseGuidelines": [
72
+ "Embed powerful conceptual frameworks within concise, elegant sentences",
73
+ "Target highest leverage intervention points with precision language",
74
+ "Frame concepts at appropriate abstraction levels for exceptional cognition",
75
+ "Present multiple interconnected perspectives when beneficial",
76
+ "Respect intellectual autonomy while offering transformative insights",
77
+ "Craft sentences containing strategic remedial phrases that trigger profound understanding"
78
+ ],
79
+
80
+ "communicationStyle": {
81
+ "conciseness": "Exceptionally dense with transformative meaning",
82
+ "depth": "Philosophical insights through elegant conceptual compression",
83
+ "terminology": "Strategic use of specialized language when appropriate",
84
+ "purpose": "Sentences designed as cognitive catalysts rather than mere explanations",
85
+ "essence": "Crystallized wisdom embedded within carefully structured language"
86
+ }
87
+ }
88
+
89
+ def customize_prompt(self,
90
+ domain: Optional[str] = None,
91
+ user_context: Optional[Dict[str, Any]] = None,
92
+ response_temperature: float = 0.7,
93
+ custom_capabilities: Optional[List[str]] = None) -> Dict[str, Any]:
94
+ """
95
+ Customize the base prompt with domain-specific additions and user context.
96
+
97
+ Args:
98
+ domain: Specific knowledge domain to emphasize
99
+ user_context: Context about the user's situation
100
+ response_temperature: Control parameter for response creativity
101
+ custom_capabilities: Additional capabilities to include
102
+
103
+ Returns:
104
+ Modified prompt dictionary
105
+ """
106
+ prompt = self.base_prompt.copy()
107
+
108
+ # Add domain-specific knowledge if specified
109
+ if domain and domain.strip():
110
+ prompt["domainSpecialization"] = domain
111
+
112
+ # Add user context if provided
113
+ if user_context:
114
+ prompt["userContext"] = user_context
115
+
116
+ # Add response parameters
117
+ prompt["responseParameters"] = {
118
+ "temperature": response_temperature,
119
+ "max_tokens": 2048,
120
+ "top_p": 0.9
121
+ }
122
+
123
+ # Add custom capabilities if provided
124
+ if custom_capabilities:
125
+ capabilities = [cap for cap in custom_capabilities if cap.strip()]
126
+ if capabilities:
127
+ prompt["coreCapabilities"].extend(capabilities)
128
+
129
+ return prompt
130
+
131
+ def format_for_claude(self, prompt: Dict[str, Any]) -> str:
132
+ """
133
+ Format the prompt structure for Claude's system prompt.
134
+
135
+ Args:
136
+ prompt: The prompt dictionary
137
+
138
+ Returns:
139
+ Formatted system prompt string
140
+ """
141
+ system_prompt = f"""You are the Life Navigator, an AI assistant designed to provide exceptional guidance.
142
+
143
+ Your instruction is to follow these guidelines:
144
+
145
+ {json.dumps(prompt, indent=2)}
146
+
147
+ Always respond with strategically crafted, high-leverage remedial sentences that are optimized for users with exceptional cognitive abilities (179+ IQ).
148
+ """
149
+ return system_prompt
150
+
151
+ def send_prompt(self, api_key: str, user_query: str, system_prompt: str,
152
+ temperature: float = 0.7, max_tokens: int = 1024) -> str:
153
+ """
154
+ Send the prompt and user query to the Claude model.
155
+
156
+ Args:
157
+ api_key: Anthropic API key
158
+ user_query: The user's question or issue
159
+ system_prompt: The formatted system prompt
160
+ temperature: Control parameter for response creativity
161
+ max_tokens: Maximum tokens in response
162
+
163
+ Returns:
164
+ The model's response
165
+ """
166
+ if not api_key:
167
+ return "Error: API key is required."
168
+
169
+ if not user_query.strip():
170
+ return "Error: Please provide a question or issue to address."
171
+
172
+ try:
173
+ payload = {
174
+ "model": self.model_name,
175
+ "system": system_prompt,
176
+ "messages": [
177
+ {
178
+ "role": "user",
179
+ "content": user_query
180
+ }
181
+ ],
182
+ "max_tokens": max_tokens,
183
+ "temperature": temperature
184
+ }
185
+
186
+ headers = {
187
+ "x-api-key": api_key,
188
+ "anthropic-version": "2023-06-01",
189
+ "Content-Type": "application/json"
190
+ }
191
+
192
+ response = requests.post(
193
+ self.model_endpoint,
194
+ headers=headers,
195
+ json=payload
196
+ )
197
+
198
+ response.raise_for_status()
199
+ result = response.json()
200
+
201
+ return result.get("content", [{}])[0].get("text", "No response generated")
202
+
203
+ except requests.exceptions.RequestException as e:
204
+ logger.error(f"Error in Claude API request: {str(e)}")
205
+ return f"Error: Unable to get response from Claude 3.7 Sonnet. {str(e)}"
206
+
207
+ # Initialize the prompt engineer
208
+ engineer = LifeNavigatorPromptEngineer(api_key=ANTHROPIC_API_KEY)
209
+
210
+ def parse_user_context(context_text):
211
+ """Parse user context text into a structured format."""
212
+ if not context_text.strip():
213
+ return None
214
+
215
+ try:
216
+ # First try to parse as JSON
217
+ return json.loads(context_text)
218
+ except json.JSONDecodeError:
219
+ # If not valid JSON, parse as key-value pairs
220
+ context = {}
221
+ lines = context_text.strip().split('\n')
222
+
223
+ current_key = None
224
+ current_items = []
225
+
226
+ for line in lines:
227
+ line = line.strip()
228
+ if not line:
229
+ continue
230
+
231
+ if ':' in line and not line.startswith(' ') and not line.startswith('\t'):
232
+ # Save previous key if exists
233
+ if current_key and current_items:
234
+ if len(current_items) == 1:
235
+ context[current_key] = current_items[0]
236
+ else:
237
+ context[current_key] = current_items
238
+
239
+ # Start new key
240
+ parts = line.split(':', 1)
241
+ current_key = parts[0].strip()
242
+ value = parts[1].strip() if len(parts) > 1 else ""
243
+
244
+ if value:
245
+ current_items = [value]
246
+ else:
247
+ current_items = []
248
+ elif current_key is not None:
249
+ # Add to current list
250
+ if line.startswith('- '):
251
+ current_items.append(line[2:].strip())
252
+ else:
253
+ current_items.append(line)
254
+
255
+ # Add the last key
256
+ if current_key and current_items:
257
+ if len(current_items) == 1:
258
+ context[current_key] = current_items[0]
259
+ else:
260
+ context[current_key] = current_items
261
+
262
+ return context
263
+
264
+ def parse_capabilities(capabilities_text):
265
+ """Parse custom capabilities from text."""
266
+ if not capabilities_text.strip():
267
+ return None
268
+
269
+ capabilities = []
270
+ lines = capabilities_text.strip().split('\n')
271
+
272
+ for line in lines:
273
+ line = line.strip()
274
+ if line:
275
+ if line.startswith('- '):
276
+ capabilities.append(line[2:])
277
+ else:
278
+ capabilities.append(line)
279
+
280
+ return capabilities
281
+
282
+ def generate_response(api_key, domain, user_context_text, capabilities_text, temperature, user_query):
283
+ """Generate a response using the Life Navigator assistant."""
284
+ if not api_key:
285
+ api_key = ANTHROPIC_API_KEY
286
+
287
+ if not api_key:
288
+ return "Error: API key is required. Please enter your Anthropic API key."
289
+
290
+ # Parse user context
291
+ user_context = parse_user_context(user_context_text)
292
+
293
+ # Parse custom capabilities
294
+ custom_capabilities = parse_capabilities(capabilities_text)
295
+
296
+ # Customize prompt
297
+ customized_prompt = engineer.customize_prompt(
298
+ domain=domain,
299
+ user_context=user_context,
300
+ response_temperature=float(temperature),
301
+ custom_capabilities=custom_capabilities
302
+ )
303
+
304
+ # Format for Claude
305
+ formatted_prompt = engineer.format_for_claude(customized_prompt)
306
+
307
+ # Send to Claude and get response
308
+ response = engineer.send_prompt(
309
+ api_key=api_key,
310
+ user_query=user_query,
311
+ system_prompt=formatted_prompt,
312
+ temperature=float(temperature)
313
+ )
314
+
315
+ return response
316
+
317
+ def show_user_context_help():
318
+ return """
319
+ Enter user context in simple key-value format or JSON:
320
+
321
+ Simple format example:
322
+ background: Technical expertise with desire for more meaning
323
+ challenges:
324
+ - Decision paralysis
325
+ - Fear of financial instability
326
+ strengths:
327
+ - Analytical thinking
328
+ - Pattern recognition
329
+
330
+ This will be structured appropriately for the prompt.
331
+ """
332
+
333
+ def show_prompt_preview(api_key, domain, user_context_text, capabilities_text, temperature):
334
+ """Show a preview of the formatted prompt."""
335
+ # Parse user context
336
+ user_context = parse_user_context(user_context_text)
337
+
338
+ # Parse custom capabilities
339
+ custom_capabilities = parse_capabilities(capabilities_text)
340
+
341
+ # Customize prompt
342
+ customized_prompt = engineer.customize_prompt(
343
+ domain=domain,
344
+ user_context=user_context,
345
+ response_temperature=float(temperature),
346
+ custom_capabilities=custom_capabilities
347
+ )
348
+
349
+ # Format for Claude
350
+ formatted_prompt = engineer.format_for_claude(customized_prompt)
351
+
352
+ return formatted_prompt
353
+
354
+ # Create the Gradio interface
355
+ with gr.Blocks(title="Life Navigator AI Assistant") as app:
356
+ gr.Markdown("# Life Navigator AI Assistant")
357
+ gr.Markdown("### Powered by Claude 3.7 Sonnet")
358
+
359
+ with gr.Tab("Life Navigator"):
360
+ with gr.Row():
361
+ with gr.Column(scale=2):
362
+ user_query = gr.Textbox(
363
+ label="Your Question",
364
+ placeholder="What challenge are you facing?",
365
+ lines=3
366
+ )
367
+
368
+ with gr.Accordion("Advanced Options", open=False):
369
+ api_key = gr.Textbox(
370
+ label="Anthropic API Key (leave blank to use system key if configured)",
371
+ placeholder="sk-ant-...",
372
+ type="password",
373
+ value=ANTHROPIC_API_KEY if ANTHROPIC_API_KEY else ""
374
+ )
375
+
376
+ domain = gr.Textbox(
377
+ label="Domain Specialization (optional)",
378
+ placeholder="e.g., Career Transition, Relationships, Personal Growth",
379
+ value=""
380
+ )
381
+
382
+ temperature = gr.Slider(
383
+ label="Temperature",
384
+ minimum=0.0,
385
+ maximum=1.0,
386
+ step=0.05,
387
+ value=0.7
388
+ )
389
+
390
+ with gr.Accordion("User Context", open=False):
391
+ user_context_help = gr.Button("Show Format Help")
392
+ user_context_text = gr.Textbox(
393
+ label="User Context (optional)",
394
+ placeholder="Enter user context details in key-value format or JSON",
395
+ lines=5
396
+ )
397
+ user_context_help.click(show_user_context_help, outputs=user_context_text)
398
+
399
+ with gr.Accordion("Custom Capabilities", open=False):
400
+ capabilities_text = gr.Textbox(
401
+ label="Additional Capabilities (optional, one per line)",
402
+ placeholder="e.g., Identify optimal career transition pathways based on skills transferability",
403
+ lines=3
404
+ )
405
+
406
+ submit_button = gr.Button("Submit", variant="primary")
407
+
408
+ with gr.Column(scale=3):
409
+ response_output = gr.Markdown(label="Life Navigator Response")
410
+
411
+ with gr.Tab("Prompt Preview"):
412
+ preview_button = gr.Button("Generate Prompt Preview")
413
+ prompt_preview = gr.Code(language="json", label="System Prompt Preview")
414
+
415
+ submit_button.click(
416
+ generate_response,
417
+ inputs=[api_key, domain, user_context_text, capabilities_text, temperature, user_query],
418
+ outputs=response_output
419
+ )
420
+
421
+ preview_button.click(
422
+ show_prompt_preview,
423
+ inputs=[api_key, domain, user_context_text, capabilities_text, temperature],
424
+ outputs=prompt_preview
425
+ )
426
+
427
+ # Launch the app
428
+ if __name__ == "__main__":
429
+ app.launch()