Skip to content

Latest commit

Β 

History

40 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

TrendJack

Autonomous AI ops centre for trend-driven advertising β€” built on Google ADK 2.8.0, Gemini 3.7 Flash, and Google Cloud.

TrendJack monitors Google Trends (ZA), automatically runs every green trend through a 10-LLM-agent pipeline (plus deterministic policy and QA nodes), and stages approved campaigns across Google Ads and Meta Ads β€” with a deterministic policy engine and full OTel audit trail at every step.

Submitted to the All Things Agentic Hackathon β€” Fortified Enterprise Fleet track.


Architecture

Google Trends (ZA)  ──▢  Trend Radar  ──▢  confidence β‰₯ 70?
                                                    β”‚ yes
                                                    β–Ό
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚  DISCOVER                           β”‚
                          β”‚  [context_analyst β€– authenticity]   β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚ βš™ Policy Gate
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚  INTELLIGENCE                        β”‚
                          β”‚  [brand_guardian β€– audience          β”‚
                          β”‚   β€– risk_guardian]                   β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚ βš™ Policy Gate
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚  CREATIVE                            β”‚
                          β”‚  [creative_director β€– copywriter     β”‚
                          β”‚   β€– media_planner]                   β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚ βš™ Policy Gate
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚  VERIFY                              β”‚
                          β”‚  [compliance_reviewer β€– red_team     β”‚
                          β”‚   β€– technical_qa]                    β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                         β”‚ βš™ Policy Engine Β· Final Verdict
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          AUTO_STAGE  REVIEW/HOLD  REJECT
                              β”‚
                    Google Ads + Meta Ads (mock gateways)
                    PostgreSQL (Cloud SQL) Β· Full audit trail

All LLM agents run on Vertex AI β€” Gemini 3.7 Flash (locations/global). Parallel agents within each stage run concurrently. technical_qa is a deterministic FunctionNode (no model call). The Policy Engine is fully deterministic β€” no model output can override a hard rule.


Tech Stack

Layer Technology
AI Agents Google ADK 2.8.0 Β· Gemini 3.7 Flash (Vertex AI Β· locations/global)
API FastAPI Β· Python 3.11 Β· Uvicorn
Database PostgreSQL (SQLModel + asyncpg)
Frontend Next.js Β· React Β· TanStack Query Β· Tailwind CSS
Observability OpenTelemetry SDK Β· Cloud Logging (structured JSON)
Cloud infra Cloud Run (API) Β· Cloud SQL (Postgres) Β· Artifact Registry
Trend discovery pytrends (Google Trends, ZA region)

Monorepo structure

trendjack/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ api/          # FastAPI backend + ADK workflow
β”‚   β”‚   β”œβ”€β”€ app/
β”‚   β”‚   β”‚   β”œβ”€β”€ agents/       # ADK Workflow, LlmAgents, FunctionNodes
β”‚   β”‚   β”‚   β”œβ”€β”€ policy/       # Deterministic policy engine + rules
β”‚   β”‚   β”‚   β”œβ”€β”€ gateway/      # Google Ads + Meta Ads mock gateways
β”‚   β”‚   β”‚   β”œβ”€β”€ renderer/     # Creative asset renderer (Pillow + Imagen)
β”‚   β”‚   β”‚   β”œβ”€β”€ observability/# OTel tracer, structured logging, redact
β”‚   β”‚   β”‚   β”œβ”€β”€ routers/      # FastAPI route handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ services/     # run_service, trend_scanner
β”‚   β”‚   β”‚   β”œβ”€β”€ models/       # Pydantic request/response models
β”‚   β”‚   β”‚   β”œβ”€β”€ repositories/ # DB access layer (brand, run, campaign)
β”‚   β”‚   β”‚   └── db/           # SQLModel engine, table models
β”‚   β”‚   └── tests/
β”‚   └── web/          # Next.js dashboard
β”‚       β”œβ”€β”€ app/              # Next.js app-router pages
β”‚       β”œβ”€β”€ components/       # UI components (Runs, Campaigns, Brands…)
β”‚       β”œβ”€β”€ context/          # Theme, sidebar providers
β”‚       β”œβ”€β”€ providers/        # TanStack QueryProvider
β”‚       └── lib/              # api-client, query hooks, utils
└── packages/
    └── contracts/    # Shared TypeScript types

Prerequisites

Tool Version
Python 3.11+
Node.js 20+
npm 10+
PostgreSQL 15+ (local) or Cloud SQL

Local setup

1 β€” Clone and install

git clone <repo-url>
cd trendjack
npm install           # installs web + contracts workspaces
cd apps/api
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

2 β€” Environment variables

Create apps/api/.env:

# Required
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/trendjack

# Gemini via Vertex AI (recommended)
GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global        # gemini-3.7-flash requires global; use us-central1 for older models
# -- or for AI Studio (local dev) --
GEMINI_API_KEY=your-gemini-api-key

