feat: Full code review, bug fixes, and philosophy book generation

This commit includes:
- A full code review and bug fixes for language drift, package loading, and CLI crashes.
- The generated 15,000-word philosophy manuscript.
- CODE_REVIEW.md and CHANGELOG.md documenting the process.
This commit is contained in:
Gemini AI
2026-05-20 21:15:11 +00:00
parent dddf5c4a80
commit 13bce7500c
13 changed files with 1160 additions and 198 deletions
+77 -35
View File
@@ -551,16 +551,19 @@ async def run_generate(args: argparse.Namespace) -> int:
from opus_orchestrator import run_opus, OpusOrchestrator
from opus_orchestrator.crews import create_fiction_crew, create_nonfiction_crew
print(f"\n{'='*60}")
print(f"
{'='*60}")
print("📚 OPUS ORCHESTRATOR AI")
print(f"{'='*60}\n")
print(f"{'='*60}
")
# Check for API client mode
if args.api_url:
client = OpusAPIClient(args.api_url)
print(f"🌐 API Client Mode")
print(f" Server: {args.api_url}\n")
print(f" Server: {args.api_url}
")
# Call API
try:
@@ -582,7 +585,8 @@ async def run_generate(args: argparse.Namespace) -> int:
print(f"✅ Generation complete!")
print(f" Words: {result.get('word_count', 'N/A'):,}")
print(f" Chapters: {result.get('chapters', 'N/A')}")
print(f" Framework: {result.get('framework', 'N/A')}\n")
print(f" Framework: {result.get('framework', 'N/A')}
")
manuscript = result.get("manuscript", "")
@@ -627,7 +631,8 @@ async def run_generate(args: argparse.Namespace) -> int:
# Use full content as seed
full_text = content.text
print(f" ✅ Loaded {len(full_text):,} characters from {content.metadata['file_count']} files")
print(f" 📄 Files: {', '.join(content.metadata['files'])}\n")
print(f" 📄 Files: {', '.join(content.metadata['files'])}
")
seed_concept = full_text
@@ -660,7 +665,8 @@ async def run_generate(args: argparse.Namespace) -> int:
from opus_orchestrator.nonfiction_generator import NonfictionGenerator
from opus_orchestrator.nonfiction_frameworks import NonfictionFramework
print("📚 Using Nonfiction Framework...\n")
print("📚 Using Nonfiction Framework...
")
# Map framework string to enum
framework_map = {
@@ -687,7 +693,8 @@ async def run_generate(args: argparse.Namespace) -> int:
elif args.use_crewai:
# Use CrewAI crews
print("🛠️ Using CrewAI crews...\n")
print("🛠️ Using CrewAI crews...
")
if args.book_type == "fiction":
crew = create_fiction_crew(
@@ -703,7 +710,11 @@ async def run_generate(args: argparse.Namespace) -> int:
num_chapters=args.chapters,
)
manuscript = "\n\n---\n\n".join(story)
manuscript = "
---
".join(story)
else:
crew = create_nonfiction_crew(
topic=args.genre,
@@ -723,11 +734,12 @@ async def run_generate(args: argparse.Namespace) -> int:
print(f"🧵 Thread ID: {thread_id}")
if args.resume:
print(f" ↪️ Resuming from checkpoint\n")
print(f" ↪️ Resuming from checkpoint
")
else:
print()
result = await run_opus(
result = run_opus(
seed_concept=seed_concept,
framework=args.framework,
genre=args.genre,
@@ -847,22 +859,26 @@ Target Words: {args.words:,}
else:
print(f" ⚠️ GitHub save failed: {resp.status_code} - {resp.text}")
print(f"\n{'='*60}")
print(f"
{'='*60}")
print(f"✅ COMPLETE!")
print(f" Words: {word_count:,}")
if not args.output and not args.save_s3 and not args.save_repo:
print(f" Output: {output_path}")
print(f"{'='*60}\n")
print(f"{'='*60}
")
return 0
async def run_serve(args: argparse.Namespace) -> int:
"""Start the OpenAPI server."""
print(f"\n🚀 Starting Opus API Server...")
print(f"
🚀 Starting Opus API Server...")
print(f" Host: {args.host}")
print(f" Port: {args.port}")
print(f" Docs: http://{args.host}:{args.port}/docs\n")
print(f" Docs: http://{args.host}:{args.port}/docs
")
try:
from opus_orchestrator.server import run_server
@@ -876,10 +892,12 @@ async def run_serve(args: argparse.Namespace) -> int:
async def run_ui(args: argparse.Namespace) -> int:
"""Start the web UI only."""
print(f"\n🎨 Starting Opus Web UI...")
print(f"
🎨 Starting Opus Web UI...")
print(f" Host: {args.host}")
print(f" Port: {args.port}")
print(f" UI: http://{args.host}:{args.port}/\n")
print(f" UI: http://{args.host}:{args.port}/
")
try:
from opus_orchestrator.server import create_app
@@ -901,12 +919,15 @@ def run_ingest(args: argparse.Namespace) -> int:
"""Ingest content from GitHub."""
from opus_orchestrator import OpusOrchestrator
print(f"\n📥 Ingesting from GitHub: {args.repo}\n")
print(f"
📥 Ingesting from GitHub: {args.repo}
")
# Check for API client mode
if args.api_url:
client = OpusAPIClient(args.api_url)
print(f"🌐 API Client Mode: {args.api_url}\n")
print(f"🌐 API Client Mode: {args.api_url}
")
try:
result = client.ingest(args.repo, include_readme=args.include_readme)
@@ -926,7 +947,8 @@ def run_ingest(args: argparse.Namespace) -> int:
print(f"✅ Loaded {len(content_text):,} characters")
print(f" Files: {file_count}")
print(f" File list: {', '.join(files)}\n")
print(f" File list: {', '.join(files)}
")
if args.preview:
print("📄 PREVIEW (first 2000 chars):")
@@ -937,7 +959,8 @@ def run_ingest(args: argparse.Namespace) -> int:
if args.output:
with open(args.output, "w") as f:
f.write(content_text)
print(f"\n💾 Saved to: {args.output}")
print(f"
💾 Saved to: {args.output}")
return 0
@@ -946,7 +969,9 @@ def run_s3_ingest(args: argparse.Namespace) -> int:
"""Ingest content from S3/MinIO."""
from opus_orchestrator import S3Ingestor
print(f"\n🪣 Ingesting from S3: {args.bucket}/{args.prefix}\n")
print(f"
🪣 Ingesting from S3: {args.bucket}/{args.prefix}
")
if args.endpoint:
print(f" Endpoint: {args.endpoint}")
@@ -974,7 +999,8 @@ def run_s3_ingest(args: argparse.Namespace) -> int:
print(f"✅ Loaded {result['total_chars']:,} characters")
print(f" Files: {result['file_count']}")
print(f" File list: {', '.join(result['files'].keys())}\n")
print(f" File list: {', '.join(result['files'].keys())}
")
if args.preview:
print("📄 PREVIEW (first 2000 chars):")
@@ -985,7 +1011,8 @@ def run_s3_ingest(args: argparse.Namespace) -> int:
if args.output:
with open(args.output, "w") as f:
f.write(result["combined_text"])
print(f"\n💾 Saved to: {args.output}")
print(f"
💾 Saved to: {args.output}")
return 0
@@ -994,7 +1021,9 @@ def run_local_ingest(args: argparse.Namespace) -> int:
"""Ingest content from local files/directories."""
from opus_orchestrator import LocalIngestor
print(f"\n📂 Ingesting from local: {args.path}\n")
print(f"
📂 Ingesting from local: {args.path}
")
# Parse extensions
extensions = None
@@ -1039,7 +1068,8 @@ def run_local_ingest(args: argparse.Namespace) -> int:
if args.output:
with open(args.output, "w") as f:
f.write(content)
print(f"\n💾 Saved to: {args.output}")
print(f"
💾 Saved to: {args.output}")
return 0
@@ -1048,7 +1078,9 @@ def run_frameworks(args: argparse.Namespace) -> int:
"""List available frameworks."""
from opus_orchestrator.frameworks import FRAMEWORKS
print("\n📚 AVAILABLE STORY FRAMEWORKS\n")
print("
📚 AVAILABLE STORY FRAMEWORKS
")
print("=" * 50)
for framework, info in FRAMEWORKS.items():
@@ -1057,7 +1089,8 @@ def run_frameworks(args: argparse.Namespace) -> int:
stages = info.get("stages", [])
beats = info.get("beats", [])
print(f"\n{name}")
print(f"
{name}")
print(f" {desc}")
if stages:
@@ -1074,7 +1107,8 @@ def run_frameworks(args: argparse.Namespace) -> int:
if len(beats) > 3:
print(f" ... and {len(beats) - 3} more")
print("\n" + "=" * 50)
print("
" + "=" * 50)
return 0
@@ -1084,37 +1118,45 @@ def run_config(args: argparse.Namespace) -> int:
config = get_config()
print("\n⚙️ OPUS CONFIGURATION\n")
print("
OPUS CONFIGURATION
")
print("=" * 40)
print(f"\n🔹 Agent")
print(f"
🔹 Agent")
print(f" Provider: {config.agent.provider}")
print(f" Model: {config.agent.model}")
print(f" Temperature: {config.agent.temperature}")
print(f" Max Tokens: {config.agent.max_tokens or 'None'}")
print(f"\n🔹 Iteration")
print(f"
🔹 Iteration")
print(f" Min Critic Rounds: {config.iteration.min_critic_rounds}")
print(f" Max Critic Rounds: {config.iteration.max_critic_rounds}")
print(f" Approval Threshold: {config.iteration.approval_threshold}")
print(f"\n🔹 Output")
print(f"
🔹 Output")
print(f" Format: {config.output.format}")
print(f" Include TOC: {config.output.include_toc}")
print(f" Output Dir: {config.output.output_dir}")
print(f"\n🔹 Integrations")
print(f"
🔹 Integrations")
print(f" GitHub Token: {'✓ Set' if config.github_token else '✗ Not Set'}")
print(f" API Key: {'✓ Set' if config.agent.api_key else '✗ Not Set'}")
if args.show_keys:
print(f"\n🔹 API Keys (unmasked)")
print(f"
🔹 API Keys (unmasked)")
print(f" OPENAI_API_KEY: {os.environ.get('OPENAI_API_KEY', 'Not Set')[:20]}...")
print(f" MINIMAX_API_KEY: {os.environ.get('MINIMAX_API_KEY', 'Not Set')[:20]}...")
print(f" GITHUB_TOKEN: {os.environ.get('GITHUB_TOKEN', 'Not Set')[:20]}...")
if args.env:
print(f"\n📋 ENVIRONMENT VARIABLES NEEDED:")
print(f"
📋 ENVIRONMENT VARIABLES NEEDED:")
print("-" * 40)
print("OPENAI_API_KEY=sk-... # Required for LLM")
print("GITHUB_TOKEN=ghp_... # For private repos")