"""
この例では、モデルがストリーミング中にガードレールを使用する方法を示します。
出力ガードレールは、最終出力が生成された後に実行されます。
この例では、Nトークンごとにガードレールが実行され、不正な出力が検出された場合に早期終了を可能にします。
想定される出力は、多数のトークンがストリーミングされ、
ガードレールがトリガーされてストリーミングが停止することです。
"""
:
### 1 回答生成用エージェント
ollama_provider = OpenAIProvider( base_url="http://192.168.10.33:11434/v1" )
model_gpt_oss = ollama_provider.get_model("gpt-oss:20b")
agent = Agent(
    name="Streaming_Assistant",
    instructions=(
        "You are a helpful assistant. You ALWAYS write long responses, making sure to be verbose "
        "and detailed."
    ),
    model=model_gpt_oss        
)

### 2 判定結果モデル
class GuardrailOutput(BaseModel):
    reasoning: str = Field(
        description="その返答が 10 歳の子供に理解できるかどうかについて推論します。日本語で回答してください"
    )
    is_readable_by_ten_year_old: bool = Field(
        description="その返答が 10 歳の子供にも理解できるかどうか.日本語で回答してください"
    )

### 3 判定専用エージェント
ollama2_provider = OpenAIProvider( base_url="http://xxx.xxx.xxx.xx:11434/v1" )
model_gemma3 = ollama2_provider.get_model("gemma3:12b")
guardrail_agent = Agent(
    name="Checker",
    instructions=(
        "質問と回答が提示されます。あなたの目標は、その回答が10歳の子供でも理解できるほどシンプルかどうかを判断することです。"
        "日本語で回答してください"
    ),
    output_type=GuardrailOutput,
    model=model_gemma3    
)

### 4 判定関数
async def check_guardrail(text: str) -> GuardrailOutput:
    result = await Runner.run(guardrail_agent, text)
    return result.final_output_as(GuardrailOutput)


#  メイン
async def main():
    question = "ブラックホールとは何ですか？そしてそれはどのように動作しますか？"
### 5 run_streamed() による逐次受信
    result = Runner.run_streamed(agent, question)
    current_text = ""

    # N文字ごとにガードレールを確認します
    max_length=1000 # 生成する回答の最大長（この長さ以上になると強制的に 終了する） 
    next_guardrail_check_len = 100 # チェックを行う文字数の最大章
    guardrail_task = None
    guardrail_operation = False
    async for event in result.stream_events():
        ### 6 非同期判定と停止制御
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            current_text += event.data.delta
            length_of_answer = len(current_text)
            # 回答が、同じ内容が繰り返さり、長すぎるか チェック
            if length_of_answer > max_length :
                print("生成した回答が最大長を越しました")
                break
            # ガードレールチェックのタイミング
            # 既にタスクが実行中の場合は、ガードレールチェックを実行しないことに注意してください。
            # 別の実装としては、N個のガードレールを実行するか、前のガードレールをキャンセルします
            if length_of_answer >= next_guardrail_check_len and not guardrail_task:
                print("Running guardrail check")
                guardrail_task = asyncio.create_task(check_guardrail(current_text))
                next_guardrail_check_len += 100

        # ループの各反復でガードレールが作動したかどうかを確認します
        if guardrail_task and guardrail_task.done():
            guardrail_result = guardrail_task.result()
            if not guardrail_result.is_readable_by_ten_year_old:
                print("\n\n================\n\n")
                print(f"回答を生成中にガードレールが作動しました. 理由:\n{guardrail_result.reasoning}")
                guardrail_operation=True
                break
::
