ここは 「OS の内部表現(IR)を Gemini に渡す直前の“生成エンジン”」 だから、
絶対に揺れない・壊れない・再現可能な IR 自動生成関数 を設計する必要がある。

あなたの OS はすでに:

  • 意味レイヤ(PoseVector / FaceVector / CharacterModel)
  • 構造レイヤ(joints / skeleton_paths)
  • SVGレイヤ(Gemini の描画結果)

という 3 層構造を持っている。

ここで作るのは:

🎯 gemini_requests.request_json を自動生成する関数設計(OS 標準)

つまり:

characters → poses → joints → skeleton_paths
    ↓
gemini_request_json(IR)

この IR 生成関数 が OS の「意味→構造→SVG」の橋渡しになる。


🧩 1. IR の構造(OS 標準フォーマット)

Gemini に渡す IR は、以下の 4 要素で構成される:

  1. coordinate_system(SVG の座標系)
  2. joints(絶対座標)
  3. skeleton_paths(線の接続順序)
  4. face_parts(目・鼻・口の座標)
  5. style(stroke / fill)

これを JSON にまとめる。


🧱 2. DB から IR を組み立てるための関数設計

OS の IR 生成関数はこうなる:

def build_gemini_request(pose_id, db):
    # 1. pose 情報を取得
    pose = db.get_pose(pose_id)

    # 2. joints(構造レイヤ)
    joints = db.get_joints(pose_id)

    # 3. skeleton_paths(構造レイヤ)
    paths = db.get_skeleton_paths(pose_id)

    # 4. face joints(構造レイヤ)
    face = {j["joint_name"]: j for j in joints if j["joint_name"].startswith("eye") 
                                             or j["joint_name"] in ["nose","mouth-L","mouth-R","chin"]}

    # 5. IR を組み立てる
    request_json = {
        "task": "generate_svg_from_pose",
        "coordinate_system": {
            "type": "svg",
            "viewBox": "0 0 1024 1024",
            "origin": "top-left",
            "x_axis": "right",
            "y_axis": "down"
        },
        "joints": joints_to_dict(joints),
        "skeleton_paths": paths_to_list(paths),
        "face": face_to_dict(face),
        "style": {
            "stroke": "#000",
            "fill": "none",
            "strokeWidth": 4
        }
    }

    return request_json

🧠 3. joints_to_dict の設計

DB の joints テーブルは行単位なので、
Gemini に渡すために joint_name → {x,y,z} の辞書に変換する。

def joints_to_dict(joints):
    out = {}
    for j in joints:
        out[j["joint_name"]] = {
            "x": j["x"],
            "y": j["y"],
            "z": j["z"]
        }
    return out

🦴 4. skeleton_paths の変換

DB では:

path_order | joint_list(JSON)

なので、Gemini 用に配列へ変換する。

def paths_to_list(paths):
    # path_order でソート
    paths = sorted(paths, key=lambda p: p["path_order"])
    return [p["joint_list"] for p in paths]

👁 5. face_to_dict の設計

顔パーツは OS の意味レイヤで特別扱いする。

def face_to_dict(face_joints):
    out = {}
    for name, j in face_joints.items():
        out[name] = {"x": j["x"], "y": j["y"]}
    return out

🧩 6. 最終的に DB に保存する(gemini_requests)

def save_gemini_request(pose_id, db):
    request_json = build_gemini_request(pose_id, db)
    db.insert_gemini_request(pose_id, request_json)
    return request_json

🌌 7. この IR 自動生成関数が OS として強い理由

✔ joints(構造)が絶対基準

→ AI が暴れても OS の意味は壊れない。

✔ skeleton_paths が OS の骨格ルールを保証

→ AI が線を勝手に変えても再生成可能。

✔ face_parts が意味レイヤを保持

→ 表情・視線の制御が安定。

✔ IR は「構造のスナップショット」

→ 再生成・比較・デバッグが容易。

✔ DB → IR → Gemini の流れが完全に自動化

→ 2026 年の靖OS の「意味→構造→SVG」パイプラインが完成。


🧭 次に深めるなら…

  • SVG → joints の逆変換(逆運動学)
  • PoseVector の正規化(角度の意味モデル)
  • 表情ベクトル(smile / anger / sad)の IR 統合
  • Gemini の出力 SVG を OS の構造に再マッピングする方法

どこに進めたい?