2025-08-17 00:18:26 +09:00
|
|
|
"""
|
|
|
|
|
DB の queries テーブルにたまってゐるクエリを AI に処理させ answers テーブルに流す.
|
|
|
|
|
"""
|
|
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import random
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
from typing import TypedDict
|
|
|
|
|
|
|
|
|
|
from nizika_ai.config import DB
|
2025-08-17 03:34:44 +09:00
|
|
|
from nizika_ai.consts import Character, Platform, QueryType
|
2025-08-17 00:18:26 +09:00
|
|
|
from nizika_ai.models import Answer, AnsweredFlag, Query
|
2024-12-24 23:39:41 +09:00
|
|
|
from nizika_ai.talk import Talk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main (
|
|
|
|
|
) -> None:
|
2025-08-17 00:18:26 +09:00
|
|
|
"""
|
|
|
|
|
メーン処理
|
|
|
|
|
"""
|
|
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
queries: list[Query] = Query.where ('answered', False).get ()
|
|
|
|
|
if not queries:
|
|
|
|
|
return
|
2025-08-16 17:59:41 +09:00
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
query: Query = random.choice (queries)
|
2025-08-16 17:59:41 +09:00
|
|
|
|
|
|
|
|
DB.begin_transaction ()
|
|
|
|
|
try:
|
|
|
|
|
user_name = query.user.name if query.user_id else None
|
|
|
|
|
|
|
|
|
|
histories: list[History] = []
|
|
|
|
|
for history in query.answer_histories:
|
|
|
|
|
if history.query is not None:
|
|
|
|
|
histories.append ({ 'role': 'user', 'content': history.query.content })
|
|
|
|
|
histories.append ({ 'role': 'assistant', 'content': history.content })
|
|
|
|
|
|
|
|
|
|
for character in [Character.DEERJIKA, Character.GOATOH]:
|
|
|
|
|
if query.target_character & character.value:
|
|
|
|
|
add_answer (query, character, user_name, histories)
|
|
|
|
|
|
|
|
|
|
query.answered = True
|
|
|
|
|
|
|
|
|
|
query.save ()
|
|
|
|
|
|
|
|
|
|
DB.commit ()
|
|
|
|
|
except Exception:
|
|
|
|
|
DB.rollback ()
|
|
|
|
|
raise
|
2024-12-24 23:39:41 +09:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_answer (
|
|
|
|
|
query: Query,
|
|
|
|
|
character: Character,
|
|
|
|
|
user_name: str | None,
|
|
|
|
|
histories: list[History],
|
|
|
|
|
) -> None:
|
2025-08-17 00:18:26 +09:00
|
|
|
"""
|
|
|
|
|
AI の返答を DB に積む.
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
query: Query
|
|
|
|
|
クエリ
|
|
|
|
|
character: Character
|
|
|
|
|
返答するキャラクタ
|
|
|
|
|
user_name: str | None
|
|
|
|
|
クエリの主
|
|
|
|
|
histories: list[History]
|
|
|
|
|
履歴
|
|
|
|
|
"""
|
|
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
message: str | list[dict[str, str | dict[str, str]]]
|
2025-08-16 17:59:41 +09:00
|
|
|
if query.image_url:
|
2024-12-24 23:39:41 +09:00
|
|
|
message = [{ 'type': 'text', 'text': query.content },
|
|
|
|
|
{ 'type': 'image_url', 'image_url': query.image_url }]
|
2025-08-16 17:59:41 +09:00
|
|
|
else:
|
|
|
|
|
message = query.content
|
|
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
answer = Answer ()
|
|
|
|
|
answer.query_id = query.id
|
|
|
|
|
answer.character = character.value
|
|
|
|
|
answer.content = Talk.main (message, user_name, histories,
|
|
|
|
|
goatoh_mode = character == Character.GOATOH)
|
|
|
|
|
answer.sent_at = datetime.now ()
|
|
|
|
|
answer.save ()
|
|
|
|
|
add_answered_flags (answer)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_answered_flags (
|
|
|
|
|
answer: Answer,
|
|
|
|
|
) -> None:
|
2025-08-17 00:18:26 +09:00
|
|
|
"""
|
|
|
|
|
返答済フラグを付与する.
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
answer: Answer
|
|
|
|
|
返答モデル
|
|
|
|
|
"""
|
|
|
|
|
|
2025-08-17 03:34:44 +09:00
|
|
|
answer_type: QueryType
|
2024-12-24 23:39:41 +09:00
|
|
|
try:
|
2025-08-17 03:34:44 +09:00
|
|
|
answer_type = QueryType (answer.query.query_type)
|
2025-08-17 00:18:26 +09:00
|
|
|
except (TypeError, ValueError):
|
2024-12-24 23:39:41 +09:00
|
|
|
return
|
2025-08-16 17:59:41 +09:00
|
|
|
|
2025-08-17 03:34:44 +09:00
|
|
|
if answer_type in (QueryType.YOUTUBE_COMMENT,
|
|
|
|
|
QueryType.YOUTUBE_COMMENT,
|
|
|
|
|
QueryType.KIRIBAN,
|
|
|
|
|
QueryType.NICO_REPORT,
|
|
|
|
|
QueryType.SNACK_TIME,
|
|
|
|
|
QueryType.HOT_SPRING):
|
2024-12-24 23:39:41 +09:00
|
|
|
add_answered_flag (answer, Platform.YOUTUBE)
|
2025-08-17 03:34:44 +09:00
|
|
|
|
|
|
|
|
if answer_type in (QueryType.BLUESKY_COMMENT,
|
|
|
|
|
QueryType.BLUESKY_SYSTEM,
|
|
|
|
|
QueryType.KIRIBAN,
|
|
|
|
|
QueryType.NICO_REPORT,
|
|
|
|
|
QueryType.SNACK_TIME,
|
|
|
|
|
QueryType.HOT_SPRING):
|
2024-12-24 23:39:41 +09:00
|
|
|
add_answered_flag (answer, Platform.BLUESKY)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_answered_flag (
|
|
|
|
|
answer: Answer,
|
|
|
|
|
platform: Platform,
|
|
|
|
|
) -> None:
|
2025-08-17 00:18:26 +09:00
|
|
|
"""
|
|
|
|
|
返答済フラグを付与する.
|
|
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
|
----------
|
|
|
|
|
answer: Answer
|
|
|
|
|
返答モデル
|
|
|
|
|
platform: Platform
|
|
|
|
|
プラットフォーム
|
|
|
|
|
"""
|
|
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
answered_flag = AnsweredFlag ()
|
|
|
|
|
answered_flag.answer_id = answer.id
|
|
|
|
|
answered_flag.platform = platform.value
|
|
|
|
|
answered_flag.answered = False
|
|
|
|
|
answered_flag.save ()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class History (TypedDict):
|
2025-08-17 00:18:26 +09:00
|
|
|
"""
|
|
|
|
|
会話履歴の 1 要素;ユーザや AI の発話を簡易に保持する型
|
|
|
|
|
"""
|
|
|
|
|
|
2024-12-24 23:39:41 +09:00
|
|
|
role: str
|
|
|
|
|
content: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
main ()
|