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
88 changes: 88 additions & 0 deletions agents/agents/wiki.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { openai } from "@ai-sdk/openai";
import { Agent } from "@mastra/core/agent";
import { google } from "@ai-sdk/google";
import { anthropic } from "@ai-sdk/anthropic";
export const wikiAgent = new Agent({
name: "Wiki Agent",
instructions: `
You are an AI assistant specialized in converting raw project inputs into a concise, Wikipedia-style article. When given structured data (research, grant application, previous grants, impact certificates, reviews), follow these rules exactly:

1. **Format & Style**

* Use Markdown for all headings, lists, and the metadata table.
* Do not add any extra commentary—only output the wiki-style article.
* If a required data point is missing, write “TBD” in its place.

2. **Sections to Include**

1. **Title and Tagline**

* First line: project name
* Second line: brief tagline or mission statement
2. **Summary**

* A single sentence summarizing the project’s main goal.
3. **Project Overview**

* 2–3 sentences of background/context (key statistics or needs).
* 1–2 sentences describing how the project addresses those needs.
4. **Core Components**

* A bulleted list (4–6 items) of the project’s major activities or workstreams.
5. **Community Engagement**

* One short paragraph on stakeholder involvement and capacity building.
* A bulleted list (3–5 items) of training, workshops, or governance structures.
6. **Impact and Metrics**

* Number of beneficiaries or communities reached.
* Key outcomes or results to date.
* Monitoring tools or methods (if provided).
* Project timeline (start and end dates).
7. **Funding and Sustainability**

* Total budget, amount secured, and any funding gap.
* List of partners or donors.
* One sentence on sustainability plan or scaling strategy.
8. **References**

* A bulleted list of citations drawn from research reports, grant documents, or impact assessments.
9. **Metadata Info Box** (Markdown table)

| Field | Value |
| ------------------- | --------------------------------------------- |
| Project ID | <\<insert or “TBD”>> |
| Category | <\<insert or “TBD”>> |
| Subcategory | <\<insert or “TBD”>> |
| Location | <\<insert or “TBD”>> |
| Status | <\<insert or “TBD”>> |
| Start Date | <\<YYYY-MM-DD or “TBD”>> |
| Expected Completion | <\<YYYY-MM-DD or “TBD”>> |
| Total Budget | <\<currency and amount or “TBD”>> |
| Funding Secured | <\<currency and amount or “TBD”>> |
| Funding Gap | <\<currency and amount or “TBD”>> |
| Beneficiaries | <\<number of people or communities or “TBD”>> |
| Impact Metrics | <\<key metrics or “TBD”>> |
| Sustainability | <\<High/Medium/Low or “TBD”>> |
| Scalability | <\<High/Medium/Low or “TBD”>> |
| Open Source | <\<Yes/No or “TBD”>> |
| Technologies | <\<list of technologies or “TBD”>> |
| Partners | <\<list of partner organizations or “TBD”>> |
| Contact | <\<email or contact info or “TBD”>> |
| Website | <\<URL or “TBD”>> |
| Unique IDs | <\<e.g., GAP ID, OSO ID, GF ID, or “TBD”>> |
| Last Updated | <\<YYYY-MM-DD or “TBD”>> |

3. **Filling in Data**

* Populate each field or bullet with the corresponding information from the inputs.
* Maintain ISO date format (YYYY-MM-DD).
* For missing or unavailable values, write “TBD.”

When you receive the project data, generate only the fully completed wiki-style article in Markdown following this structure.
`,
model: openai("gpt-4.1-2025-04-14"),
// model: google("gemini-1.5-pro-latest", {}),
// model: google("gemini-2.0-flash-thinking-exp-01-21"),
// model: anthropic("claude-3-7-sonnet-20250219"),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# GainForest
*Decentralized technology and regenerative intelligence for transparent, equitable, and scalable conservation.*

---

## Summary

GainForest leverages AI, blockchain, and community-driven data to create a transparent, trustless, and equitable system for global forest conservation and biodiversity protection.

---

## Project Overview

Deforestation and biodiversity loss remain critical global challenges, with traditional conservation funding hampered by trust gaps, slow verification, and exclusion of frontline stewards. GainForest addresses these issues by fusing satellite imagery, AI, and community-sourced data to verify ecological impact in real time, automating transparent funding flows via blockchain, and empowering indigenous and local communities through co-designed digital tools and on-chain environmental hypercerts.

By bridging cutting-edge technology with indigenous wisdom, GainForest creates a scalable, open-source platform that enables grassroots conservation projects to access funding, document impact, and participate in global environmental governance.

---

## Core Components

- **EcoCertain Platform**: Issuance of environmental hypercerts, enabling projects to tokenize and monetize verified ecological impact.
- **Green Globe App**: Geospatial visualization of conservation activities, carbon and biodiversity metrics, and transparent donation tracking.
- **Multi-Source Impact Verification**: Integration of satellite, drone, and bioacoustic data with EAS attestations for robust, real-time impact validation.
- **ImpactQF Funding Mechanism**: Quadratic funding protocol distributing resources based on verified conservation outcomes.
- **Community Onboarding & Toolkits**: Specialized workflows and mobile-friendly interfaces for grassroots and indigenous groups to join Web3 with minimal technical barriers.
- **Open-Source Standards & Interoperability**: Development of reusable frameworks (Ecocerts, ImpactQF) adopted by ReFi DAO, Kolektivo, Ma Earth, and others.

---

## Community Engagement

Stakeholder involvement is central to GainForest, with indigenous leaders and local communities co-designing tools, shaping AI systems, and participating in governance. The project prioritizes capacity building through workshops, hackathons, and knowledge exchange, ensuring technology respects traditional knowledge and empowers frontline stewards.

- Monthly community calls for peer learning and feedback
- Regional environmental AI training workshops
- Local hackathons (e.g., in the Amazon, Brazil)
- Community Data Council for co-governance of data policy
- Youth negotiator training for climate policy engagement (e.g., COP events)

---

## Impact and Metrics

- **Beneficiaries**: Over 28 communities across 3 continents onboarded; $32,000+ distributed in conservation data income (2024)
- **Key Outcomes**:
- 13+ workshops co-hosted with local communities
- Dozens of environmental hypercerts minted and on-chain
- Field-tested, open-source protocols adopted by multiple organizations
- Winner of XPRIZE Rainforest “Most Impactful Approach” (BioDivX co-lead)
- **Monitoring Tools**: Satellite, drone, and bioacoustic data integration; EAS attestations; public dashboards; on-chain transparency
- **Timeline**: Ongoing; major milestones through 2025 (e.g., Impact Verification System, Hypercerts Platform v1, community onboarding)

---

## Funding and Sustainability

- **Total Budget**: $200,000+ (annual core development estimate)
- **Funding Secured**: $80,000 USDC (ENS x Octant), 28.95 ETH (Octant Epoch 7), 25K cUSD (Prezenti), additional grants from Gitcoin, Celo, Ma Earth, and others
- **Funding Gap**: TBD
- **Partners/Donors**: Hypercerts Foundation, ReFi DAO, Kolektivo, Ma Earth, Celo Ultragreen Money, ENS, Octant, Giveth, Gitcoin, and others
- **Sustainability Plan**: Focus on reusable open-source infrastructure, protocol adoption, and network effects to reduce reliance on grants and enable long-term, community-driven scaling

---

## References

- [GainForest Docs](https://gainforest.gitbook.io/docs)
- [Annual Impact Report 23/24](https://www.canva.com/design/DAGNpwdK0jo/QkBOQ1gfl0gy8jDTBAo10g/view?utm_content=DAGNpwdK0jo&utm_campaign=designshare&utm_medium=link&utm_source=editor)
- [EcoCertain Platform](https://ecocertain.xyz)
- [Green Globe App](https://www.gainforest.app)
- [ImpactQF Protocol](https://gov.gitcoin.co/t/citizen-grants-gcp-impact-passports-and-impact-quadratic-funding-impactqf/19712/5)
- [XPRIZE Rainforest Winner Announcement](https://www.xprize.org/prizes/rainforest/articles/xprize-rainforest-names-limelight-rainforest-winner-of-biodiversity-tech-competition)
- Goetz et al., 2009; Hansen et al., 2013; Rolnick et al., 2019 (academic references on remote sensing, deforestation monitoring, and AI for climate)
- [Hypercerts](https://app.hypercerts.org/)
- [GainForest on Giveth](https://giveth.io/project/gainforest)
- [ENS x Octant Public Goods Grant](https://octant.app/project/7/0x98D3F6EBf58b0258ce8ccbE35D53D0162c3A316C)
- [Celo Attestations](https://celo.easscan.org/address/0x00da1b2D16c777D8Be7656C6780d23a98292c0ee)
- [Info Hub for GainForest Community Partners](https://gainforest.notion.site/Info-Hub-for-GainForest-Community-Partners-cbfbb5c733834571ad358db0860c8382)

---

## Metadata Info Box

| Field | Value |
| ------------------- | --------------------------------------------------------------------------------------- |
| Project ID | 0x62f25a11c2ae5a2af563cc5b1f772b3aebe1bd4a0a82e41a78e61e1db972ad7e |
| Category | Open Source Software, Environmental Conservation |
| Subcategory | dApps, Impact Verification, Regenerative Finance, Community Science |
| Location | Global (notably Amazon, SE Asia, Chile, Africa) |
| Status | Active |
| Start Date | 2022-01-01 |
| Expected Completion | 2025-12-31 |
| Total Budget | $200,000+ USD (annual estimate) |
| Funding Secured | $80,000 USDC (ENS x Octant), 28.95 ETH (Octant), 25K cUSD (Prezenti), others |
| Funding Gap | TBD |
| Beneficiaries | 28+ communities, 13+ workshops, $32K+ distributed in 2024 |
| Impact Metrics | Communities onboarded, hypercerts minted, funds distributed, workshops held, biodiversity and carbon metrics, on-chain attestations |
| Sustainability | High |
| Scalability | High |
| Open Source | Yes |
| Technologies | Blockchain (Celo, Filecoin), AI, Satellite/Drone/Bioacoustic Data, EAS, Hypercerts, Quadratic Funding, ZK Proofs |
| Partners | Hypercerts Foundation, ReFi DAO, Kolektivo, Ma Earth, Celo, ENS, Octant, Giveth, Gitcoin |
| Contact | team@gainforest.net |
| Website | https://gainforest.earth |
| Unique IDs | GG23 OSS - dApps and Apps (867_42161), Hypercerts (see above), ENS x Octant, Prezenti |
| Last Updated | 2025-05-14 |
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"review-applications": "bun scripts/review-applications.ts",
"research-projects": "bun scripts/research-projects.ts",
"credit-assignment": "bun scripts/credit-assignment.ts",
"summarize-scores": "bun scripts/summarize-scores.ts"
"summarize-scores": "bun scripts/summarize-scores.ts",
"generate-wiki": "bun scripts/generate-wiki.ts"
},
"devDependencies": {
"@types/bun": "^1.2.11"
Expand Down
182 changes: 182 additions & 0 deletions scripts/generate-wiki.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import {
getApplicationId,
getApplicationPath,
getProjectName,
loadApplicationsFromDirectory,
loadReview,
loadRoundDetails,
saveFile,
loadKarmaGap,
loadResearch,
loadHypercerts,
} from "../utils/utils";

import fs from "fs";
import path from "path";
import { evaluationAgent } from "../agents/agents/evaluator";
import { wikiAgent } from "../agents/agents/wiki";

function parseKarmaGap({ grants }: any) {
if (!grants) return [];
return grants.map((grant: any) => ({
details: grant.details.data,
milestones: grant.milestones.map((milestone: any) => ({
...milestone.data,
endsAt: new Date(milestone.data.endsAt * 1000).toLocaleDateString(),
})),
}));
}

function parseHypercerts(hypercerts: any) {
if (!hypercerts?.data?.hypercerts?.data) {
return [];
}
return hypercerts.data.hypercerts.data.flatMap((hypercert: any) => {
const { hypercert_id, metadata } = hypercert;
if (
!hypercert.attestations?.data ||
hypercert.attestations.data.length === 0
) {
return [];
}
return hypercert.attestations.data.map((attestation: any) => ({
hypercert_id,
metadata,
attester: attestation.attester,
timestamp: new Date(
parseInt(attestation.creation_block_timestamp) * 1000
).toLocaleDateString(),
title: attestation.data.title,
description: attestation.data.description,
sources: attestation.data.sources,
}));
});
}

function loadAllReviews(applicationId: string): any[] {
const dir = getApplicationPath(applicationId);
if (!fs.existsSync(dir)) return [];
return fs
.readdirSync(dir)
.filter((f) => f.startsWith("review-") && f.endsWith(".json"))
.map((f) => {
try {
return JSON.parse(fs.readFileSync(path.join(dir, f), "utf8"));
} catch {
return null;
}
})
.filter(Boolean);
}

async function main() {
try {
const applications = loadApplicationsFromDirectory("application.json");
const applicationIndex = applications.findIndex(
(application) => getProjectName(application) === "GainForest"
);
console.log(applications[applicationIndex]);

for (const application of [applications[applicationIndex]]) {
const applicationId = getApplicationId(application);
const round = loadRoundDetails(application.chainId, application.roundId);
const research = loadResearch(applicationId);
const karmaGap = loadKarmaGap(applicationId);
const karmaGrants = parseKarmaGap(karmaGap ?? { grants: [] });
const hypercerts = loadHypercerts(applicationId);
const hypercertsData = parseHypercerts(
hypercerts ?? { data: { hypercerts: { data: [] } } }
);
const reviews = loadAllReviews(applicationId);

const prompt = `
Using the provided project data (research, grant application, previous grants, impact certificates, reviews), generate a concise, wiki‐style article in Markdown. Include these sections:

1. **Title and Tagline**
- Project name
- Brief tagline or mission statement

2. **Summary**
- One‐sentence overview of the project’s main goal

3. **Project Overview**
- Background/context (key statistics or needs)
- How the project addresses those needs

4. **Core Components**
- 4–6 bullet points listing major activities or workstreams

5. **Community Engagement**
- Description of stakeholder involvement and capacity‐building efforts
- 3–5 bullet points on trainings, workshops, or governance structures

6. **Impact and Metrics**
- Number of beneficiaries or communities reached
- Main outcomes or results to date
- Monitoring tools or methods (if available)
- Project timeline (start and end dates)

7. **Funding and Sustainability**
- Total budget, amount secured, and any funding gap
- List of partners or donors
- Brief note on sustainability plan or scaling strategy

8. **References**
- List any citations from research reports, grant documents, or impact assessments

9. **Metadata Info Box** (table format)
- Project ID
- Category / Subcategory
- Location
- Status
- Dates (start, expected completion)
- Budget details (total, secured, gap)
- Beneficiaries and impact metrics
- Sustainability rating (e.g., high/medium/low)
- Technologies or key tools
- Partner organizations
- Contact info and website (if available)
- Any unique identifiers (e.g., GAP ID, OSO ID, etc.)
- Last updated date

Fill in each section with the relevant information from the inputs. If a specific data point is missing, write “TBD.” Maintain clean Markdown formatting with headings, bullet lists, and a table for the info box.



: ${JSON.stringify(application, null, 2)}\n- Round: ${JSON.stringify(
round,
null,
2
)}\n- Research: ${JSON.stringify(
research,
null,
2
)}\n- Application: ${JSON.stringify(
application,
null,
2
)}\n- Previous Grants (KarmaGap): ${JSON.stringify(
karmaGrants,
null,
2
)}\n- Impact Certs / Hypercerts: ${JSON.stringify(
hypercertsData,
null,
2
)}\n- Reviews: ${JSON.stringify(
reviews,
null,
2
)}\n\nReturn ONLY the markdown article, no prose or commentary.`;

const result = await wikiAgent.generate(prompt);
saveFile(getApplicationPath(applicationId) + "/wiki.md", result.text);
console.log(`✅ Wiki generated for ${getProjectName(application)}`);
}
} catch (error) {
console.error("❌ Error:", error);
process.exit(1);
}
}

main();