# Agent execution β€” set to 1 to make real LLM calls; 0 = simulated responses only
TRENDJACK_AGENTS_ENABLED=1

# Optional overrides
TRENDJACK_AUTH_DISABLED=1          # skip API key header locally
TRENDJACK_DEMO_API_KEY=demo-key-2026
TRENDJACK_CORS_ORIGINS=http://localhost:3000,http://localhost:3001  # comma-separated; add deployed web URL in Cloud Run
TRENDJACK_BASE_URL=http://localhost:8000  # used for agent card URLs; set to public API URL in Cloud Run
GEMINI_MODEL=gemini-3.7-flash      # model override
TRENDJACK_CI_FAKE=0                # set to 1 in CI to skip real API calls

Create apps/web/.env.local:

NEXT_PUBLIC_API_URL=http://localhost:8000

3 β€” Database

Tables are created automatically on first startup via SQLModel.metadata.create_all β€” no migration step needed. Just ensure DATABASE_URL is set and the Postgres server is running before starting the API.

4 β€” Run the API

cd apps/api
uvicorn app.main:app --reload

API available at http://localhost:8000. Interactive docs at http://localhost:8000/docs.

5 β€” Run the frontend

cd apps/web
npm run dev

Dashboard available at http://localhost:3000.


Running a trend through the workflow

# Trigger a run manually
curl -X POST http://localhost:8000/api/v1/runs \
  -H "Content-Type: application/json" \
  -H "X-Demo-API-Key: demo-key-2026" \
  -d '{
    "trend_name": "Load Shedding Solutions",
    "trend_confidence": 82,
    "budget_total_zar": 50000,
    "budget_daily_zar": 5000,
    "flight_days": 10,
    "platforms": ["google", "meta"],
    "creative_headline": "Never Go Dark Again",
    "creative_body": "Solar solutions for South African homes."
  }'

The scheduler runs automatically every 30 minutes β€” any trend from Google Trends (ZA) with confidence β‰₯ 70 is queued automatically.


Running tests

cd apps/api
pytest

CI-safe: set GEMINI_MODEL=fake (or TRENDJACK_CI_FAKE=1) to run the full workflow without paid API calls.


Key API endpoints

Method Path Description
GET /api/v1/trends Current trend scan results
POST /api/v1/runs Create a new agent workflow run
GET /api/v1/runs List all runs
GET /api/v1/runs/{id} Run detail + agent evidence
GET /api/v1/audit/timeline All OTel audit timelines
POST /api/v1/policy/evaluate Evaluate a trend against the policy engine
GET /api/v1/brands List brand profiles
GET /api/v1/brands/{id} Brand detail
PATCH /api/v1/brands/{id} Update brand (name, guidelines, colors, etc.)
GET /api/v1/campaigns List campaigns
GET /api/v1/campaigns/{id} Campaign detail + asset manifest
GET /api/v1/command-centre Live command centre data
POST /api/v1/runs/{id}/approve Human approval of a held run
POST /api/v1/runs/{id}/reject Human rejection of a held run
GET /api/v1/runs/{id}/audit Per-run OTel audit timeline
POST /api/v1/trends/scan Trigger a fresh Google Trends scan
GET /ready Readiness check (DB + dependencies)
GET /health Health check

Cloud Run deployment

GCP project: hackathon-trend-jack Β· Region: us-central1 Β· Registry: us-central1-docker.pkg.dev/hackathon-trend-jack/trendjack/

Prerequisites β€” IAM grants

The Cloud Build service account needs three roles (one-time):

SA="806222250471-compute@developer.gserviceaccount.com"
PROJECT="hackathon-trend-jack"

gcloud projects add-iam-policy-binding $PROJECT --member="serviceAccount:$SA" --role="roles/storage.objectAdmin"
gcloud projects add-iam-policy-binding $PROJECT --member="serviceAccount:$SA" --role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding $PROJECT --member="serviceAccount:$SA" --role="roles/logging.logWriter"

The Cloud Run service account needs Vertex AI and Secret Manager access:

gcloud services enable aiplatform.googleapis.com --project=$PROJECT

gcloud projects add-iam-policy-binding $PROJECT --member="serviceAccount:$SA" --role="roles/aiplatform.user"
gcloud secrets add-iam-policy-binding trendjack-db-url --member="serviceAccount:$SA" --role="roles/secretmanager.secretAccessor" --project=$PROJECT

Note: IAM changes take ~30–60 seconds to propagate β€” no redeploy needed after granting.

Step 1 β€” Create Artifact Registry repository (one-time)

gcloud artifacts repositories create trendjack --repository-format=docker --location=us-central1 --project=hackathon-trend-jack

Step 2 β€” Store database URL as a secret (one-time)

gcloud secrets create trendjack-db-url --replication-policy=automatic --project=hackathon-trend-jack
echo -n "postgresql://USER:PASS@HOST:5432/trendjack" | gcloud secrets versions add trendjack-db-url --data-file=- --project=hackathon-trend-jack

