135 lines
5.0 KiB
Python
135 lines
5.0 KiB
Python
"""
|
|
games/sequence_word.py - Arrange Words Game
|
|
type_id = 3
|
|
"""
|
|
from typing import List
|
|
from pydantic import BaseModel, Field
|
|
from langchain_core.output_parsers import PydanticOutputParser
|
|
|
|
|
|
# ============== SCHEMA ==============
|
|
class WordItem(BaseModel):
|
|
word: str = Field(description="Word or phrase to arrange (EXACT from source)")
|
|
original_quote: str = Field(description="EXACT quote from source text")
|
|
image_description: str = Field(default="", description="Visual description of the content")
|
|
image_keywords: List[str] = Field(default=[], description="Keywords for image search")
|
|
image_is_complex: bool = Field(default=False, description="True if image needs precise quantities, humans, or multiple detailed objects")
|
|
|
|
|
|
class WordMetadata(BaseModel):
|
|
"""Metadata đánh giá nội dung"""
|
|
title: str = Field(
|
|
description="Title for this content. Prefer title from source document if available and suitable, otherwise create a short descriptive title."
|
|
)
|
|
description: str = Field(
|
|
description="Short description summarizing the content/topic."
|
|
)
|
|
grade: int = Field(
|
|
description="Estimated grade level 1-5 (1=easy/young, 5=advanced/older). Judge by vocabulary complexity."
|
|
)
|
|
type: str = Field(default="sequence_word", description="Game type")
|
|
difficulty: int = Field(
|
|
description="Difficulty 1-5 for that grade (1=very easy, 5=very hard). Judge by word complexity, number of items."
|
|
)
|
|
|
|
|
|
class WordOutput(BaseModel):
|
|
"""Output wrapper for word items"""
|
|
items: List[WordItem] = Field(description="List of word items generated from source text")
|
|
metadata: WordMetadata = Field(description="Metadata about the content")
|
|
|
|
|
|
# Output parser
|
|
output_parser = PydanticOutputParser(pydantic_object=WordOutput)
|
|
|
|
|
|
# ============== CONFIG ==============
|
|
GAME_CONFIG = {
|
|
"game_type": "sequence_word",
|
|
"display_name": "Arrange Words",
|
|
"description": "Arrange words or phrases in order",
|
|
"type_id": 3,
|
|
|
|
"active": True,
|
|
|
|
"max_items": 10,
|
|
"schema": WordItem,
|
|
"output_schema": WordOutput,
|
|
"output_parser": output_parser,
|
|
|
|
# Dùng cho analyze + generate (không có format rules)
|
|
"system_prompt": """Extract words or phrases from source text.
|
|
|
|
RULES:
|
|
1. KEEP THE ORIGINAL LANGUAGE - Do NOT translate
|
|
2. word = EXACT copy from source text
|
|
3. original_quote = same as word value
|
|
4. image_description = ALWAYS provide a short visual description (NEVER empty)
|
|
5. image_is_complex = FALSE for simple/static objects, TRUE for quantities/humans/complex scenes""",
|
|
|
|
# Dùng cho generate trực tiếp (CÓ format rules)
|
|
"direct_prompt": """Extract words or phrases from source text.
|
|
|
|
EXPECTED INPUT: List of words/phrases (separated by semicolon, comma, newline, or similar)
|
|
|
|
STEP 1 - VALIDATE INPUT:
|
|
Analyze if input looks like a list of words/phrases suitable for "arrange words" game.
|
|
- Should contain multiple short words or phrases
|
|
- Should NOT be a paragraph, essay, or Q&A format
|
|
|
|
If input is clearly NOT suitable (e.g. it's a quiz, a long paragraph, or wrong format), return:
|
|
{{"items": [], "format_error": "Input không phù hợp cho game sắp xếp từ"}}
|
|
|
|
STEP 2 - EXTRACT (if valid):
|
|
RULES:
|
|
1. KEEP THE ORIGINAL LANGUAGE - Do NOT translate
|
|
2. Extract ALL words/phrases from source
|
|
3. word = EXACT word/phrase from source (trim whitespace)
|
|
4. original_quote = same as word value
|
|
5. image_description = ALWAYS provide a short visual description (NEVER leave empty)
|
|
6. image_is_complex:
|
|
- FALSE: simple objects, static things, no specific quantities (e.g. "an apple", "a book")
|
|
- TRUE: needs exact quantities, humans/people, or complex details (e.g. "5 oranges", "a woman cooking")""",
|
|
}
|
|
|
|
|
|
# ============== EXAMPLES ==============
|
|
EXAMPLES = [
|
|
{
|
|
"input": "Apple; Banana; Orange; Grape",
|
|
"output": {
|
|
"items": [
|
|
{
|
|
"word": "Apple",
|
|
"original_quote": "Apple",
|
|
"image_description": "A red apple",
|
|
"image_keywords": ["apple"],
|
|
"image_is_complex": False
|
|
},
|
|
{
|
|
"word": "Banana",
|
|
"original_quote": "Banana",
|
|
"image_description": "A yellow banana",
|
|
"image_keywords": ["banana"],
|
|
"image_is_complex": False
|
|
},
|
|
{
|
|
"word": "Orange",
|
|
"original_quote": "Orange",
|
|
"image_description": "An orange fruit",
|
|
"image_keywords": ["orange"],
|
|
"image_is_complex": False
|
|
},
|
|
{
|
|
"word": "Grape",
|
|
"original_quote": "Grape",
|
|
"image_description": "Purple grapes",
|
|
"image_keywords": ["grape"],
|
|
"image_is_complex": False
|
|
}
|
|
]
|
|
},
|
|
"why_suitable": "Source has words separated by semicolons"
|
|
}
|
|
]
|