forked from 0xWheatyz/SPARC
af4114969a
Replace direct Anthropic API integration with OpenRouter to enable more flexible LLM provider access while maintaining Claude 3.5 Sonnet. Changes: - Replace anthropic package with openai in requirements.txt - Update config to use OPENROUTER_API_KEY instead of ANTHROPIC_API_KEY - Migrate LLMAnalyzer from Anthropic client to OpenAI client with OpenRouter base URL (https://openrouter.ai/api/v1) - Update model identifier to OpenRouter format: anthropic/claude-3.5-sonnet - Convert API calls from messages.create() to chat.completions.create() - Update response parsing to match OpenAI format - Rename API key parameter in CompanyAnalyzer from anthropic_api_key to openrouter_api_key - Update all tests to mock OpenAI client instead of Anthropic - Fix client initialization to accept direct API key parameter 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
119 lines
4.3 KiB
Python
119 lines
4.3 KiB
Python
"""LLM integration for patent analysis using OpenRouter."""
|
|
|
|
from openai import OpenAI
|
|
from SPARC import config
|
|
from typing import Dict
|
|
|
|
|
|
class LLMAnalyzer:
|
|
"""Handles LLM-based analysis of patent content."""
|
|
|
|
def __init__(self, api_key: str | None = None, test_mode: bool = False):
|
|
"""Initialize the LLM analyzer.
|
|
|
|
Args:
|
|
api_key: OpenRouter API key. If None, will attempt to load from config.
|
|
test_mode: If True, print prompts instead of making API calls
|
|
"""
|
|
self.test_mode = test_mode
|
|
|
|
if (api_key or config.openrouter_api_key) and not test_mode:
|
|
self.client = OpenAI(
|
|
api_key=api_key or config.openrouter_api_key,
|
|
base_url="https://openrouter.ai/api/v1"
|
|
)
|
|
self.model = "anthropic/claude-3.5-sonnet"
|
|
else:
|
|
self.client = None
|
|
|
|
def analyze_patent_content(self, patent_content: str, company_name: str) -> str:
|
|
"""Analyze patent content to estimate company innovation and performance.
|
|
|
|
Args:
|
|
patent_content: Minimized patent text (abstract, claims, summary)
|
|
company_name: Name of the company for context
|
|
|
|
Returns:
|
|
Analysis text describing innovation quality and potential impact
|
|
"""
|
|
prompt = f"""You are a patent analyst evaluating {company_name}'s innovation strategy.
|
|
|
|
Analyze the following patent content and provide insights on:
|
|
1. Innovation quality and novelty
|
|
2. Technical complexity and defensibility
|
|
3. Market potential and commercial viability
|
|
4. Strategic positioning relative to industry trends
|
|
|
|
Patent Content:
|
|
{patent_content}
|
|
|
|
Provide a concise analysis (2-3 paragraphs) focusing on what this patent reveals about the company's technical direction and competitive advantage."""
|
|
|
|
if self.test_mode:
|
|
print("=" * 80)
|
|
print("TEST MODE - Prompt that would be sent to LLM:")
|
|
print("=" * 80)
|
|
print(prompt)
|
|
print("=" * 80)
|
|
return "[TEST MODE - No API call made]"
|
|
|
|
if self.client:
|
|
response = self.client.chat.completions.create(
|
|
model=self.model,
|
|
max_tokens=1024,
|
|
messages=[{"role": "user", "content": prompt}],
|
|
)
|
|
return response.choices[0].message.content
|
|
|
|
def analyze_patent_portfolio(
|
|
self, patents_data: list[Dict[str, str]], company_name: str
|
|
) -> str:
|
|
"""Analyze multiple patents to estimate overall company performance.
|
|
|
|
Args:
|
|
patents_data: List of dicts, each containing 'patent_id' and 'content'
|
|
company_name: Name of the company being analyzed
|
|
|
|
Returns:
|
|
Comprehensive analysis of company's innovation trajectory and outlook
|
|
"""
|
|
# Combine all patent summaries
|
|
portfolio_summary = []
|
|
for idx, patent in enumerate(patents_data, 1):
|
|
portfolio_summary.append(
|
|
f"Patent {idx} ({patent['patent_id']}):\n{patent['content']}"
|
|
)
|
|
|
|
combined_content = "\n\n---\n\n".join(portfolio_summary)
|
|
|
|
prompt = f"""You are analyzing {company_name}'s patent portfolio to estimate their future performance and innovation trajectory.
|
|
|
|
You have {len(patents_data)} recent patents to analyze. Evaluate the portfolio holistically:
|
|
|
|
1. Innovation Trends: What technology areas are they focusing on?
|
|
2. Strategic Direction: What does this reveal about their business strategy?
|
|
3. Competitive Position: How defensible are these innovations?
|
|
4. Market Outlook: What market opportunities do these patents target?
|
|
5. Performance Forecast: Based on this innovation activity, what's your assessment of their likely performance?
|
|
|
|
Patent Portfolio:
|
|
{combined_content}
|
|
|
|
Provide a comprehensive analysis (4-5 paragraphs) with a final verdict on the company's innovation strength and performance outlook."""
|
|
|
|
if self.test_mode:
|
|
print(prompt)
|
|
return "[TEST MODE]"
|
|
|
|
try:
|
|
response = self.client.chat.completions.create(
|
|
model=self.model,
|
|
max_tokens=2048,
|
|
messages=[{"role": "user", "content": prompt}],
|
|
)
|
|
|
|
return response.choices[0].message.content
|
|
except AttributeError:
|
|
return prompt
|
|
|