| Server IP : 3.147.158.171 / Your IP : 216.73.216.216 Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.21 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /tsai/www/html/api.turmansolutions.ai/app/services/ |
Upload File : |
"""Shared corrections orchestration.
The corrections *generation* logic lives in `ChatService.generate_corrections`.
This module wraps the surrounding orchestration — picking a model, generating the
corrections, optionally updating the article body, and posting the threaded
corrections comment — so it can be reused by both the standalone
`improve_article.py` script and the inline article-creation flow.
The core deliberately accepts `fact_check_text` and `parent_comment_id` as
explicit inputs rather than re-fetching the fact-check comment from WordPress.
On sites that hold comments in moderation (e.g. scike), an unauthenticated GET
does not return a just-posted held comment, so callers that already hold these
values in memory (article creation) must pass them in directly.
"""
from __future__ import annotations
import logging
import random
from typing import Any, Dict, List, Optional
from app.services.ll_model_service import LLModelService
from app.services import usage_history
def run_corrections_core(
wp_service,
chat_service,
site,
wp_token: str,
post_id: int,
article_title: str,
article_body: str,
fact_check_text: str,
parent_comment_id: Optional[int],
images: Optional[List[str]],
search_results: Optional[List[Dict[str, Any]]],
character,
corrections_model_name: Optional[str] = None,
) -> Dict[str, Any]:
"""Generate and post a corrections follow-up to a fact-check.
Picks a model (random 50/50 between Claude Sonnet 4.6 and GPT-5.5 when none
is given), generates the corrections, updates the article body when the
fact-check surfaced genuine factual errors, and posts the corrections comment
threaded under the fact-check.
Returns a dict: {'body_updated': bool, 'model_name': str, 'provider_name': str}.
"""
if not corrections_model_name:
corrections_model_name = random.choice(["claude-sonnet-4-6", "gpt-5.5"])
logging.info(f"No corrections model specified; randomly selected {corrections_model_name}")
model_override = LLModelService().get_model_by_name(corrections_model_name)
# Attribute corrections usage to this site. Harmless no-op re-set when the
# caller (ArticleCreationService.create_article) already scoped it.
with usage_history.usage_scope(getattr(site, 'slug', None)):
comment_html, revised_body, model_name, provider_name = chat_service.generate_corrections(
article_title=article_title,
article_body=article_body,
fact_check_text=fact_check_text,
images=images or [],
original_model=None,
search_results=search_results,
model_override=model_override,
)
body_updated = False
if revised_body:
wp_service.update_post_content(site, wp_token, post_id, revised_body)
body_updated = True
logging.info(f"Article body updated for post {post_id}")
wp_service.post_comment(
site=site,
character=character,
post_id=post_id,
comment=comment_html,
token=wp_token,
parent_comment_id=parent_comment_id,
author_name_override=f"Corrections (via {provider_name} {model_name})",
author_email_override="editor@turmansolutions.ai",
)
return {
"body_updated": body_updated,
"model_name": model_name,
"provider_name": provider_name,
}