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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this repository are documented in this file.

### Added

- `setup.ps1` Windows PowerShell setup helper and root README Windows setup instructions for native PowerShell users.
- `stripe-payment-agents/twitch-growth-agent/`: Twitch channel growth copilot built on the Fetch.ai uAgents framework. Integrates ASI:One LLM (intent classification, LangGraph 5-node growth pipeline, announcement drafting), Stripe embedded checkout (in-chat one-time unlock), Twitch Helix API (chat settings, announcements, raids, clips), and EventSub WebSocket (reactive copilot that monitors live stream events and proactively suggests actions).

- `Browser-based-agents/playwright/job-application-agent/`: Playwright + ASI:One + Stripe job application agent. Orchestrates a Chromium session to auto-fill Greenhouse application forms using a stored user profile, with LLM-drafted free-text answers via ASI:One, Stripe-gated premium features, and resume ingestion.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This guide explains how to add agents in a consistent, review-friendly format.
1. Fork the repository and clone your fork.
2. Create a feature branch from `main`.
3. Keep changes focused (one feature/fix per PR).
4. Use `./setup.sh <example-folder>` to quickly test any example locally.
4. Use `./setup.sh <example-folder>` on macOS/Linux/Git Bash/WSL or `.\setup.ps1 <example-folder>` on Windows PowerShell to quickly test any example locally.

```bash
git checkout -b feat/short-description
Expand Down
51 changes: 49 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Whether you're building your first agent or architecting multi-agent systems wit

## ⚡ Quickstart — Run Your First Example in Under 2 Minutes

### macOS/Linux/Git Bash/WSL

```bash
# 1. Clone the repo
git clone https://github.com/fetchai/innovation-lab-examples.git
Expand All @@ -41,12 +43,52 @@ cp .env.example .env
python agents/alice/agent.py
```

Or use the **automated setup script** from the repo root:
### Windows PowerShell

```powershell
# 1. Clone the repo
git clone https://github.com/fetchai/innovation-lab-examples.git
cd innovation-lab-examples

# 2. Pick an example (e.g. the hackathon quickstarter)
cd fetch-hackathon-quickstarter

# 3. Create a virtual environment and install dependencies
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt

# 4. Set up environment variables
Copy-Item .env.example .env
# Edit .env with your API keys

# 5. Run the agent
python agents/alice/agent.py
```

### Automated setup helpers

Use the Bash helper from the repo root on macOS/Linux/Git Bash/WSL:

```bash
./setup.sh fetch-hackathon-quickstarter
```

Use the PowerShell helper from the repo root on native Windows PowerShell:

```powershell
.\setup.ps1 fetch-hackathon-quickstarter

# Optional: run the detected entry file after setup
.\setup.ps1 fetch-hackathon-quickstarter -Run
```

If PowerShell blocks local script execution, allow scripts for the current shell process only, then rerun the helper:

```powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
```

> **Prerequisites:** Python 3.10+, pip, and git. Some examples require API keys (ASI:One, OpenAI, Stripe, etc.) — check each example's `.env.example`.

---
Expand All @@ -61,7 +103,8 @@ innovation-lab-examples/
├── SECURITY.md # Vulnerability reporting
├── ISSUES_GUIDE.md # How to file issues
├── LICENSE # Apache 2.0
├── setup.sh # Quickstart setup script
├── setup.sh # Bash quickstart setup script (macOS/Linux/Git Bash/WSL)
├── setup.ps1 # Windows PowerShell quickstart setup script
├── Dockerfile # Run any example in Docker
├── docker-compose.yml # Docker Compose support
├── contributors/ # Community-submitted agent examples (start here!)
Expand Down Expand Up @@ -194,6 +237,10 @@ Or use Docker Compose:
EXAMPLE=fetch-hackathon-quickstarter docker compose up
```

```powershell
$env:EXAMPLE="fetch-hackathon-quickstarter"; docker compose up
```

> Several examples also include their own `Dockerfile` and `docker-compose.yml` for custom setups.

---
Expand Down
171 changes: 171 additions & 0 deletions setup.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Example,

[switch]$Run
)

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$RepoRoot = $PSScriptRoot
$ExampleDir = Join-Path $RepoRoot $Example

function Show-Usage {
Write-Host "Usage: .\setup.ps1 <example-folder> [-Run]"
Write-Host ""
Write-Host "Sets up a Fetch.ai Innovation Lab example for local development."
Write-Host ""
Write-Host "Arguments:"
Write-Host " <example-folder> Name of the example folder (e.g. fetch-hackathon-quickstarter)"
Write-Host " -Run Automatically run the agent after setup (optional)"
Write-Host ""
Write-Host "Examples:"
Write-Host " .\setup.ps1 fetch-hackathon-quickstarter"
Write-Host " .\setup.ps1 gemini-quickstart/01-basic-gemini-agent -Run"
Write-Host " .\setup.ps1 fet-example"
}