Step 3 β€” Build and deploy the API

# Build and push (run from repo root)
gcloud builds submit apps/api/ \
  --tag us-central1-docker.pkg.dev/hackathon-trend-jack/trendjack/trendjack-api \
  --project hackathon-trend-jack

# Deploy
gcloud run deploy trendjack-api \
  --image us-central1-docker.pkg.dev/hackathon-trend-jack/trendjack/trendjack-api \
  --region us-central1 \
  --platform managed \
  --allow-unauthenticated \
  --set-env-vars "TRENDJACK_AGENTS_ENABLED=1,GOOGLE_CLOUD_PROJECT=hackathon-trend-jack,GOOGLE_CLOUD_LOCATION=global,GOOGLE_GENAI_USE_VERTEXAI=1,GEMINI_MODEL=gemini-3.7-flash,TRENDJACK_CORS_ORIGINS=https://trendjack-web-806222250471.us-central1.run.app" \
  --set-secrets "DATABASE_URL=trendjack-db-url:latest" \
  --memory 2Gi --cpu 2 --timeout 300 \
  --project hackathon-trend-jack

After deploy, set the public URL so agent cards use the correct endpoint, and confirm the CORS origin matches the frontend URL:

gcloud run services update trendjack-api \
  --region us-central1 \
  --update-env-vars "TRENDJACK_BASE_URL=https://trendjack-api-806222250471.us-central1.run.app,TRENDJACK_CORS_ORIGINS=https://trendjack-web-806222250471.us-central1.run.app" \
  --project hackathon-trend-jack

CORS note: TRENDJACK_CORS_ORIGINS must list every origin that the browser will use to call the API (comma-separated). Without it the API falls back to localhost-only origins and the deployed frontend will get 403 Forbidden CORS errors. Update it whenever the frontend URL changes (e.g. after a new Cloud Run revision assigns a different URL).

To update an already-running service without a full redeploy:

gcloud run services update trendjack-api \
  --region us-central1 \
  --update-env-vars "TRENDJACK_CORS_ORIGINS=https://trendjack-web-806222250471.us-central1.run.app" \
  --project hackathon-trend-jack

Step 4 β€” Build and deploy the frontend

The frontend build bakes NEXT_PUBLIC_API_URL at compile time.

# Build and push (run from repo root)
gcloud builds submit . \
  --config=cloudbuild-web.yaml \
  --substitutions=_NEXT_PUBLIC_API_URL=https://trendjack-api-806222250471.us-central1.run.app \
  --project hackathon-trend-jack

# Deploy
gcloud run deploy trendjack-web \
  --image us-central1-docker.pkg.dev/hackathon-trend-jack/trendjack/trendjack-web \
  --region us-central1 \
  --platform managed \
  --allow-unauthenticated \
  --memory 1Gi --cpu 1 --timeout 60 \
  --project hackathon-trend-jack

Agent Registry (GEAP β€” Fortified Enterprise Fleet)

TrendJack registers all 11 agents (1 fleet + 10 LLM specialists) in Vertex AI Agent Registry using the A2A v1.0 protocol. (technical_qa is a deterministic FunctionNode and is not separately registered.)

Agent card endpoints served by the API:

Endpoint Description
GET /.well-known/agent-card.json Fleet A2A card (registry entry point)
GET /api/v1/agents Catalog of all specialist agents
GET /api/v1/agents/{id}/agent-card.json Individual agent A2A card

Register or update all agents (upserts β€” safe to re-run after URL changes):

cd apps/api
python scripts/register_agents.py \
  --project=hackathon-trend-jack \
  --location=us-central1 \
  --base-url=https://trendjack-api-806222250471.us-central1.run.app

Options: --fleet-only to register only the fleet card, --list to inspect current state, --dry-run to preview request bodies without calling the API.

Prerequisite: gcloud auth application-default login and gcloud services enable agentregistry.googleapis.com --project=hackathon-trend-jack.


Governance & Observability

Every run produces a full OTel-compatible audit trail (trace_id + span_id on every entry), written as structured JSON to Cloud Logging. The Governance page in the dashboard shows live audit timelines. Key invariant: rejected runs never produce a gateway call β€” the policy engine terminates the workflow before any ad platform is contacted. This is enforced in code and covered by TestRejectedRunNoGateway in the test suite.

See docs/OBSERVABILITY.md for the full trace model.


Hackathon track

Fortified Enterprise Fleet β€” scalable multi-agent system with governance.

  • 10 LLM agents (Google ADK 2.8.0) with parallel fan-out across four stages (Discover Β· Intelligence Β· Creative Β· Verify), plus deterministic policy and QA nodes
  • Deterministic policy engine with scored rules (0–100) gating every stage transition β€” AI advises, rules decide
  • Full OTel audit trail with structured JSON logging to Cloud Logging
  • Automated trend scheduler running every 30 minutes without human intervention
  • Mock Google Ads + Meta Ads gateways with simulated receipts (simulated: true)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages