Skip to content

Conversation

@SidharthK2
Copy link
Contributor

Add DAO Proposal Analyzer: Multi-Agent Governance Analysis System

Description

Introducing the DAO Proposal Analyzer - a comprehensive multi-agent system that analyzes on-chain DAO governance proposals and provides voting recommendations. This project showcases advanced agent orchestration using the ADK-TS framework with real blockchain data integration.

Type of Change

  • New sample project
  • Bug fix in existing sample
  • Documentation update
  • Sample improvement/enhancement

Key Features

Multi-Agent Architecture:

  • Root Agent - User interaction and on-chain data fetching
  • Analysis Workflow Agent - SequentialAgent coordinating analysis pipeline
  • Proposal Analyzer Agent - Deep technical and risk analysis
  • Vote Recommender Agent - Balanced voting recommendations

Real On-Chain Integration:

  • Fetches live governance data from Ethereum mainnet
  • Supports Compound, Uniswap, ENS, and Aave Governor Bravo contracts
  • Uses viem library for reliable blockchain RPC calls
  • Real-time proposal state, vote counts, and quorum data

Comprehensive Analysis Pipeline:

  • Technical implementation assessment
  • Risk evaluation (Low/Medium/High)
  • Stakeholder impact analysis
  • Balanced pros/cons reasoning
  • Clear voting recommendations with confidence levels

Technical Implementation

Core Components:

  • governanceService.ts - viem-based on-chain data fetching
  • fetchProposalTool.ts - Agent tools for proposal access
  • Multi-agent workflow with state management
  • TypeScript interfaces for governance data

Supported DAOs (Ethereum Mainnet):

  • Compound: 0xc0Da02939E1441F497fd74F78cE7Decb17B66529
  • Uniswap: 0x408ED6354d4973f66138C91495F2f2FCbd8724C3
  • ENS: 0x323A76393544d5ecca80cd6ef2A560C6a395b7E3
  • Aave: 0x9AEE0B04504CeF83A65AC3f0e838D0593BCb2BC7

Demo Experience

The interactive demo showcases:

  1. Discovery Phase - List supported DAOs and recent proposals
  2. Data Fetching - Retrieve specific proposal data from blockchain
  3. Sequential Analysis - Multi-agent pipeline processes proposal
  4. Final Recommendation - Vote recommendation with reasoning

Usage Examples

User: What DAOs do you support?
Agent: I support DAOs on Ethereum mainnet: Compound, Uniswap, ENS, Aave...

User: Show me recent Compound proposals
Agent: Here are the latest Compound proposals with vote counts...

User: Analyze proposal 289 from Compound
Agent: [Full pipeline execution]
  - Executive Summary: Technical upgrade proposal...
  - Risk Level: Medium
  - Recommendation: FOR (High confidence)
  - Detailed pros/cons analysis

Architecture Highlights

State Management: Uses ADK-TS shared state for agent coordination
Error Handling: Graceful fallbacks for RPC failures and missing data
Modular Design: Each agent has clear responsibilities and interfaces
Extensible: Easy to add new DAOs and analysis dimensions

Project Structure

apps/dao-proposal-analyzer/
├── src/agents/          # Multi-agent definitions
├── src/tools/           # On-chain data fetching tools
├── src/services/        # viem-based blockchain integration
├── src/constants.ts      # DAO configurations and addresses
├── src/types.ts         # TypeScript interfaces
└── README.md           # Detailed setup and usage guide

Related Issue

closes IQAIcom/adk-ts#453

Checklist

  • Sample runs successfully
  • README is updated with setup instructions
  • Code follows project conventions
  • All dependencies are properly listed

@SidharthK2 SidharthK2 requested a review from Timonwa January 8, 2026 13:12
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @SidharthK2, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates a new sample project, the "DAO Proposal Analyzer," into the repository. This system leverages a multi-agent architecture built with ADK-TS to connect with real-world blockchain data. Its primary function is to fetch, analyze, and provide voting recommendations for governance proposals from various Ethereum mainnet DAOs, aiming to empower users with informed decision-making in decentralized autonomous organizations.

Highlights

  • New Multi-Agent System: Introduces the "DAO Proposal Analyzer," a comprehensive multi-agent system for analyzing on-chain DAO governance proposals.
  • Real-time On-Chain Data Integration: Fetches live governance data from Ethereum mainnet, supporting DAOs like Compound, Uniswap, ENS, and Aave using the viem library.
  • Structured Analysis Workflow: Implements a sequential multi-agent architecture (Root, Analysis Workflow, Proposal Analyzer, Vote Recommender agents) for deep technical and risk analysis.
  • Informed Voting Recommendations: Provides balanced voting recommendations with confidence levels, pros, and cons, based on comprehensive analysis.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an impressive new sample project, the DAO Proposal Analyzer. The multi-agent architecture is well-structured, and the use of on-chain data from various DAOs provides a great real-world example. My review focuses on a few key areas to improve correctness, efficiency, and maintainability. I've identified a critical issue with environment variable configuration that would prevent the application from starting, as well as several opportunities to optimize data fetching and improve code clarity and type safety. Addressing these points will make the sample project more robust and easier for other developers to use.

config();
export const envSchema = z.object({
ADK_DEBUG: z.coerce.boolean().default(false),
GOOGLE_API_KEY: z.string(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The environment schema requires GOOGLE_API_KEY, but the .env.example file and the default model (gpt-4o-mini) indicate that OPENAI_API_KEY is what's actually needed. This will cause the application to fail at startup for anyone following the setup instructions. Please correct the schema to expect OPENAI_API_KEY.

Suggested change
GOOGLE_API_KEY: z.string(),
OPENAI_API_KEY: z.string(),

Comment on lines +123 to +125
} catch {
// Silently fail
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The catch block for fetching proposal description logs is empty and fails silently. If the RPC call fails for any reason (e.g., rate limiting, network issues), the error is completely ignored. This leads to the function returning a generic, unhelpful description like "Proposal #123", which will result in a very poor analysis from the LLM. You should at least log the error to aid in debugging.

	} catch (error) {
		// Log error but continue, so a partial proposal can be returned.
		console.error(
			`[governanceService] Failed to fetch description for proposal ${proposalId}:`,
			error,
		);
	}

Comment on lines +245 to +252
for (let id = count; id >= startId; id--) {
try {
const proposal = await getProposal(daoKey, id);
proposals.push(proposal);
} catch (error) {
console.error(`Failed to fetch proposal ${id}:`, error);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The getRecentProposals function fetches proposals sequentially in a for loop. This is inefficient as each await getProposal() call blocks until the previous one is complete. You can significantly improve performance by fetching the proposals in parallel using Promise.allSettled.

	const proposalIds = Array.from({ length: count - startId + 1 }, (_, i) => count - i);
	const results = await Promise.allSettled(
		proposalIds.map((id) => getProposal(daoKey, id)),
	);
	results.forEach((result, i) => {
		if (result.status === "fulfilled") {
			proposals.push(result.value);
		} else {
			console.error(`Failed to fetch proposal ${proposalIds[i]}:`, result.reason);
		}
	});

{
"name": "dao-proposal-analyzer",
"version": "1.0.0",
"description": "Multi-agent DAO governance system that analyzes proposals, simulates outcomes, and recommends votes for DAO members using ADK-TS",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The package description mentions that the system "simulates outcomes". However, based on the current implementation, the agents analyze proposals and provide recommendations, but do not perform any outcome simulation. To avoid confusion, I suggest updating the description to more accurately reflect the project's capabilities.

Suggested change
"description": "Multi-agent DAO governance system that analyzes proposals, simulates outcomes, and recommends votes for DAO members using ADK-TS",
"description": "Multi-agent DAO governance system that analyzes on-chain proposals and provides voting recommendations for DAO members using ADK-TS",

Comment on lines +1 to +4
import * as dotenv from "dotenv";
import { getRootAgent } from "./agents/agent";

dotenv.config();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The dotenv import and dotenv.config() call are redundant here. The environment variables are already loaded and parsed within src/env.ts when it's first imported by any module. To centralize environment handling and avoid redundant operations, you should remove these lines.

Suggested change
import * as dotenv from "dotenv";
import { getRootAgent } from "./agents/agent";
dotenv.config();
import { getRootAgent } from "./agents/agent";

function getClient(): PublicClient {
return createPublicClient({
chain: mainnet,
transport: http(env.ETHEREUM_RPC_URL || "https://eth.drpc.org"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The fallback URL || "https://eth.drpc.org" is effectively dead code. The env.ts file defines a default value for ETHEREUM_RPC_URL, so env.ETHEREUM_RPC_URL will never be falsy. You can simplify this by removing the fallback.

Suggested change
transport: http(env.ETHEREUM_RPC_URL || "https://eth.drpc.org"),
transport: http(env.ETHEREUM_RPC_URL),

Comment on lines +66 to +70
export interface DAOConfig {
name: string;
governor: string;
token: string;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The DAOConfig interface is missing the chain property. The getSupportedDAOs function in governanceService.ts returns an array of objects that include a chain property, but its return type is DAOConfig[]. This creates a type inconsistency. Please add the chain property to the DAOConfig interface.

Suggested change
export interface DAOConfig {
name: string;
governor: string;
token: string;
}
export interface DAOConfig {
name: string;
governor: string;
token: string;
chain: string;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add DAO proposals agent to adk-ts-samples

2 participants