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:
+77
-35
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user