bizy-ai 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.
- agent/__init__.py +5 -0
- agent/cli.py +228 -0
- agent/core.py +205 -0
- agent/models.py +216 -0
- agent/planner.py +363 -0
- agent/research.py +199 -0
- agent/tasks.py +251 -0
- bizy_ai-1.0.0.dist-info/METADATA +471 -0
- bizy_ai-1.0.0.dist-info/RECORD +18 -0
- bizy_ai-1.0.0.dist-info/WHEEL +5 -0
- bizy_ai-1.0.0.dist-info/entry_points.txt +2 -0
- bizy_ai-1.0.0.dist-info/licenses/LICENSE +21 -0
- bizy_ai-1.0.0.dist-info/top_level.txt +2 -0
- scripts/agent_cli.py +232 -0
- scripts/evening_review.py +148 -0
- scripts/init_db.py +91 -0
- scripts/morning_brief.py +132 -0
- scripts/weekly_review.py +72 -0
agent/planner.py
ADDED
@@ -0,0 +1,363 @@
|
|
1
|
+
from datetime import datetime, timedelta
|
2
|
+
from sqlalchemy import and_
|
3
|
+
from agent.models import Goal, BusinessPlan, Task, get_session
|
4
|
+
from agent.tasks import TaskManager
|
5
|
+
import anthropic
|
6
|
+
import os
|
7
|
+
import json
|
8
|
+
|
9
|
+
class BusinessPlanner:
|
10
|
+
def __init__(self):
|
11
|
+
self.session = get_session()
|
12
|
+
self.task_mgr = TaskManager()
|
13
|
+
self.client = anthropic.Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))
|
14
|
+
self.model = "claude-sonnet-4-20250514"
|
15
|
+
|
16
|
+
# === Business Plan Management ===
|
17
|
+
|
18
|
+
def create_business_plan(self, vision, mission, value_proposition,
|
19
|
+
target_market, revenue_model, key_resources=None,
|
20
|
+
key_activities=None, key_partnerships=None,
|
21
|
+
cost_structure=None, version="1.0"):
|
22
|
+
"""Create a new business plan"""
|
23
|
+
# Deactivate old plans
|
24
|
+
old_plans = self.session.query(BusinessPlan).filter(
|
25
|
+
BusinessPlan.is_active == True
|
26
|
+
).all()
|
27
|
+
for plan in old_plans:
|
28
|
+
plan.is_active = False
|
29
|
+
|
30
|
+
plan = BusinessPlan(
|
31
|
+
version=version,
|
32
|
+
vision=vision,
|
33
|
+
mission=mission,
|
34
|
+
value_proposition=value_proposition,
|
35
|
+
target_market=target_market,
|
36
|
+
revenue_model=revenue_model,
|
37
|
+
key_resources=key_resources or {},
|
38
|
+
key_activities=key_activities or [],
|
39
|
+
key_partnerships=key_partnerships or [],
|
40
|
+
cost_structure=cost_structure or {},
|
41
|
+
is_active=True
|
42
|
+
)
|
43
|
+
self.session.add(plan)
|
44
|
+
self.session.commit()
|
45
|
+
return plan
|
46
|
+
|
47
|
+
def get_active_business_plan(self):
|
48
|
+
"""Get the current active business plan"""
|
49
|
+
return self.session.query(BusinessPlan).filter(
|
50
|
+
BusinessPlan.is_active == True
|
51
|
+
).first()
|
52
|
+
|
53
|
+
# === Goal Management ===
|
54
|
+
|
55
|
+
def create_goal(self, title, description, horizon, target_date=None,
|
56
|
+
success_criteria=None, parent_goal_id=None, metrics=None):
|
57
|
+
"""Create a new goal"""
|
58
|
+
goal = Goal(
|
59
|
+
title=title,
|
60
|
+
description=description,
|
61
|
+
horizon=horizon,
|
62
|
+
target_date=target_date,
|
63
|
+
success_criteria=success_criteria,
|
64
|
+
parent_goal_id=parent_goal_id,
|
65
|
+
metrics=metrics or {}
|
66
|
+
)
|
67
|
+
self.session.add(goal)
|
68
|
+
self.session.commit()
|
69
|
+
return goal
|
70
|
+
|
71
|
+
def get_goal(self, goal_id):
|
72
|
+
"""Get a specific goal"""
|
73
|
+
return self.session.query(Goal).filter(Goal.id == goal_id).first()
|
74
|
+
|
75
|
+
def get_active_goals(self):
|
76
|
+
"""Get all active goals"""
|
77
|
+
return self.session.query(Goal).filter(
|
78
|
+
Goal.status == 'active'
|
79
|
+
).order_by(Goal.horizon, Goal.target_date).all()
|
80
|
+
|
81
|
+
def get_goals_by_horizon(self, horizon):
|
82
|
+
"""Get goals for a specific time horizon"""
|
83
|
+
return self.session.query(Goal).filter(
|
84
|
+
and_(
|
85
|
+
Goal.horizon == horizon,
|
86
|
+
Goal.status == 'active'
|
87
|
+
)
|
88
|
+
).order_by(Goal.target_date).all()
|
89
|
+
|
90
|
+
def update_goal_progress(self, goal_id, progress_percentage):
|
91
|
+
"""Update goal progress"""
|
92
|
+
goal = self.get_goal(goal_id)
|
93
|
+
if goal:
|
94
|
+
goal.progress_percentage = progress_percentage
|
95
|
+
goal.updated_at = datetime.now()
|
96
|
+
|
97
|
+
# Auto-complete if 100%
|
98
|
+
if progress_percentage >= 100:
|
99
|
+
goal.status = 'completed'
|
100
|
+
|
101
|
+
self.session.commit()
|
102
|
+
return goal
|
103
|
+
|
104
|
+
def calculate_goal_progress(self, goal_id):
|
105
|
+
"""Calculate goal progress based on completed tasks"""
|
106
|
+
tasks = self.task_mgr.get_tasks_by_goal(goal_id)
|
107
|
+
if not tasks:
|
108
|
+
return 0
|
109
|
+
|
110
|
+
completed = len([t for t in tasks if t.status == 'completed'])
|
111
|
+
progress = (completed / len(tasks)) * 100
|
112
|
+
|
113
|
+
# Update the goal
|
114
|
+
self.update_goal_progress(goal_id, progress)
|
115
|
+
return progress
|
116
|
+
|
117
|
+
# === Goal Breakdown (AI-Powered) ===
|
118
|
+
|
119
|
+
def break_down_goal(self, goal_id):
|
120
|
+
"""Use AI to break down a goal into actionable tasks"""
|
121
|
+
goal = self.get_goal(goal_id)
|
122
|
+
if not goal:
|
123
|
+
return None
|
124
|
+
|
125
|
+
business_plan = self.get_active_business_plan()
|
126
|
+
context = ""
|
127
|
+
if business_plan:
|
128
|
+
context = f"""
|
129
|
+
Business Context:
|
130
|
+
- Vision: {business_plan.vision}
|
131
|
+
- Mission: {business_plan.mission}
|
132
|
+
- Value Proposition: {business_plan.value_proposition}
|
133
|
+
"""
|
134
|
+
|
135
|
+
prompt = f"""{context}
|
136
|
+
|
137
|
+
I need help breaking down this business goal into actionable tasks:
|
138
|
+
|
139
|
+
GOAL: {goal.title}
|
140
|
+
DESCRIPTION: {goal.description}
|
141
|
+
TIME HORIZON: {goal.horizon}
|
142
|
+
TARGET DATE: {goal.target_date.strftime('%Y-%m-%d') if goal.target_date else 'Not set'}
|
143
|
+
SUCCESS CRITERIA: {goal.success_criteria or 'Not defined'}
|
144
|
+
|
145
|
+
Please break this goal down into 5-10 specific, actionable tasks that would help achieve this goal. For each task, provide:
|
146
|
+
|
147
|
+
1. Title (clear, action-oriented)
|
148
|
+
2. Description (what needs to be done)
|
149
|
+
3. Estimated hours
|
150
|
+
4. Priority (1-5, where 1 is highest)
|
151
|
+
5. Category (development, marketing, operations, finance, etc.)
|
152
|
+
6. Dependencies (if any, reference other task numbers)
|
153
|
+
|
154
|
+
Format your response as a JSON array of tasks:
|
155
|
+
[
|
156
|
+
{{
|
157
|
+
"title": "Task title",
|
158
|
+
"description": "Detailed description",
|
159
|
+
"estimated_hours": 2.5,
|
160
|
+
"priority": 1,
|
161
|
+
"category": "development",
|
162
|
+
"dependencies": []
|
163
|
+
}},
|
164
|
+
...
|
165
|
+
]
|
166
|
+
|
167
|
+
Only return the JSON array, no additional text."""
|
168
|
+
|
169
|
+
try:
|
170
|
+
message = self.client.messages.create(
|
171
|
+
model=self.model,
|
172
|
+
max_tokens=3000,
|
173
|
+
messages=[{"role": "user", "content": prompt}]
|
174
|
+
)
|
175
|
+
|
176
|
+
response_text = message.content[0].text.strip()
|
177
|
+
|
178
|
+
# Remove markdown code blocks if present
|
179
|
+
if response_text.startswith('```'):
|
180
|
+
response_text = response_text.split('```')[1]
|
181
|
+
if response_text.startswith('json'):
|
182
|
+
response_text = response_text[4:]
|
183
|
+
response_text = response_text.strip()
|
184
|
+
|
185
|
+
tasks_data = json.loads(response_text)
|
186
|
+
|
187
|
+
# Create tasks in database
|
188
|
+
created_tasks = []
|
189
|
+
task_id_mapping = {} # Map array index to actual task ID
|
190
|
+
|
191
|
+
for i, task_data in enumerate(tasks_data):
|
192
|
+
# Calculate due date based on goal target date
|
193
|
+
due_date = None
|
194
|
+
if goal.target_date:
|
195
|
+
# Distribute tasks evenly before target date
|
196
|
+
days_until_target = (goal.target_date - datetime.now()).days
|
197
|
+
task_offset = (days_until_target / len(tasks_data)) * (i + 1)
|
198
|
+
due_date = datetime.now() + timedelta(days=task_offset)
|
199
|
+
|
200
|
+
task = self.task_mgr.create_task(
|
201
|
+
title=task_data['title'],
|
202
|
+
description=task_data['description'],
|
203
|
+
estimated_hours=task_data.get('estimated_hours'),
|
204
|
+
priority=task_data.get('priority', 3),
|
205
|
+
category=task_data.get('category'),
|
206
|
+
due_date=due_date,
|
207
|
+
parent_goal_id=goal_id,
|
208
|
+
dependencies=[] # Will update after all tasks created
|
209
|
+
)
|
210
|
+
created_tasks.append(task)
|
211
|
+
task_id_mapping[i] = task.id
|
212
|
+
|
213
|
+
# Update dependencies
|
214
|
+
for i, task_data in enumerate(tasks_data):
|
215
|
+
if task_data.get('dependencies'):
|
216
|
+
dep_ids = [task_id_mapping[dep_idx] for dep_idx in task_data['dependencies']
|
217
|
+
if dep_idx in task_id_mapping]
|
218
|
+
created_tasks[i].dependencies = dep_ids
|
219
|
+
|
220
|
+
self.session.commit()
|
221
|
+
return created_tasks
|
222
|
+
|
223
|
+
except Exception as e:
|
224
|
+
print(f"Error breaking down goal: {e}")
|
225
|
+
return None
|
226
|
+
|
227
|
+
def suggest_next_tasks(self, goal_id, num_tasks=3):
|
228
|
+
"""Use AI to suggest next tasks based on current progress"""
|
229
|
+
goal = self.get_goal(goal_id)
|
230
|
+
if not goal:
|
231
|
+
return None
|
232
|
+
|
233
|
+
existing_tasks = self.task_mgr.get_tasks_by_goal(goal_id)
|
234
|
+
completed_tasks = [t for t in existing_tasks if t.status == 'completed']
|
235
|
+
pending_tasks = [t for t in existing_tasks if t.status in ['pending', 'in_progress']]
|
236
|
+
|
237
|
+
completed_str = "\n".join([f"- {t.title}" for t in completed_tasks[:10]])
|
238
|
+
pending_str = "\n".join([f"- {t.title} ({t.status})" for t in pending_tasks[:10]])
|
239
|
+
|
240
|
+
prompt = f"""Given this goal and current progress, suggest {num_tasks} next actionable tasks:
|
241
|
+
|
242
|
+
GOAL: {goal.title}
|
243
|
+
DESCRIPTION: {goal.description}
|
244
|
+
PROGRESS: {goal.progress_percentage}%
|
245
|
+
|
246
|
+
COMPLETED TASKS:
|
247
|
+
{completed_str or 'None yet'}
|
248
|
+
|
249
|
+
PENDING/IN-PROGRESS TASKS:
|
250
|
+
{pending_str or 'None'}
|
251
|
+
|
252
|
+
Suggest {num_tasks} new tasks that would best advance this goal right now. Consider:
|
253
|
+
- What's already been accomplished
|
254
|
+
- What's currently in progress
|
255
|
+
- Natural next steps
|
256
|
+
- Quick wins vs. strategic moves
|
257
|
+
|
258
|
+
Return as JSON array with same format as before."""
|
259
|
+
|
260
|
+
try:
|
261
|
+
message = self.client.messages.create(
|
262
|
+
model=self.model,
|
263
|
+
max_tokens=2000,
|
264
|
+
messages=[{"role": "user", "content": prompt}]
|
265
|
+
)
|
266
|
+
|
267
|
+
response_text = message.content[0].text.strip()
|
268
|
+
if response_text.startswith('```'):
|
269
|
+
response_text = response_text.split('```')[1]
|
270
|
+
if response_text.startswith('json'):
|
271
|
+
response_text = response_text[4:]
|
272
|
+
response_text = response_text.strip()
|
273
|
+
|
274
|
+
tasks_data = json.loads(response_text)
|
275
|
+
|
276
|
+
created_tasks = []
|
277
|
+
for task_data in tasks_data:
|
278
|
+
task = self.task_mgr.create_task(
|
279
|
+
title=task_data['title'],
|
280
|
+
description=task_data['description'],
|
281
|
+
estimated_hours=task_data.get('estimated_hours'),
|
282
|
+
priority=task_data.get('priority', 3),
|
283
|
+
category=task_data.get('category'),
|
284
|
+
parent_goal_id=goal_id
|
285
|
+
)
|
286
|
+
created_tasks.append(task)
|
287
|
+
|
288
|
+
return created_tasks
|
289
|
+
|
290
|
+
except Exception as e:
|
291
|
+
print(f"Error suggesting tasks: {e}")
|
292
|
+
return None
|
293
|
+
|
294
|
+
def create_goal_hierarchy(self, yearly_goal_title, yearly_goal_description):
|
295
|
+
"""Create a full goal hierarchy: yearly -> quarterly -> monthly"""
|
296
|
+
# Create yearly goal
|
297
|
+
yearly_goal = self.create_goal(
|
298
|
+
title=yearly_goal_title,
|
299
|
+
description=yearly_goal_description,
|
300
|
+
horizon='yearly',
|
301
|
+
target_date=datetime.now() + timedelta(days=365)
|
302
|
+
)
|
303
|
+
|
304
|
+
# Use AI to break into quarterly goals
|
305
|
+
prompt = f"""Break down this yearly goal into 4 quarterly goals:
|
306
|
+
|
307
|
+
YEARLY GOAL: {yearly_goal_title}
|
308
|
+
DESCRIPTION: {yearly_goal_description}
|
309
|
+
|
310
|
+
Create 4 quarterly milestones (Q1, Q2, Q3, Q4) that would logically lead to achieving this yearly goal.
|
311
|
+
|
312
|
+
Return as JSON:
|
313
|
+
[
|
314
|
+
{{
|
315
|
+
"title": "Q1 goal title",
|
316
|
+
"description": "What to achieve in Q1",
|
317
|
+
"success_criteria": "How to measure success"
|
318
|
+
}},
|
319
|
+
...
|
320
|
+
]"""
|
321
|
+
|
322
|
+
try:
|
323
|
+
message = self.client.messages.create(
|
324
|
+
model=self.model,
|
325
|
+
max_tokens=2000,
|
326
|
+
messages=[{"role": "user", "content": prompt}]
|
327
|
+
)
|
328
|
+
|
329
|
+
response_text = message.content[0].text.strip()
|
330
|
+
if response_text.startswith('```'):
|
331
|
+
response_text = response_text.split('```')[1]
|
332
|
+
if response_text.startswith('json'):
|
333
|
+
response_text = response_text[4:]
|
334
|
+
response_text = response_text.strip()
|
335
|
+
|
336
|
+
quarterly_goals_data = json.loads(response_text)
|
337
|
+
|
338
|
+
quarterly_goals = []
|
339
|
+
for i, qgoal_data in enumerate(quarterly_goals_data):
|
340
|
+
target = datetime.now() + timedelta(days=90 * (i + 1))
|
341
|
+
qgoal = self.create_goal(
|
342
|
+
title=qgoal_data['title'],
|
343
|
+
description=qgoal_data['description'],
|
344
|
+
horizon='quarterly',
|
345
|
+
target_date=target,
|
346
|
+
success_criteria=qgoal_data.get('success_criteria'),
|
347
|
+
parent_goal_id=yearly_goal.id
|
348
|
+
)
|
349
|
+
quarterly_goals.append(qgoal)
|
350
|
+
|
351
|
+
return {
|
352
|
+
'yearly': yearly_goal,
|
353
|
+
'quarterly': quarterly_goals
|
354
|
+
}
|
355
|
+
|
356
|
+
except Exception as e:
|
357
|
+
print(f"Error creating goal hierarchy: {e}")
|
358
|
+
return {'yearly': yearly_goal, 'quarterly': []}
|
359
|
+
|
360
|
+
def close(self):
|
361
|
+
"""Close database session"""
|
362
|
+
self.session.close()
|
363
|
+
self.task_mgr.close()
|
agent/research.py
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
import anthropic
|
2
|
+
import os
|
3
|
+
from datetime import datetime
|
4
|
+
from agent.models import ResearchItem, get_session
|
5
|
+
|
6
|
+
class ResearchAgent:
|
7
|
+
def __init__(self):
|
8
|
+
api_key = os.getenv('ANTHROPIC_API_KEY')
|
9
|
+
if not api_key:
|
10
|
+
raise ValueError("ANTHROPIC_API_KEY environment variable not set")
|
11
|
+
|
12
|
+
self.client = anthropic.Anthropic(api_key=api_key)
|
13
|
+
self.model = "claude-sonnet-4-20250514"
|
14
|
+
self.session = get_session()
|
15
|
+
|
16
|
+
def research_topic(self, topic, business_goal, depth="standard"):
|
17
|
+
"""Research a topic using Claude's web search capability"""
|
18
|
+
|
19
|
+
depth_guidance = {
|
20
|
+
"quick": "Use 1-2 web searches to get a quick overview",
|
21
|
+
"standard": "Use 3-5 web searches to get comprehensive information",
|
22
|
+
"deep": "Use 5-10 web searches for thorough, multi-angle research"
|
23
|
+
}
|
24
|
+
|
25
|
+
prompt = f"""Research this topic for my business:
|
26
|
+
|
27
|
+
TOPIC: {topic}
|
28
|
+
|
29
|
+
BUSINESS GOAL: {business_goal}
|
30
|
+
|
31
|
+
RESEARCH DEPTH: {depth_guidance.get(depth, depth_guidance['standard'])}
|
32
|
+
|
33
|
+
Please research this topic and provide:
|
34
|
+
|
35
|
+
1. **Key Findings** - Most important insights (3-5 bullet points)
|
36
|
+
2. **Trends** - Current trends or patterns
|
37
|
+
3. **Opportunities** - How this could benefit my business
|
38
|
+
4. **Risks/Challenges** - What to watch out for
|
39
|
+
5. **Action Items** - 2-3 specific next steps I should take
|
40
|
+
6. **Sources** - List the key sources you used
|
41
|
+
|
42
|
+
Use web search to gather current information. Be thorough and practical."""
|
43
|
+
|
44
|
+
try:
|
45
|
+
message = self.client.messages.create(
|
46
|
+
model=self.model,
|
47
|
+
max_tokens=4000,
|
48
|
+
messages=[{"role": "user", "content": prompt}]
|
49
|
+
)
|
50
|
+
|
51
|
+
research_text = message.content[0].text
|
52
|
+
|
53
|
+
# Save to database
|
54
|
+
research_item = ResearchItem(
|
55
|
+
title=topic,
|
56
|
+
summary=research_text,
|
57
|
+
category="general",
|
58
|
+
date_found=datetime.now(),
|
59
|
+
raw_data={"prompt": prompt, "depth": depth}
|
60
|
+
)
|
61
|
+
self.session.add(research_item)
|
62
|
+
self.session.commit()
|
63
|
+
|
64
|
+
return {
|
65
|
+
'research_id': research_item.id,
|
66
|
+
'topic': topic,
|
67
|
+
'findings': research_text,
|
68
|
+
'date': datetime.now()
|
69
|
+
}
|
70
|
+
|
71
|
+
except Exception as e:
|
72
|
+
return {
|
73
|
+
'error': str(e),
|
74
|
+
'topic': topic
|
75
|
+
}
|
76
|
+
|
77
|
+
def research_competitors(self, business_domain, your_offering):
|
78
|
+
"""Research competitive landscape"""
|
79
|
+
|
80
|
+
prompt = f"""Research the competitive landscape for my business:
|
81
|
+
|
82
|
+
MY BUSINESS DOMAIN: {business_domain}
|
83
|
+
MY OFFERING: {your_offering}
|
84
|
+
|
85
|
+
Use web search to find and analyze:
|
86
|
+
|
87
|
+
1. **Top 5-7 Competitors**
|
88
|
+
- Company name
|
89
|
+
- What they offer
|
90
|
+
- Their key strengths
|
91
|
+
- Pricing approach (if public)
|
92
|
+
- Market position
|
93
|
+
|
94
|
+
2. **Competitive Gaps**
|
95
|
+
- What are competitors NOT doing well?
|
96
|
+
- Underserved customer needs
|
97
|
+
- Opportunities for differentiation
|
98
|
+
|
99
|
+
3. **Market Trends**
|
100
|
+
- Where is this market heading?
|
101
|
+
- Emerging technologies or approaches
|
102
|
+
- Changing customer expectations
|
103
|
+
|
104
|
+
4. **Strategic Recommendations**
|
105
|
+
- How should we position ourselves?
|
106
|
+
- What should we focus on?
|
107
|
+
- What should we avoid?
|
108
|
+
|
109
|
+
Be specific and cite sources where possible."""
|
110
|
+
|
111
|
+
try:
|
112
|
+
message = self.client.messages.create(
|
113
|
+
model=self.model,
|
114
|
+
max_tokens=5000,
|
115
|
+
messages=[{"role": "user", "content": prompt}]
|
116
|
+
)
|
117
|
+
|
118
|
+
research_text = message.content[0].text
|
119
|
+
|
120
|
+
# Save to database
|
121
|
+
research_item = ResearchItem(
|
122
|
+
title=f"Competitive Analysis: {business_domain}",
|
123
|
+
summary=research_text,
|
124
|
+
category="competitor",
|
125
|
+
date_found=datetime.now(),
|
126
|
+
raw_data={
|
127
|
+
"domain": business_domain,
|
128
|
+
"offering": your_offering
|
129
|
+
}
|
130
|
+
)
|
131
|
+
self.session.add(research_item)
|
132
|
+
self.session.commit()
|
133
|
+
|
134
|
+
return {
|
135
|
+
'research_id': research_item.id,
|
136
|
+
'findings': research_text,
|
137
|
+
'date': datetime.now()
|
138
|
+
}
|
139
|
+
|
140
|
+
except Exception as e:
|
141
|
+
return {'error': str(e)}
|
142
|
+
|
143
|
+
def get_research_history(self, category=None, limit=10):
|
144
|
+
"""Retrieve past research"""
|
145
|
+
query = self.session.query(ResearchItem)
|
146
|
+
|
147
|
+
if category:
|
148
|
+
query = query.filter(ResearchItem.category == category)
|
149
|
+
|
150
|
+
items = query.order_by(ResearchItem.date_found.desc()).limit(limit).all()
|
151
|
+
return [item.to_dict() for item in items]
|
152
|
+
|
153
|
+
def weekly_intelligence_report(self, business_focus_areas):
|
154
|
+
"""Generate a weekly intelligence digest"""
|
155
|
+
from datetime import timedelta
|
156
|
+
week_ago = datetime.now() - timedelta(days=7)
|
157
|
+
|
158
|
+
recent_research = self.session.query(ResearchItem).filter(
|
159
|
+
ResearchItem.date_found >= week_ago
|
160
|
+
).all()
|
161
|
+
|
162
|
+
research_summary = "\n".join([
|
163
|
+
f"- {r.title} ({r.category})"
|
164
|
+
for r in recent_research[:10]
|
165
|
+
])
|
166
|
+
|
167
|
+
prompt = f"""Create a weekly intelligence report for my business:
|
168
|
+
|
169
|
+
FOCUS AREAS: {', '.join(business_focus_areas)}
|
170
|
+
|
171
|
+
RECENT RESEARCH CONDUCTED:
|
172
|
+
{research_summary or 'No research this week'}
|
173
|
+
|
174
|
+
Generate a concise intelligence brief covering:
|
175
|
+
|
176
|
+
1. **Key Insights** - Top 3 takeaways from this week
|
177
|
+
2. **Trending Topics** - What's gaining attention in our space
|
178
|
+
3. **Competitive Intelligence** - Notable competitor moves
|
179
|
+
4. **Opportunities** - What we should act on
|
180
|
+
5. **Threats** - What we should watch
|
181
|
+
6. **Next Week's Research Priorities** - What to investigate next
|
182
|
+
|
183
|
+
Keep it scannable and actionable."""
|
184
|
+
|
185
|
+
try:
|
186
|
+
message = self.client.messages.create(
|
187
|
+
model=self.model,
|
188
|
+
max_tokens=3000,
|
189
|
+
messages=[{"role": "user", "content": prompt}]
|
190
|
+
)
|
191
|
+
|
192
|
+
return message.content[0].text
|
193
|
+
|
194
|
+
except Exception as e:
|
195
|
+
return f"Error generating intelligence report: {e}"
|
196
|
+
|
197
|
+
def close(self):
|
198
|
+
"""Close database session"""
|
199
|
+
self.session.close()
|