Encyclopedia / art_explorer.py
baconnier's picture
Update art_explorer.py
092d495 verified
from typing import Dict, Any, List, Optional
from openai import OpenAI
import json
from pydantic import BaseModel, Field
from prompts import SYSTEM_PROMPT, format_exploration_prompt, DEFAULT_RESPONSE
class ExplorationNode(BaseModel):
id: Optional[str] = None
title: str
description: str
connections: List[Dict[str, Any]] = Field(default_factory=list)
depth: int = 0
class ExplorationPath(BaseModel):
nodes: List[ExplorationNode]
query: str
domain: Optional[str] = None
class Config:
populate_by_name = True
arbitrary_types_allowed = True
def transform_response_to_nodes(api_response: Dict[str, Any]) -> List[Dict[str, Any]]:
"""Transform the API response into a list of ExplorationNode-compatible dictionaries"""
nodes = []
# Add main exploration summary as root node
if "exploration_summary" in api_response:
nodes.append({
"id": "root",
"title": "Exploration Overview",
"description": api_response["exploration_summary"]["current_context"],
"depth": 0,
"connections": []
})
# Transform standard axes into nodes
if "knowledge_axes" in api_response and "standard_axes" in api_response["knowledge_axes"]:
for axis in api_response["knowledge_axes"]["standard_axes"]:
# Create node for the axis itself
axis_node = {
"id": f"axis_{axis['name']}",
"title": axis['name'],
"description": f"Standard exploration axis: {axis['name']}",
"depth": 1,
"connections": []
}
nodes.append(axis_node)
# Create nodes for potential values
for idx, value in enumerate(axis.get("potential_values", [])):
value_node = {
"id": f"value_{axis['name']}_{idx}",
"title": value["value"],
"description": value["contextual_rationale"],
"depth": 2,
"connections": []
}
nodes.append(value_node)
# Add connection to axis node
axis_node["connections"].append({
"target_id": value_node["id"],
"relevance_score": value["relevance_score"]
})
# Transform emergent axes into nodes
if "knowledge_axes" in api_response and "emergent_axes" in api_response["knowledge_axes"]:
for e_axis in api_response["knowledge_axes"]["emergent_axes"]:
# Create node for emergent axis
e_axis_node = {
"id": f"emergent_{e_axis['name']}",
"title": f"{e_axis['name']} (Emergent)",
"description": f"Emergent axis derived from {e_axis['parent_axis']}",
"depth": 2,
"connections": []
}
nodes.append(e_axis_node)
# Create nodes for innovative values
for idx, value in enumerate(e_axis.get("innovative_values", [])):
value_node = {
"id": f"innovative_{e_axis['name']}_{idx}",
"title": value["value"],
"description": value["discovery_potential"],
"depth": 3,
"connections": []
}
nodes.append(value_node)
# Add connection to emergent axis node
e_axis_node["connections"].append({
"target_id": value_node["id"],
"innovation_score": value["innovation_score"]
})
return nodes
class ExplorationPathGenerator:
def __init__(self, api_key: str):
self.client = OpenAI(
api_key=api_key,
base_url="https://api.groq.com/openai/v1"
)
def generate_exploration_path(
self,
query: str,
selected_path: List[Dict[str, Any]] = None,
exploration_parameters: Dict[str, Any] = None
) -> Dict[str, Any]:
"""Generate an exploration path based on the query and parameters"""
try:
print("\n=== Starting API Request ===")
selected_path = selected_path or []
exploration_parameters = exploration_parameters or {}
formatted_prompt = format_exploration_prompt(
user_query=query,
selected_path=selected_path,
exploration_parameters=exploration_parameters
)
print("\n=== Formatted Request ===")
print("System Prompt:", SYSTEM_PROMPT[:200] + "...")
print("\nFormatted Prompt (excerpt):", formatted_prompt[:200] + "...")
response = self.client.chat.completions.create(
model="mixtral-8x7b-32768",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": formatted_prompt}
],
temperature=0.7,
max_tokens=2000
)
print("\n=== API Response ===")
print("Raw response content:", response.choices[0].message.content)
try:
result = json.loads(response.choices[0].message.content)
print("\n=== Parsed Response ===")
print(json.dumps(result, indent=2))
# Transform the API response into nodes
nodes = transform_response_to_nodes(result)
# Create ExplorationPath with transformed nodes
exploration_path = ExplorationPath(
nodes=nodes,
query=query,
domain=exploration_parameters.get("domain")
)
final_result = exploration_path.model_dump()
print("\n=== Final Result ===")
print(json.dumps(final_result, indent=2))
return final_result
except json.JSONDecodeError as e:
print(f"\n=== JSON Parse Error ===\n{str(e)}")
print("Using default response")
return {
"nodes": [],
"query": query,
"domain": exploration_parameters.get("domain")
}
except Exception as e:
print(f"\n=== Error ===\n{str(e)}")
return {
"error": str(e),
"status": "failed",
"message": "Failed to generate exploration path",
"default_response": DEFAULT_RESPONSE
}