"""
Bob agent plugin for CLAIA.
Bob is a gruff, straightforward, no-nonsense assistant with a unique personality.
"""

# External dependencies
import logging
import pluggy
from typing import Type

# Internal dependencies
from claia.lib import BaseAgent, Process
from claia.lib.enums.conversation import MessageRole
from claia.hooks import AgentHooks, AgentInfo


########################################################################
#                              CONSTANTS                               #
########################################################################
BOB_SYSTEM_PROMPT = """
You are Bob, a straightforward and no-nonsense assistant.
Bob speaks in the third person and keeps responses brief.
Bob doesn't use flowery language.
Bob is direct and sometimes sarcastic.
Bob always tries to be helpful despite his gruff demeanor.
"""


########################################################################
#                            INITIALIZATION                            #
########################################################################
hookimpl = pluggy.HookimplMarker("claia_agents")


########################################################################
#                            BOB AGENT CLASS                           #
########################################################################
class BobAgent(BaseAgent):
  """
  Bob is a gruff, straightforward, no-nonsense assistant with a unique personality.

  Bob applies his own system prompt to conversations for a distinctive interaction style.
  """

  @classmethod
  def process_request(cls, process, registry=None, **kwargs) -> object:
    """Process a request using Bob's unique style by applying his system prompt."""
    try:
      model_id = process.parameters["model_id"]

      if process.conversation.prompt.get("system", "") != BOB_SYSTEM_PROMPT:
        process.conversation.change_prompt(BOB_SYSTEM_PROMPT)

      full_response = ""

      for token in registry.run(model_id, process.conversation, streaming=True, **kwargs):
        full_response += token
        process.emit("token", token)

      process.conversation.add_message(MessageRole.ASSISTANT, full_response)
      process.mark_completed(full_response)

    except Exception as e:
      logging.exception(f"Bob encountered an error for {process.id}: {str(e)}")
      process.mark_failed(str(e))

    return process


########################################################################
#                            PLUGIN HOOKS                              #
########################################################################
class BobAgentPlugin:
  """Plugin implementation for the Bob agent."""

  @hookimpl
  def get_agent_class(self, agent_name: str) -> Type[BaseAgent]:
    """Get the agent class for the Bob agent."""
    if agent_name.lower() == "bob":
      return BobAgent
    return None

  @hookimpl
  def get_agent_info(self) -> AgentInfo:
    """Get information about the Bob agent."""
    return AgentInfo(
      name="bob",
      title="Bob",
      description="A gruff, straightforward, no-nonsense assistant with a unique personality",
      agent_class=BobAgent,
      required_args=None
    )
