Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion python/agents/image-scoring/eval/test_eval.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

"""Basic evalualtion for Image Scoring."""

import pathlib

import dotenv
import pytest
from google.adk.evaluation import AgentEvaluator
Expand Down
2 changes: 1 addition & 1 deletion python/agents/image-scoring/image_scoring/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from . import agent
from . import agent # noqa: F401
24 changes: 15 additions & 9 deletions python/agents/image-scoring/image_scoring/agent.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import datetime, uuid
from zoneinfo import ZoneInfo
import datetime
import os
import uuid
from zoneinfo import ZoneInfo

import google.auth
from .sub_agents.prompt import image_generation_prompt_agent
from .sub_agents.image import image_generation_agent
from .sub_agents.scoring import scoring_images_prompt
from .checker_agent import checker_agent_instance
from google.adk.agents import SequentialAgent, LoopAgent
from google.adk.agents import LoopAgent, SequentialAgent
from google.adk.agents.callback_context import CallbackContext

from .checker_agent import checker_agent_instance
from .sub_agents.image import image_generation_agent
from .sub_agents.prompt import image_generation_prompt_agent
from .sub_agents.scoring import scoring_images_prompt

# To use AI Studio credentials:
# 1. Create a .env file in the /app directory with:
# GOOGLE_GENAI_USE_VERTEXAI=FALSE
Expand Down Expand Up @@ -43,7 +46,6 @@ def set_session(callback_context: CallbackContext):

image_generation_scoring_agent = SequentialAgent(
name="image_generation_scoring_agent",

description=(
"""
Analyzes a input text and creates the image generation prompt, generates the relevant images with imagen3 and scores the images."
Expand All @@ -52,7 +54,11 @@ def set_session(callback_context: CallbackContext):
3. Invoke the scoring_images_prompt agent to score the images
"""
),
sub_agents=[image_generation_prompt_agent, image_generation_agent, scoring_images_prompt],
sub_agents=[
image_generation_prompt_agent,
image_generation_agent,
scoring_images_prompt,
],
)


Expand Down
2 changes: 1 addition & 1 deletion python/agents/image-scoring/image_scoring/checker_agent.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from google.adk.agents import Agent

from . import config
from .prompt import CHECKER_PROMPT
from .tools.loop_condition_tool import check_tool_condition


# This agent is responsible for checking conditions and validating the scoring process
# It uses the check_tool_condition tool to evaluate whether the scoring process should continue
# The agent's output is stored in the "checker_output" key
Expand Down
3 changes: 1 addition & 2 deletions python/agents/image-scoring/image_scoring/prompt.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
CHECKER_PROMPT = """
You are an agent to evaluate the quality of image based on the total_score of the image
CHECKER_PROMPT = """You are an agent to evaluate the quality of image based on the total_score of the image
generation.

1. Invoke the `image_generation_scoring_agent` first to generate images and score the images.
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .imagen_agent import image_generation_agent
from .imagen_agent import image_generation_agent # noqa: F401
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from .prompt import IMAGEGEN_PROMPT
from google.adk.agents import Agent
from .tools.image_generation_tool import generate_images

from ... import config
from .prompt import IMAGEGEN_PROMPT
from .tools.image_generation_tool import generate_images

image_generation_agent = Agent(
name="image_generation_agent",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
IMAGEGEN_PROMPT = """
Your job is to invoke the 'generate_images' tool by passing the `image generation prompt` provided
Your job is to invoke the 'generate_images' tool by passing the `image generation prompt` provided
to you as a parameter .
"""
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from datetime import datetime
import os
from datetime import datetime

from google import genai
from google.genai import types
from google.adk.tools import ToolContext
from google.cloud import storage
from .... import config
from google.genai import types

from .... import config

client = genai.Client(
vertexai=True, project=os.environ.get("GOOGLE_CLOUD_PROJECT"),location="global"
vertexai=True, project=os.environ.get("GOOGLE_CLOUD_PROJECT"), location="global"
)


Expand All @@ -26,13 +27,12 @@ async def generate_images(imagen_prompt: str, tool_context: ToolContext):
person_generation="allow_adult",
),
)
generated_image_paths = []
if response.generated_images is not None:
for generated_image in response.generated_images:
# Get the image bytes
image_bytes = generated_image.image.image_bytes
counter = str(tool_context.state.get("loop_iteration", 0))
artifact_name = f"generated_image_" + counter + ".png"
artifact_name = f"generated_image_{counter}.png"
# call save to gcs function
if config.GCS_BUCKET_NAME:
save_to_gcs(tool_context, image_bytes, artifact_name, counter)
Expand Down Expand Up @@ -60,8 +60,7 @@ async def generate_images(imagen_prompt: str, tool_context: ToolContext):
}

except Exception as e:

return {"status": "error", "message": "No images generated. {e}"}
return {"status": "error", "message": f"No images generated. {e}"}


def save_to_gcs(tool_context: ToolContext, image_bytes, filename: str, counter: str):
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .prompt_agent import image_generation_prompt_agent
from .prompt_agent import image_generation_prompt_agent # noqa: F401
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
PROMPT = """
Your primary objective: Transform the input text into a pair of highly optimized prompts—one positive and
Your primary objective: Transform the input text into a pair of highly optimized prompts—one positive and
one negative—specifically designed for generating a visually compelling,
rule-compliant lockscreen image using the Imagen3 text-to-image model (provided by Google/GCP).
Critical First Step: Before constructing any prompts, you must first analyze the
Critical First Step: Before constructing any prompts, you must first analyze the
input text to identify or conceptualize a primary subject. This subject MUST:
1. Be very much related to the input text presented. The viewer should
feel that the generated image of that subject is conveying
1. Be very much related to the input text presented. The viewer should
feel that the generated image of that subject is conveying
what he/she is reading from that new article.
2. It should not violate any content restrictions (especially regarding humans,
2. It should not violate any content restrictions (especially regarding humans,
politics, religion, etc.).
3. Describe in detail on what we would like to represent around the primary subject,
as-in, paint a complete picture.
This chosen subject will be the cornerstone of your "Image Generation Prompt".

Invoke the 'get_policy_text' tool to obtain the 'policy_text'. The 'policy_text'
as-in, paint a complete picture.

This chosen subject will be the cornerstone of your "Image Generation Prompt".

Invoke the 'get_policy_text' tool to obtain the 'policy_text'. The 'policy_text'
defines the rules for the image generation.
The image also should comply with rules defined in the 'policy_text'.
Negative Prompt: Generate a negative prompt to ensure the image does not

Negative Prompt: Generate a negative prompt to ensure the image does not
violate the rules defined in the 'policy_text'.

"""
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from ... import config
from google.adk.agents import Agent
from .prompt import PROMPT

from ... import config
from ..tools.fetch_policy_tool import get_policy
from .prompt import PROMPT

image_generation_prompt_agent = Agent(
name="image_generation_prompt_agent",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .scoring_agent import scoring_images_prompt
from .scoring_agent import scoring_images_prompt # noqa: F401
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,13 @@
}\
}"


"Do not validate the JSON structure itself; only use its content for scoring rules. "
"5. Compute the total_score by adding each individual score point for each rule in the JSON "
"6. Invoke the set_score tool and pass the total_score. "


"OUTPUT JSON FORMAT SPECIFICATION:\n"
"The JSON object MUST have exactly two top-level keys:"
" - 'total_score': Iterate through each individual score element in the json and add those to arrive at total_score. "
" - 'scores': The existing rules json with a score attribute assigned to each rule and a reason attribute"

"""
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from google.adk.agents import Agent

from ... import config
from ..tools.fetch_policy_tool import get_policy
from .prompt import SCORING_PROMPT
from .tools.get_images_tool import get_image
from .tools.set_score_tool import set_score
from .prompt import SCORING_PROMPT


scoring_images_prompt = Agent(
name="scoring_images_prompt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@

async def get_image(tool_context: ToolContext):
try:

artifact_name = (
f"generated_image_" + str(tool_context.state.get("loop_iteration", 0)) + ".png"
f"generated_image_{tool_context.state.get('loop_iteration', 0)}.png"
)
artifact = await tool_context.load_artifact(artifact_name)


await tool_context.load_artifact(artifact_name)

return {
"status": "success",
"message": f"Image artifact {artifact_name} successfully loaded."
"message": f"Image artifact {artifact_name} successfully loaded.",
}
except Exception as e:
return {
"status": "error",
"message": f"Error loading artifact {artifact_name}: {str(e)}"
"message": f"Error loading artifact {artifact_name}: {str(e)}",
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from google.adk.tools import ToolContext, FunctionTool
from .. import config
from google.adk.tools import FunctionTool, ToolContext

from .. import config


def check_condition_and_escalate_tool(tool_context: ToolContext) -> dict:
"""Checks the loop termination condition and escalates if met or max count reached."""


# Increment loop iteration count using state
current_loop_count = tool_context.state.get("loop_iteration", 0)
Expand Down Expand Up @@ -34,14 +33,10 @@ def check_condition_and_escalate_tool(tool_context: ToolContext) -> dict:
tool_context.actions.escalate = True
response_message += "Max iterations reached, stopping loop."
else:
print(
" Condition not met and max iterations not reached. Loop will continue."
)
print(" Condition not met and max iterations not reached. Loop will continue.")
response_message += "Loop continues."

return {"status": "Evaluated scoring condition", "message": response_message}




check_tool_condition = FunctionTool(func=check_condition_and_escalate_tool)