Skip to content

WIP: Combine changes from function analyzer (PR 1107) and crash analyzer (PR 1109) #1111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 101 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
683caaa
Added a basic function analyzer agent using the ADK library.
AmPaschal May 21, 2025
16a687c
Resolved review comments.
AmPaschal May 21, 2025
0316104
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into fu…
AmPaschal May 21, 2025
554e5d3
Implemented a FuzzIntrospector tool and provided to the agent.
AmPaschal May 22, 2025
fb4754c
Merge branch 'function-analyzer-main' of https://github.com/google/os…
AmPaschal May 22, 2025
fb8607d
Formatted code using presubmit.
AmPaschal May 22, 2025
52a5c12
Made the agent call synchronous. This is because the main program doe…
AmPaschal May 23, 2025
b69f506
This commit includes the function's source in the agent's prompt.
AmPaschal May 23, 2025
381868e
Merge branch 'function-analyzer-main' of https://github.com/google/os…
AmPaschal May 23, 2025
4e632c0
Impleemnted the function analyzer agent as a sequential agent.
AmPaschal May 27, 2025
e82309e
This commits modifies the function analyzer agent to return both the …
AmPaschal May 27, 2025
eadd827
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal May 27, 2025
a242059
Ran presubmit and fixed reported issues.
AmPaschal May 27, 2025
47010af
Refactored imports
AmPaschal May 28, 2025
4314b30
Parallelize analysis of a benchmark and created a script to upload an…
AmPaschal May 29, 2025
1266603
Upgraded function analyzer test to use 2.5 pro and updated function a…
AmPaschal May 29, 2025
a80b52a
Merge branch 'introspector-tool' of https://github.com/google/oss-fuz…
AmPaschal May 30, 2025
44e7325
Implemented an alternative agentic architecture where the target func…
AmPaschal Jun 2, 2025
97984a0
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into fa…
AmPaschal Jun 4, 2025
69c03a3
function-analyzer: Implemented flow of requirements from function ana…
AmPaschal Jun 4, 2025
40cbdb4
base-agent: adjust logging (#1075)
DavidKorczynski Jun 1, 2025
be2edba
Crash Analyzer Agent (#814)
maoyixie Jun 2, 2025
e95b020
add initial OSS-Fuzz project build fixer (#1076)
DavidKorczynski Jun 2, 2025
d40bfa2
build_generator: llm_agent: fix typo (#1078)
DavidKorczynski Jun 2, 2025
149d47e
build-fixer: improve capabilities (#1080)
DavidKorczynski Jun 3, 2025
98a7a02
build-fixer: add simple build output truncation (#1082)
DavidKorczynski Jun 3, 2025
9695911
build-fixer: fix template creation (#1083)
DavidKorczynski Jun 4, 2025
893edc5
build-fixer: add function tool based flow (#1084)
DavidKorczynski Jun 4, 2025
f852534
models: add gpt-4.1 and minor build-fixer fix (#1085)
DavidKorczynski Jun 4, 2025
b4934ab
build-fixer: add tool for building both Dockerfile and build script (…
DavidKorczynski Jun 4, 2025
91ab496
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 4, 2025
537e7c7
Merge branch 'main' into introspector-tool
AmPaschal Jun 4, 2025
6937d40
Merge branch 'introspector-tool' of https://github.com/google/oss-fuz…
AmPaschal Jun 4, 2025
1fbe6d3
Merge branch 'introspector-tool' of https://github.com/google/oss-fuz…
AmPaschal Jun 4, 2025
d757ef7
Removed commented out statements.
AmPaschal Jun 4, 2025
6df02b3
Added TODOs
AmPaschal Jun 5, 2025
643e246
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 5, 2025
be31842
Refactored code
AmPaschal Jun 5, 2025
2f92cca
Merge branch 'introspector-tool' of https://github.com/google/oss-fuz…
AmPaschal Jun 5, 2025
2242f66
Ran presubmit to fix lint errors.
AmPaschal Jun 5, 2025
800b601
Remove unneeded file.
AmPaschal Jun 5, 2025
e108701
Removed redundant files
AmPaschal Jun 5, 2025
fc0b49f
Merge branch 'introspector-tool' into new-fa-arch
AmPaschal Jun 5, 2025
53342aa
Integrated the function analyzer agent to the writing stage.
AmPaschal Jun 5, 2025
be8ff8f
Presubmit fixes
AmPaschal Jun 5, 2025
385a332
Fixed bug in cloud_builder
AmPaschal Jun 5, 2025
e9a14ef
Fixed an error in cloud_builder that caused incorrect experiment path.
AmPaschal Jun 6, 2025
0ec4675
Presubmit fixes
AmPaschal Jun 6, 2025
3a60edc
Presubmit fixes for cloud_builder.py
AmPaschal Jun 6, 2025
dde533e
Refactored logging in function analyzer
AmPaschal Jun 6, 2025
d2d3137
Ensure new experiment files from cloud experiment are saved after the…
AmPaschal Jun 6, 2025
716ff40
Presubmit fixes
AmPaschal Jun 6, 2025
1f8cf96
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 6, 2025
735c46e
Fixed bug
AmPaschal Jun 6, 2025
2108ded
Integrated ProjectContainerTool and modified the prompt.
AmPaschal Jun 6, 2025
a7a700d
Added additional benchmarks to quick-test
AmPaschal Jun 9, 2025
5809692
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 11, 2025
466ca80
Fix errors after pulling main
AmPaschal Jun 11, 2025
08263a0
Presubmit changes
AmPaschal Jun 11, 2025
f21a7ab
Created ADKBaseAgent so it contains reusable ADK logic.
AmPaschal Jun 11, 2025
3b38d85
Integrate results from function analyzer into web report
AmPaschal Jun 11, 2025
da435e9
Fixed presubmit errors
AmPaschal Jun 11, 2025
b6bb19f
Merge branch 'make-adk-base-agent' of https://github.com/google/oss-f…
AmPaschal Jun 11, 2025
f767db9
Fix presubmit errors
AmPaschal Jun 11, 2025
831e5f2
Log tool interaction
AmPaschal Jun 11, 2025
56a3698
Fixed presubmit errors
AmPaschal Jun 11, 2025
a8008cb
Fixed error in agent name
AmPaschal Jun 12, 2025
7aa44ce
Fixed error in FunctionAnalyzer
AmPaschal Jun 12, 2025
671b8c6
Fix error in FunctionAnalyzer
AmPaschal Jun 12, 2025
f7be5b4
Integrate crash analyzer's result in the enhancer
AmPaschal Jun 12, 2025
3bf4773
Presubmit fixes
AmPaschal Jun 12, 2025
40718bb
Revert the create_children_dirs flag in Workdir
AmPaschal Jun 12, 2025
326ad83
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 13, 2025
14fe293
Minor fixes to prompt_builder.py
AmPaschal Jun 13, 2025
2dccf23
Presubmit fixes
AmPaschal Jun 13, 2025
dd35173
Updated the way tool interactions, using the ADKBaseAgent, are logged.
AmPaschal Jun 13, 2025
ba1cb93
Presubmit fixes
AmPaschal Jun 13, 2025
2c34ef4
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 13, 2025
c65ccad
Fix error from pulling main
AmPaschal Jun 13, 2025
2117219
Update TrialResult to be populated from CrashAnalysis instead of Sema…
AmPaschal Jun 13, 2025
b44bff0
Merge branch 'fix-true-positive-for-ca' into integrate-ca-to-enhancer
AmPaschal Jun 13, 2025
fa270ae
Merge branch 'integrate-pct-in-fa' into merge-fa-ca-enhancer-changes
AmPaschal Jun 13, 2025
c0fa530
Addressed comments from pull request
AmPaschal Jun 13, 2025
774489c
Presubmit fixes
AmPaschal Jun 13, 2025
4c89442
Merge branch 'integrate-fa-to-wstage' into merge-fa-ca-enhancer-changes
AmPaschal Jun 13, 2025
a582683
Merge branch 'main' into merge-fa-ca-enhancer-changes
AmPaschal Jun 13, 2025
3134a90
Integrated function requirements to enhancer
AmPaschal Jun 13, 2025
339406c
Merge branch 'integrate-fa-to-enhancer' into merge-fa-ca-enhancer-cha…
AmPaschal Jun 13, 2025
8498115
Add requirements to CrashEnhancer
AmPaschal Jun 13, 2025
6c4a89d
Presubmit fixes
AmPaschal Jun 13, 2025
d4f4b7f
Merge branch 'main' into merge-fa-ca-enhancer-changes
AmPaschal Jun 16, 2025
3785338
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into me…
AmPaschal Jun 17, 2025
3d26d34
Removed unnecessary files.
AmPaschal Jun 17, 2025
be7701f
Merge branch 'main' of https://github.com/google/oss-fuzz-gen into in…
AmPaschal Jun 17, 2025
e635f59
Merge branch 'main' into integrate-pct-in-fa
AmPaschal Jun 17, 2025
df628f5
Refactored get_function_implementation tool so tool response is logge…
AmPaschal Jun 17, 2025
b7f4914
Presubmit fixes
AmPaschal Jun 18, 2025
ee2438c
Use ephemeral temporary storage when downloading temporary files.
AmPaschal Jun 18, 2025
c027061
Presubmit fixes
AmPaschal Jun 18, 2025
41b841a
Merge branch 'fix-excessive-storage' of https://github.com/google/oss…
AmPaschal Jun 18, 2025
3ba27ef
Merge branch 'integrate-pct-in-fa' of https://github.com/google/oss-f…
AmPaschal Jun 18, 2025
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
119 changes: 118 additions & 1 deletion agent/base_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.
"""The abstract base class for LLM agents in stages."""
import argparse
import asyncio
import os
import random
import re
Expand All @@ -23,11 +24,14 @@
from typing import Any, Optional

import requests
from google.adk import agents, runners, sessions
from google.genai import errors, types

import logger
import utils
from data_prep import introspector
from llm_toolkit.models import LLM
from experiment import benchmark as benchmarklib
from llm_toolkit.models import LLM, VertexAIModel
from llm_toolkit.prompts import Prompt
from results import Result
from tool.base_tool import BaseTool
Expand Down Expand Up @@ -269,6 +273,18 @@ def _preprocess_fi_setup(cls) -> None:

introspector.set_introspector_endpoints('http://127.0.0.1:8080/api')

def get_function_requirements(self) -> str:
"""Gets the function requirements from the result."""

requirements_path = self.args.work_dirs.requirements_file_path(self.trial)
if os.path.isfile(requirements_path):
with open(requirements_path, 'r') as file:
function_requirements = file.read()
else:
function_requirements = ''

return function_requirements

@classmethod
def cloud_main(cls) -> None:
"""Executes agent using dill files. This is for cloud experiments launched
Expand All @@ -295,6 +311,107 @@ def execute(self, result_history: list[Result]) -> Result:
"""Executes the agent based on previous result."""


class ADKBaseAgent(BaseAgent):
"""The abstract base class for agents created using the ADK library."""

def __init__(self,
trial: int,
llm: LLM,
args: argparse.Namespace,
benchmark: benchmarklib.Benchmark,
description: str = '',
instruction: str = '',
tools: Optional[list] = None,
name: str = ''):

super().__init__(trial, llm, args, tools, name)

self.benchmark = benchmark

# For now, ADKBaseAgents only support the Vertex AI Models.
if not isinstance(llm, VertexAIModel):
raise ValueError(f'{self.name} only supports Vertex AI models.')

# Create the agent using the ADK library
adk_agent = agents.LlmAgent(
name=self.name,
model=llm._vertex_ai_model,
description=description,
instruction=instruction,
tools=tools or [],
)

# Create the session service
session_service = sessions.InMemorySessionService()
session_service.create_session(
app_name=self.name,
user_id=benchmark.id,
session_id=f'session_{self.trial}',
)

# Create the runner
self.runner = runners.Runner(
agent=adk_agent,
app_name=self.name,
session_service=session_service,
)

self.round = 0

logger.info('ADK Agent %s created.', self.name, trial=self.trial)

def chat_llm(self, cur_round: int, client: Any, prompt: Prompt,
trial: int) -> str:
"""Call the agent with the given prompt, running async code in sync."""

self.round = cur_round

self.log_llm_prompt(prompt.get())

async def _call():
user_id = self.benchmark.id
session_id = f'session_{self.trial}'
content = types.Content(role='user',
parts=[types.Part(text=prompt.get())])

final_response_text = ''

async for event in self.runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=content,
):
if event.is_final_response():
if (event.content and event.content.parts and
event.content.parts[0].text):
final_response_text = event.content.parts[0].text
elif event.actions and event.actions.escalate:
error_message = event.error_message
logger.error('Agent escalated: %s', error_message, trial=self.trial)

self.log_llm_response(final_response_text)

return final_response_text

return self.llm.with_retry_on_error(lambda: asyncio.run(_call()),
[errors.ClientError])

def log_llm_prompt(self, promt: str) -> None:
self.round += 1
logger.info('<CHAT PROMPT:ROUND %02d>%s</CHAT PROMPT:ROUND %02d>',
self.round,
promt,
self.round,
trial=self.trial)

def log_llm_response(self, response: str) -> None:
logger.info('<CHAT RESPONSE:ROUND %02d>%s</CHAT RESPONSE:ROUND %02d>',
self.round,
response,
self.round,
trial=self.trial)


if __name__ == "__main__":
# For cloud experiments.
BaseAgent.cloud_main()
3 changes: 2 additions & 1 deletion agent/crash_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ def execute(self, result_history: list[Result]) -> AnalysisResult:
trial=last_result.trial,
work_dirs=last_result.work_dirs,
author=self,
chat_history={self.name: ''})
chat_history={self.name: ''},
stacktrace=last_result.run_error)
cur_round = 1
try:
client = self.llm.get_chat_client(model=self.llm.get_model())
Expand Down
12 changes: 11 additions & 1 deletion agent/enhancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import logger
from agent.prototyper import Prototyper
from llm_toolkit.prompt_builder import (CoverageEnhancerTemplateBuilder,
CrashEnhancerTemplateBuilder,
EnhancerTemplateBuilder,
JvmFixingBuilder)
from llm_toolkit.prompts import Prompt, TextPrompt
Expand Down Expand Up @@ -48,6 +49,8 @@ def _initial_prompt(self, results: list[Result]) -> Prompt:
trial=self.trial)
return Prompt()

function_requirements = self.get_function_requirements()

if benchmark.language == 'jvm':
# TODO: Do this in a separate agent for JVM coverage.
builder = JvmFixingBuilder(self.llm, benchmark,
Expand All @@ -59,6 +62,12 @@ def _initial_prompt(self, results: list[Result]) -> Prompt:
error_desc, errors = last_result.semantic_result.get_error_info()
builder = EnhancerTemplateBuilder(self.llm, benchmark,
last_build_result, error_desc, errors)
elif last_result.crash_result:
crash_result = last_result.crash_result
builder = CrashEnhancerTemplateBuilder(self.llm, benchmark,
last_build_result,
crash_result.insight,
crash_result.stacktrace)
elif last_result.coverage_result:
builder = CoverageEnhancerTemplateBuilder(
self.llm,
Expand All @@ -77,7 +86,8 @@ def _initial_prompt(self, results: list[Result]) -> Prompt:
return prompt
prompt = builder.build(example_pair=[],
tool_guides=self.inspect_tool.tutorial(),
project_dir=self.inspect_tool.project_dir)
project_dir=self.inspect_tool.project_dir,
function_requirements=function_requirements)
# TODO: A different file name/dir.
prompt.save(self.args.work_dirs.prompt)

Expand Down
Loading