function Get-CompatiblePython {
$candidates = @(
[pscustomobject]@{ Command = "python"; Arguments = @() },
[pscustomobject]@{ Command = "py"; Arguments = @("-3") }
)

foreach ($candidate in $candidates) {
if (-not (Get-Command $candidate.Command -ErrorAction SilentlyContinue)) {
continue
}

$versionOutput = & $candidate.Command @($candidate.Arguments + @("--version")) 2>&1
if ($LASTEXITCODE -ne 0) {
continue
}

$versionMatch = [regex]::Match(($versionOutput | Out-String), "(?<version>\d+\.\d+(\.\d+)?)")
if (-not $versionMatch.Success) {
continue
}

$version = [version]$versionMatch.Groups["version"].Value
if ($version -ge [version]"3.10") {
return [pscustomobject]@{
Command = $candidate.Command
Arguments = $candidate.Arguments
Version = $versionOutput
}
}
}

return $null
}

function Invoke-PythonCommand {
param(
[Parameter(Mandatory = $true)]
[pscustomobject]$Python,

[Parameter(Mandatory = $true)]
[string[]]$Arguments
)

& $Python.Command @($Python.Arguments + $Arguments)
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
}

if (-not (Test-Path -Path $ExampleDir -PathType Container)) {
Write-Host "Error: Example folder '$Example' not found."
Write-Host ""
Write-Host "Available examples:"
Get-ChildItem -Path $RepoRoot -Directory |
Where-Object {
-not $_.Name.StartsWith(".") -and
$_.Name -notin @("docs", ".github", "tests") -and
(
(Test-Path (Join-Path $_.FullName "requirements.txt")) -or
(Test-Path (Join-Path $_.FullName "agent.py")) -or
(Test-Path (Join-Path $_.FullName "main.py"))
)
} |
ForEach-Object { Write-Host " $($_.Name)" }
Write-Host ""
Show-Usage
exit 1
}

Write-Host "=== Fetch.ai Innovation Lab Setup ==="
Write-Host "Example: $Example"
Write-Host ""

Set-Location $ExampleDir

$Python = Get-CompatiblePython
if ($null -eq $Python) {
Write-Host "Error: Python 3.10+ is required but not found."
Write-Host "Install Python from https://www.python.org/downloads/"
exit 1
}

Write-Host "[1/4] Using $($Python.Version)"

if (-not (Test-Path -Path ".venv" -PathType Container)) {
Write-Host "[2/4] Creating virtual environment..."
Invoke-PythonCommand -Python $Python -Arguments @("-m", "venv", ".venv")
} else {
Write-Host "[2/4] Virtual environment already exists."
}

$VenvPython = Join-Path $ExampleDir ".venv\Scripts\python.exe"
if (-not (Test-Path -Path $VenvPython -PathType Leaf)) {
Write-Host "Error: Expected virtual environment Python not found at $VenvPython"
exit 1
}

if (Test-Path -Path "requirements.txt" -PathType Leaf) {
Write-Host "[3/4] Installing dependencies..."
& $VenvPython -m pip install -q --upgrade pip
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& $VenvPython -m pip install -q -r requirements.txt
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
} else {
Write-Host "[3/4] No requirements.txt found - skipping dependency install."
}

if ((Test-Path -Path ".env.example" -PathType Leaf) -and -not (Test-Path -Path ".env" -PathType Leaf)) {
Copy-Item -Path ".env.example" -Destination ".env"
Write-Host "[4/4] Created .env from .env.example - edit it with your API keys."
} elseif (Test-Path -Path ".env" -PathType Leaf) {
Write-Host "[4/4] .env already exists - skipping."
} else {
Write-Host "[4/4] No .env.example found - no environment variables needed."
}

$EntryFile = $null
foreach ($candidate in @("agent.py", "main.py", "workflow.py", "app.py")) {
if (Test-Path -Path $candidate -PathType Leaf) {
$EntryFile = $candidate
break
}
}

Write-Host ""
Write-Host "=== Setup Complete ==="
Write-Host ""
Write-Host "To activate the environment:"
Write-Host " cd $Example; .\.venv\Scripts\Activate.ps1"
Write-Host ""

if ($null -ne $EntryFile) {
if ($Run) {
Write-Host "Starting agent..."
& $VenvPython $EntryFile
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
} else {
Write-Host "To run the agent:"
Write-Host " python $EntryFile"
}
} else {
Write-Host "Check the example's README.md for run instructions."
}
39 changes: 39 additions & 0 deletions tests/test_setup_ps1_static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import unittest
from pathlib import Path


REPO_ROOT = Path(__file__).resolve().parents[1]
SETUP_PS1 = REPO_ROOT / "setup.ps1"


class SetupPs1StaticTests(unittest.TestCase):
def test_windows_setup_helper_exists_with_expected_interface(self):
script = SETUP_PS1.read_text(encoding="utf-8")

self.assertIn("[string]$Example", script)
self.assertIn("[switch]$Run", script)
self.assertIn("$PSScriptRoot", script)

def test_windows_setup_helper_matches_bash_safety_behaviors(self):
script = SETUP_PS1.read_text(encoding="utf-8")

self.assertIn("Test-Path", script)
self.assertIn(".env.example", script)
self.assertIn("-not (Test-Path", script)
self.assertIn("requirements.txt", script)
for entry_file in ("agent.py", "main.py", "workflow.py", "app.py"):
self.assertIn(entry_file, script)

def test_windows_setup_helper_checks_python_and_uses_venv_python(self):
script = SETUP_PS1.read_text(encoding="utf-8")

self.assertIn("python", script)
self.assertIn("py", script)
self.assertIn("[version]", script)
self.assertIn("3.10", script)
self.assertIn("Scripts", script)
self.assertIn("python.exe", script)


if __name__ == "__main__":
unittest.main()
Loading