Blueprint v1.0.4: Implemented AI Context Optimization & Token Management
- core/utils.py: Added estimate_tokens(), truncate_to_tokens(), get_ai_cache(), set_ai_cache(), make_cache_key() utilities - story/writer.py: Applied truncate_to_tokens() to prev_content (2000 tokens) and prev_sum (600 tokens) context injections - story/editor.py: Applied truncate_to_tokens() to summary (1000t), last_chapter_text (800t), eval text (7500t), propagation contexts (2500t/3000t) - web/routes/persona.py: Added MD5-keyed in-memory cache for persona analyze endpoint; truncated sample_text to 750 tokens - ai/models.py: Added pre-dispatch payload size estimation with 30k-token warning threshold Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import os
|
||||
import json
|
||||
import datetime
|
||||
import time
|
||||
import hashlib
|
||||
from core import config
|
||||
import threading
|
||||
import re
|
||||
@@ -19,6 +20,40 @@ _log_context = threading.local()
|
||||
# Cache for dynamic pricing from AI model selection
|
||||
PRICING_CACHE = {}
|
||||
|
||||
# --- Token Estimation & Truncation Utilities ---
|
||||
|
||||
def estimate_tokens(text):
|
||||
"""Estimate token count using a 4-chars-per-token heuristic (no external libs required)."""
|
||||
if not text:
|
||||
return 0
|
||||
return max(1, len(text) // 4)
|
||||
|
||||
def truncate_to_tokens(text, max_tokens):
|
||||
"""Truncate text to approximately max_tokens, keeping the most recent (tail) content."""
|
||||
if not text:
|
||||
return text
|
||||
max_chars = max_tokens * 4
|
||||
if len(text) <= max_chars:
|
||||
return text
|
||||
return text[-max_chars:]
|
||||
|
||||
# --- In-Memory AI Response Cache ---
|
||||
|
||||
_AI_CACHE = {}
|
||||
|
||||
def get_ai_cache(key):
|
||||
"""Retrieve a cached AI response by key. Returns None if not cached."""
|
||||
return _AI_CACHE.get(key)
|
||||
|
||||
def set_ai_cache(key, value):
|
||||
"""Store an AI response in the in-memory cache keyed by a hash string."""
|
||||
_AI_CACHE[key] = value
|
||||
|
||||
def make_cache_key(prefix, *parts):
|
||||
"""Build a stable MD5 cache key from a prefix and variable string parts."""
|
||||
raw = "|".join(str(p) for p in parts)
|
||||
return f"{prefix}:{hashlib.md5(raw.encode('utf-8', errors='replace')).hexdigest()}"
|
||||
|
||||
def set_log_file(filepath):
|
||||
_log_context.log_file = filepath
|
||||
|
||||
|
||||
Reference in New Issue
Block a user