fix: strip code fences, add MIME/size validation, add tests
This commit is contained in:
@@ -16,9 +16,9 @@ Usage:
|
||||
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import yaml
|
||||
@@ -66,11 +66,30 @@ def build_file_content(filepath: str) -> list[dict]:
|
||||
|
||||
Returns a list with one document/image content block.
|
||||
"""
|
||||
SUPPORTED_DOCUMENT_TYPES = {"application/pdf"}
|
||||
SUPPORTED_IMAGE_TYPES = {"image/jpeg", "image/png", "image/gif", "image/webp"}
|
||||
|
||||
mime_type, _ = mimetypes.guess_type(filepath)
|
||||
if mime_type is None:
|
||||
# Default to octet-stream; let the API decide
|
||||
mime_type = "application/octet-stream"
|
||||
|
||||
if mime_type not in SUPPORTED_DOCUMENT_TYPES | SUPPORTED_IMAGE_TYPES:
|
||||
print(
|
||||
f"Error: unsupported file type '{mime_type}'. "
|
||||
f"Supported types: PDF, JPEG, PNG, GIF, WebP",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
MAX_FILE_SIZE = 20 * 1024 * 1024 # 20MB
|
||||
file_size = os.path.getsize(filepath)
|
||||
if file_size > MAX_FILE_SIZE:
|
||||
print(
|
||||
f"Error: file too large ({file_size} bytes). Maximum file size is 20MB.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
with open(filepath, "rb") as f:
|
||||
data = base64.b64encode(f.read()).decode("utf-8")
|
||||
|
||||
@@ -114,6 +133,14 @@ def cooklang_from_anthropic(
|
||||
],
|
||||
)
|
||||
|
||||
# Warn if response was truncated
|
||||
if response.stop_reason == "max_tokens":
|
||||
print(
|
||||
"Warning: response may be truncated (reached max_tokens limit). "
|
||||
"Consider splitting the recipe into smaller parts.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
# Extract text from response content blocks
|
||||
parts: list[str] = []
|
||||
for block in response.content:
|
||||
@@ -122,6 +149,12 @@ def cooklang_from_anthropic(
|
||||
|
||||
cooklang = "\n".join(parts).strip()
|
||||
|
||||
# Strip markdown code fences if present (the prompts may instruct the
|
||||
# model to wrap output in ```cooklang blocks)
|
||||
cooklang = re.sub(r"^```\w*\n?", "", cooklang)
|
||||
cooklang = re.sub(r"\n```\s*$", "", cooklang)
|
||||
cooklang = cooklang.strip()
|
||||
|
||||
# Basic validation: must start with front matter marker
|
||||
if not cooklang.startswith("---"):
|
||||
print(
|
||||
|
||||
Reference in New Issue
Block a user