Compare commits

..

58 Commits

Author SHA1 Message Date
Reinier van der Leer
7e0b1156cc feat(agent): Improve history format for code flow execution results 2024-07-23 23:15:50 +02:00
Reinier van der Leer
da9360fdeb feat(agent/api): Pretty-print execute_code_flow proposal in Agent Protocol output 2024-07-23 22:55:16 +02:00
Reinier van der Leer
9dea6a273e Merge branch 'master' into zamilmajdy/code-validation 2024-07-23 22:42:32 +02:00
Reinier van der Leer
e19636ac3e feat(agent/cli): Pretty-print code flow proposal
- Amend `main.py:update_user(..)` to improve displaying of existing + new prompt strategy output
- Replace `"execute_code_flow"` literals with references to the command definition
2024-07-23 22:18:54 +02:00
Reinier van der Leer
f03c6546b8 Merge branch 'master' into zamilmajdy/code-validation 2024-07-23 20:38:30 +02:00
Reinier van der Leer
2c4afd4458 Migrate autogpt/agents/prompt_strategies/code_flow.py to Pydantic v2 2024-07-04 01:07:16 -06:00
Reinier van der Leer
8b1d416de3 Merge branch 'master' into zamilmajdy/code-validation 2024-07-04 01:05:40 -06:00
Reinier van der Leer
7f6b7d6d7e remove unused import in forge/llm/providers/openai.py 2024-07-02 13:05:53 -06:00
Reinier van der Leer
736ac778cc Merge branch 'master' into zamilmajdy/code-validation 2024-07-02 13:05:31 -06:00
Reinier van der Leer
38eafdbb66 Update CodeFlowPromptStrategy with upstream changes (#7223) 2024-07-02 04:29:55 +02:00
Reinier van der Leer
6d9f564dc5 Merge branch 'master' into zamilmajdy/code-validation 2024-07-01 20:16:31 -06:00
Reinier van der Leer
3e675123d7 Merge branch 'master' into zamilmajdy/code-validation 2024-06-27 14:12:19 -06:00
Reinier van der Leer
37cc047656 lint-fix + minor refactor 2024-06-25 09:55:13 -07:00
Reinier van der Leer
9f804080ed address feedback: pass commands getter to CodeFlowExecutionComponent(..) 2024-06-25 09:30:26 -07:00
Reinier van der Leer
680fbf49aa Merge branch 'master' into zamilmajdy/code-validation 2024-06-24 20:42:52 -07:00
Krzysztof Czerwinski
901dadefc3 Merge branch 'master' into zamilmajdy/code-validation 2024-06-19 13:05:40 +02:00
Nicholas Tindle
e204491c6c Merge branch 'master' into zamilmajdy/code-validation 2024-06-13 17:33:44 -05:00
Zamil Majdy
3597f801a7 Merge branch 'master' of github.com:Significant-Gravitas/AutoGPT into zamilmajdy/code-validation 2024-06-10 13:05:05 +07:00
Zamil Majdy
b59862c402 Address comment 2024-06-10 13:04:54 +07:00
Reinier van der Leer
81bac301e8 fix type issues 2024-06-08 23:44:45 +02:00
Reinier van der Leer
a9eb49d54e Merge branch 'master' into zamilmajdy/code-validation 2024-06-08 21:52:36 +02:00
Reinier van der Leer
2c6e1eb4c8 fix type issue in test_code_flow_strategy.py 2024-06-08 21:38:22 +02:00
Reinier van der Leer
3e8849b08e fix linting and type issues 2024-06-08 21:32:10 +02:00
Reinier van der Leer
111e8585b5 feat(forge/llm): allow async completion parsers 2024-06-08 21:29:35 +02:00
Reinier van der Leer
8144d26cef fix type issues 2024-06-08 21:02:44 +02:00
Reinier van der Leer
e264bf7764 forge.llm.providers.schema + code_flow_executor lint-fix and cleanup 2024-06-08 15:28:52 +02:00
Reinier van der Leer
6dd0975236 clean up & improve @command decorator
- add ability to extract parameter descriptions from docstring
- add ability to determine parameter JSON schemas from function signature
- add `JSONSchema.from_python_type` factory
2024-06-08 15:05:45 +02:00
Reinier van der Leer
c3acb99314 clean up forge.command.command 2024-06-08 15:01:00 +02:00
Reinier van der Leer
0578fb0246 fix async issues with code flow execution 2024-06-08 02:03:22 +02:00
Reinier van der Leer
731d0345f0 implement annotation expansion for non-builtin types 2024-06-08 02:01:20 +02:00
Reinier van der Leer
b4cd735f26 fix name collision with type in Command.return_type 2024-06-07 12:57:30 +02:00
Reinier van der Leer
6e715b6c71 simplify function header generation 2024-06-07 12:56:41 +02:00
Reinier van der Leer
fcca4cc893 clarify execute_code_flow 2024-06-03 22:00:34 +02:00
Reinier van der Leer
5c7c276c10 Merge branch 'master' into zamilmajdy/code-validation 2024-06-03 21:43:59 +02:00
Zamil Majdy
ae63aa8ebb Merge remote-tracking branch 'origin/zamilmajdy/code-validation' into zamilmajdy/code-validation 2024-05-20 22:39:47 +07:00
Zamil Majdy
fdd9f9b5ec Log fix 2024-05-20 22:39:30 +07:00
Zamil Majdy
a825aa8515 Merge branch 'master' into zamilmajdy/code-validation 2024-05-20 16:53:52 +02:00
Zamil Majdy
ae43136c2c Fix linting 2024-05-20 18:48:44 +07:00
Zamil Majdy
c8e16f3fe1 Fix linting 2024-05-20 18:42:36 +07:00
Zamil Majdy
3a60504138 isort 2024-05-20 18:21:17 +07:00
Zamil Majdy
dfa77739c3 Remove unnecessary changes 2024-05-20 18:14:39 +07:00
Zamil Majdy
9f6e25664c Debug Log changes 2024-05-20 18:11:53 +07:00
Zamil Majdy
3c4ff60e11 Add unit tests 2024-05-20 18:09:16 +07:00
Zamil Majdy
47eeaf0325 Revert dumb changes 2024-05-20 17:07:55 +07:00
Zamil Majdy
81ad3cb69a Merge conflicts 2024-05-20 17:00:25 +07:00
Zamil Majdy
834eb6c6e0 Some quality polishing 2024-05-20 15:56:18 +07:00
Zamil Majdy
fb802400ba Add return type 2024-05-17 17:10:54 +02:00
Zamil Majdy
922e643737 Fix Await fiasco 2024-05-17 00:57:29 +02:00
Zamil Majdy
7b5272f1f2 Fix Await fiasco 2024-05-17 00:50:11 +02:00
Zamil Majdy
ea134c7dbd Benchmark test 2024-05-16 20:09:10 +02:00
Zamil Majdy
f7634524fa More prompt engineering 2024-05-16 19:53:42 +02:00
Zamil Majdy
0eccbe1483 Prompt change 2024-05-15 21:04:52 +02:00
Zamil Majdy
0916df4df7 Fix async fiasco 2024-05-15 19:30:29 +02:00
Zamil Majdy
22e2373a0b Add code flow as a loop 2024-05-15 17:10:51 +02:00
Zamil Majdy
40426e4646 Merge master 2024-05-14 23:36:31 +02:00
Zamil Majdy
ef1fe7c4e8 Update notebook 2024-05-11 12:12:30 +02:00
Reinier van der Leer
ca7ca226ff one_shot_flow.ipynb + edits to make it work 2024-05-10 20:03:40 +02:00
Zamil Majdy
ed5f12c02b Add code validation 2024-05-10 16:43:53 +02:00
2873 changed files with 31518 additions and 119050 deletions

View File

@@ -2,11 +2,11 @@
*
# AutoGPT
!original_autogpt/autogpt/
!original_autogpt/pyproject.toml
!original_autogpt/poetry.lock
!original_autogpt/README.md
!original_autogpt/tests/
!autogpt/autogpt/
!autogpt/pyproject.toml
!autogpt/poetry.lock
!autogpt/README.md
!autogpt/tests/
# Benchmark
!benchmark/agbenchmark/
@@ -15,7 +15,7 @@
!benchmark/README.md
# Forge
!forge/
!forge/forge/
!forge/pyproject.toml
!forge/poetry.lock
!forge/README.md

6
.gitattributes vendored
View File

@@ -1,10 +1,8 @@
classic/frontend/build/** linguist-generated
frontend/build/** linguist-generated
**/poetry.lock linguist-generated
docs/_javascript/** linguist-vendored
# Exclude VCR cassettes from stats
classic/forge/tests/vcr_cassettes/**/**.y*ml linguist-generated
* text=auto
forge/tests/vcr_cassettes/**/**.y*ml linguist-generated

12
.github/CODEOWNERS vendored
View File

@@ -1,7 +1,5 @@
* @Significant-Gravitas/maintainers
.github/workflows/ @Significant-Gravitas/devops
classic/forge/ @Significant-Gravitas/forge-maintainers
classic/benchmark/ @Significant-Gravitas/benchmark-maintainers
classic/frontend/ @Significant-Gravitas/frontend-maintainers
autogpt_platform/infra @Significant-Gravitas/devops
.github/CODEOWNERS @Significant-Gravitas/admins
.github/workflows/ @Significant-Gravitas/devops
autogpt/ @Significant-Gravitas/maintainers
forge/ @Significant-Gravitas/forge-maintainers
benchmark/ @Significant-Gravitas/benchmark-maintainers
frontend/ @Significant-Gravitas/frontend-maintainers

View File

@@ -6,18 +6,26 @@
<!-- Concisely describe all of the changes made in this pull request: -->
### Testing 🔍
> [!NOTE]
Only for the new autogpt platform, currently in autogpt_platform/
### PR Quality Scorecard ✨
<!--
Please make sure your changes have been tested and are in good working condition.
Here is a list of our critical paths, if you need some inspiration on what and how to test:
Check out our contribution guide:
https://github.com/Significant-Gravitas/AutoGPT/wiki/Contributing
1. Avoid duplicate work, issues, PRs etc.
2. Also consider contributing something other than code; see the [contribution guide]
for options.
3. Clearly explain your changes.
4. Avoid making unnecessary changes, especially if they're purely based on personal
preferences. Doing so is the maintainers' job. ;-)
-->
- Create from scratch and execute an agent with at least 3 blocks
- Import an agent from file upload, and confirm it executes correctly
- Upload agent to marketplace
- Import an agent from marketplace and confirm it executes correctly
- Edit an agent from monitor, and confirm it executes correctly
- [x] Have you used the PR description template? &ensp; `+2 pts`
- [ ] Is your pull request atomic, focusing on a single change? &ensp; `+5 pts`
- [ ] Have you linked the GitHub issue(s) that this PR addresses? &ensp; `+5 pts`
- [ ] Have you documented your changes clearly and comprehensively? &ensp; `+5 pts`
- [ ] Have you changed or added a feature? &ensp; `-4 pts`
- [ ] Have you added/updated corresponding documentation? &ensp; `+4 pts`
- [ ] Have you added/updated corresponding integration tests? &ensp; `+5 pts`
- [ ] Have you changed the behavior of AutoGPT? &ensp; `-5 pts`
- [ ] Have you also run `agbenchmark` to verify that these changes do not regress performance? &ensp; `+10 pts`

12
.github/labeler.yml vendored
View File

@@ -1,18 +1,18 @@
AutoGPT Agent:
- changed-files:
- any-glob-to-any-file: classic/original_autogpt/**
- any-glob-to-any-file: autogpt/**
Forge:
- changed-files:
- any-glob-to-any-file: classic/forge/**
- any-glob-to-any-file: forge/**
Benchmark:
- changed-files:
- any-glob-to-any-file: classic/benchmark/**
- any-glob-to-any-file: benchmark/**
Frontend:
- changed-files:
- any-glob-to-any-file: classic/frontend/**
- any-glob-to-any-file: frontend/**
documentation:
- changed-files:
@@ -20,8 +20,8 @@ documentation:
Builder:
- changed-files:
- any-glob-to-any-file: autogpt_platform/autogpt_builder/**
- any-glob-to-any-file: rnd/autogpt_builder/**
Server:
- changed-files:
- any-glob-to-any-file: autogpt_platform/autogpt_server/**
- any-glob-to-any-file: rnd/autogpt_server/**

View File

@@ -1,23 +1,22 @@
name: Platform - AutoGPT Builder CI
name: AutoGPT Builder CI
on:
push:
branches: [ master ]
paths:
- '.github/workflows/autogpt-builder-ci.yml'
- 'autogpt_platform/autogpt_builder/**'
- 'rnd/autogpt_builder/**'
pull_request:
paths:
- '.github/workflows/autogpt-builder-ci.yml'
- 'autogpt_platform/autogpt_builder/**'
- 'rnd/autogpt_builder/**'
defaults:
run:
shell: bash
working-directory: autogpt_platform/autogpt_builder
working-directory: rnd/autogpt_builder
jobs:
lint:
runs-on: ubuntu-latest
@@ -32,10 +31,6 @@ jobs:
run: |
npm install
- name: Check formatting with Prettier
run: |
npx prettier --check .
- name: Run lint
run: |
npm run lint

View File

@@ -1,25 +1,25 @@
name: Classic - AutoGPT CI
name: AutoGPT CI
on:
push:
branches: [ master, development, ci-test* ]
paths:
- '.github/workflows/classic-autogpt-ci.yml'
- 'classic/original_autogpt/**'
- '.github/workflows/autogpt-ci.yml'
- 'autogpt/**'
pull_request:
branches: [ master, development, release-* ]
paths:
- '.github/workflows/classic-autogpt-ci.yml'
- 'classic/original_autogpt/**'
- '.github/workflows/autogpt-ci.yml'
- 'autogpt/**'
concurrency:
group: ${{ format('classic-autogpt-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
group: ${{ format('autogpt-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
cancel-in-progress: ${{ startsWith(github.event_name, 'pull_request') }}
defaults:
run:
shell: bash
working-directory: classic/original_autogpt
working-directory: autogpt
jobs:
test:
@@ -86,7 +86,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ runner.os == 'macOS' && '~/Library/Caches/pypoetry' || '~/.cache/pypoetry' }}
key: poetry-${{ runner.os }}-${{ hashFiles('classic/original_autogpt/poetry.lock') }}
key: poetry-${{ runner.os }}-${{ hashFiles('autogpt/poetry.lock') }}
- name: Install Poetry (Unix)
if: runner.os != 'Windows'
@@ -135,4 +135,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: test-logs
path: classic/original_autogpt/logs/
path: autogpt/logs/

View File

@@ -1,4 +1,4 @@
name: Classic - Purge Auto-GPT Docker CI cache
name: Purge Auto-GPT Docker CI cache
on:
schedule:
@@ -25,8 +25,7 @@ jobs:
name: Build image
uses: docker/build-push-action@v5
with:
context: classic/
file: classic/Dockerfile.autogpt
file: Dockerfile.autogpt
build-args: BUILD_TYPE=${{ matrix.build-type }}
load: true # save to docker images
# use GHA cache as read-only

View File

@@ -1,26 +1,24 @@
name: Classic - AutoGPT Docker CI
name: AutoGPT Docker CI
on:
push:
branches: [ master, development ]
paths:
- '.github/workflows/classic-autogpt-docker-ci.yml'
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- '.github/workflows/autogpt-docker-ci.yml'
- 'autogpt/**'
pull_request:
branches: [ master, development, release-* ]
paths:
- '.github/workflows/classic-autogpt-docker-ci.yml'
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- '.github/workflows/autogpt-docker-ci.yml'
- 'autogpt/**'
concurrency:
group: ${{ format('classic-autogpt-docker-ci-{0}', github.head_ref && format('pr-{0}', github.event.pull_request.number) || github.sha) }}
group: ${{ format('autogpt-docker-ci-{0}', github.head_ref && format('pr-{0}', github.event.pull_request.number) || github.sha) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
defaults:
run:
working-directory: classic/original_autogpt
working-directory: autogpt
env:
IMAGE_NAME: auto-gpt
@@ -49,8 +47,7 @@ jobs:
name: Build image
uses: docker/build-push-action@v5
with:
context: classic/
file: classic/Dockerfile.autogpt
file: Dockerfile.autogpt
build-args: BUILD_TYPE=${{ matrix.build-type }}
tags: ${{ env.IMAGE_NAME }}
labels: GIT_REVISION=${{ github.sha }}
@@ -119,8 +116,7 @@ jobs:
name: Build image
uses: docker/build-push-action@v5
with:
context: classic/
file: classic/Dockerfile.autogpt
file: Dockerfile.autogpt
build-args: BUILD_TYPE=dev # include pytest
tags: >
${{ env.IMAGE_NAME }},

View File

@@ -1,4 +1,4 @@
name: Classic - AutoGPT Docker Release
name: AutoGPT Docker Release
on:
release:
@@ -44,7 +44,6 @@ jobs:
name: Build image
uses: docker/build-push-action@v5
with:
context: classic/
file: Dockerfile.autogpt
build-args: BUILD_TYPE=release
load: true # save to docker images

View File

@@ -1,16 +1,16 @@
name: Platform - AutoGPT Server CI
name: AutoGPT Server CI
on:
push:
branches: [master, development, ci-test*]
paths:
- ".github/workflows/autogpt-server-ci.yml"
- "autogpt_platform/autogpt_server/**"
- "rnd/autogpt_server/**"
pull_request:
branches: [master, development, release-*]
paths:
- ".github/workflows/autogpt-server-ci.yml"
- "autogpt_platform/autogpt_server/**"
- "rnd/autogpt_server/**"
concurrency:
group: ${{ format('autogpt-server-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
@@ -19,7 +19,7 @@ concurrency:
defaults:
run:
shell: bash
working-directory: autogpt_platform/autogpt_server
working-directory: rnd/autogpt_server
jobs:
test:
@@ -37,8 +37,8 @@ jobs:
- name: Setup PostgreSQL
uses: ikalnytskyi/action-setup-postgres@v6
with:
username: ${{ secrets.DB_USER || 'postgres' }}
password: ${{ secrets.DB_PASS || 'postgres' }}
username: ${{ secrets.DB_USER }}
password: ${{ secrets.DB_PASS }}
database: postgres
port: 5432
id: postgres
@@ -90,7 +90,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ runner.os == 'macOS' && '~/Library/Caches/pypoetry' || '~/.cache/pypoetry' }}
key: poetry-${{ runner.os }}-${{ hashFiles('autogpt_platform/autogpt_server/poetry.lock') }}
key: poetry-${{ runner.os }}-${{ hashFiles('rnd/autogpt_server/poetry.lock') }}
- name: Install Poetry (Unix)
if: runner.os != 'Windows'
@@ -115,38 +115,31 @@ jobs:
run: poetry install
- name: Generate Prisma Client
run: poetry run prisma generate
run: poetry run prisma generate --schema postgres/schema.prisma
- name: Run Database Migrations
run: poetry run prisma migrate dev --name updates
run: poetry run prisma migrate dev --schema postgres/schema.prisma --name updates
env:
CONNECTION_STR: ${{ steps.postgres.outputs.connection-uri }}
- id: lint
name: Run Linter
- name: Run Linter
run: poetry run lint
- name: Run pytest with coverage
run: |
if [[ "${{ runner.debug }}" == "1" ]]; then
poetry run pytest -vv -o log_cli=true -o log_cli_level=DEBUG test
else
poetry run pytest -vv test
fi
if: success() || (failure() && steps.lint.outcome == 'failure')
env:
LOG_LEVEL: ${{ runner.debug && 'DEBUG' || 'INFO' }}
poetry run pytest -vv \
test
env:
CI: true
PLAIN_OUTPUT: True
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DB_USER: ${{ secrets.DB_USER || 'postgres' }}
DB_PASS: ${{ secrets.DB_PASS || 'postgres' }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASS: ${{ secrets.DB_PASS }}
DB_NAME: postgres
DB_PORT: 5432
RUN_ENV: local
PORT: 8080
DATABASE_URL: postgresql://${{ secrets.DB_USER || 'postgres' }}:${{ secrets.DB_PASS || 'postgres' }}@localhost:5432/${{ secrets.DB_NAME || 'postgres'}}
DATABASE_URL: postgresql://${{ secrets.DB_USER }}:${{ secrets.DB_PASS }}@localhost:5432/${{ secrets.DB_NAME }}
# - name: Upload coverage reports to Codecov
# uses: codecov/codecov-action@v4

View File

@@ -0,0 +1,97 @@
name: AutoGPTs Nightly Benchmark
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * *'
jobs:
benchmark:
permissions:
contents: write
runs-on: ubuntu-latest
strategy:
matrix:
agent-name: [ autogpt ]
fail-fast: false
timeout-minutes: 120
env:
min-python-version: '3.10'
REPORTS_BRANCH: data/benchmark-reports
REPORTS_FOLDER: ${{ format('benchmark/reports/{0}', matrix.agent-name) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- name: Set up Python ${{ env.min-python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.min-python-version }}
- name: Install Poetry
run: curl -sSL https://install.python-poetry.org | python -
- name: Prepare reports folder
run: mkdir -p ${{ env.REPORTS_FOLDER }}
- run: poetry -C benchmark install
- name: Benchmark ${{ matrix.agent-name }}
run: |
./run agent start ${{ matrix.agent-name }}
cd ${{ matrix.agent-name }}
set +e # Do not quit on non-zero exit codes
poetry run agbenchmark run -N 3 \
--test=ReadFile \
--test=BasicRetrieval --test=RevenueRetrieval2 \
--test=CombineCsv --test=LabelCsv --test=AnswerQuestionCombineCsv \
--test=UrlShortener --test=TicTacToe --test=Battleship \
--test=WebArenaTask_0 --test=WebArenaTask_21 --test=WebArenaTask_124 \
--test=WebArenaTask_134 --test=WebArenaTask_163
# Convert exit code 1 (some challenges failed) to exit code 0
if [ $? -eq 0 ] || [ $? -eq 1 ]; then
exit 0
else
exit $?
fi
env:
AGENT_NAME: ${{ matrix.agent-name }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
REQUESTS_CA_BUNDLE: /etc/ssl/certs/ca-certificates.crt
REPORTS_FOLDER: ${{ format('../../{0}', env.REPORTS_FOLDER) }} # account for changed workdir
TELEMETRY_ENVIRONMENT: autogpt-benchmark-ci
TELEMETRY_OPT_IN: ${{ github.ref_name == 'master' }}
- name: Push reports to data branch
run: |
# BODGE: Remove success_rate.json and regression_tests.json to avoid conflicts on checkout
rm ${{ env.REPORTS_FOLDER }}/*.json
# Find folder with newest (untracked) report in it
report_subfolder=$(find ${{ env.REPORTS_FOLDER }} -type f -name 'report.json' \
| xargs -I {} dirname {} \
| xargs -I {} git ls-files --others --exclude-standard {} \
| xargs -I {} dirname {} \
| sort -u)
json_report_file="$report_subfolder/report.json"
# Convert JSON report to Markdown
markdown_report_file="$report_subfolder/report.md"
poetry -C benchmark run benchmark/reports/format.py "$json_report_file" > "$markdown_report_file"
cat "$markdown_report_file" >> $GITHUB_STEP_SUMMARY
git config --global user.name 'GitHub Actions'
git config --global user.email 'github-actions@agpt.co'
git fetch origin ${{ env.REPORTS_BRANCH }}:${{ env.REPORTS_BRANCH }} \
&& git checkout ${{ env.REPORTS_BRANCH }} \
|| git checkout --orphan ${{ env.REPORTS_BRANCH }}
git reset --hard
git add ${{ env.REPORTS_FOLDER }}
git commit -m "Benchmark report for ${{ matrix.agent-name }} @ $(date +'%Y-%m-%d')" \
&& git push origin ${{ env.REPORTS_BRANCH }}

View File

@@ -1,4 +1,4 @@
name: Classic - Agent smoke tests
name: Agent smoke tests
on:
workflow_dispatch:
@@ -7,37 +7,32 @@ on:
push:
branches: [ master, development, ci-test* ]
paths:
- '.github/workflows/classic-autogpts-ci.yml'
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- 'classic/benchmark/**'
- 'classic/run'
- 'classic/cli.py'
- 'classic/setup.py'
- '.github/workflows/autogpts-ci.yml'
- 'autogpt/**'
- 'forge/**'
- 'benchmark/**'
- 'run'
- 'cli.py'
- 'setup.py'
- '!**/*.md'
pull_request:
branches: [ master, development, release-* ]
paths:
- '.github/workflows/classic-autogpts-ci.yml'
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- 'classic/benchmark/**'
- 'classic/run'
- 'classic/cli.py'
- 'classic/setup.py'
- '.github/workflows/autogpts-ci.yml'
- 'autogpt/**'
- 'forge/**'
- 'benchmark/**'
- 'run'
- 'cli.py'
- 'setup.py'
- '!**/*.md'
defaults:
run:
shell: bash
working-directory: classic
jobs:
serve-agent-protocol:
runs-on: ubuntu-latest
strategy:
matrix:
agent-name: [ original_autogpt ]
agent-name: [ autogpt ]
fail-fast: false
timeout-minutes: 20
env:
@@ -55,7 +50,7 @@ jobs:
python-version: ${{ env.min-python-version }}
- name: Install Poetry
working-directory: ./classic/${{ matrix.agent-name }}/
working-directory: ./${{ matrix.agent-name }}/
run: |
curl -sSL https://install.python-poetry.org | python -

View File

@@ -1,18 +1,18 @@
name: Classic - AGBenchmark CI
name: AGBenchmark CI
on:
push:
branches: [ master, development, ci-test* ]
paths:
- 'classic/benchmark/**'
- '!classic/benchmark/reports/**'
- .github/workflows/classic-benchmark-ci.yml
- 'benchmark/**'
- .github/workflows/benchmark-ci.yml
- '!benchmark/reports/**'
pull_request:
branches: [ master, development, release-* ]
paths:
- 'classic/benchmark/**'
- '!classic/benchmark/reports/**'
- .github/workflows/classic-benchmark-ci.yml
- 'benchmark/**'
- '!benchmark/reports/**'
- .github/workflows/benchmark-ci.yml
concurrency:
group: ${{ format('benchmark-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
@@ -39,7 +39,7 @@ jobs:
defaults:
run:
shell: bash
working-directory: classic/benchmark
working-directory: benchmark
steps:
- name: Checkout repository
uses: actions/checkout@v4
@@ -58,7 +58,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ runner.os == 'macOS' && '~/Library/Caches/pypoetry' || '~/.cache/pypoetry' }}
key: poetry-${{ runner.os }}-${{ hashFiles('classic/benchmark/poetry.lock') }}
key: poetry-${{ runner.os }}-${{ hashFiles('benchmark/poetry.lock') }}
- name: Install Poetry (Unix)
if: runner.os != 'Windows'
@@ -122,7 +122,7 @@ jobs:
curl -sSL https://install.python-poetry.org | python -
- name: Run regression tests
working-directory: classic
working-directory: .
run: |
./run agent start ${{ matrix.agent-name }}
cd ${{ matrix.agent-name }}
@@ -155,7 +155,7 @@ jobs:
poetry run agbenchmark --mock
CHANGED=$(git diff --name-only | grep -E '(agbenchmark/challenges)|(../classic/frontend/assets)') || echo "No diffs"
CHANGED=$(git diff --name-only | grep -E '(agbenchmark/challenges)|(../frontend/assets)') || echo "No diffs"
if [ ! -z "$CHANGED" ]; then
echo "There are unstaged changes please run agbenchmark and commit those changes since they are needed."
echo "$CHANGED"

View File

@@ -1,4 +1,4 @@
name: Classic - Publish to PyPI
name: Publish to PyPI
on:
workflow_dispatch:
@@ -21,21 +21,21 @@ jobs:
python-version: 3.8
- name: Install Poetry
working-directory: ./classic/benchmark/
working-directory: ./benchmark/
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Build project for distribution
working-directory: ./classic/benchmark/
working-directory: ./benchmark/
run: poetry build
- name: Install dependencies
working-directory: ./classic/benchmark/
working-directory: ./benchmark/
run: poetry install
- name: Check Version
working-directory: ./classic/benchmark/
working-directory: ./benchmark/
id: check-version
run: |
echo version=$(poetry version --short) >> $GITHUB_OUTPUT
@@ -43,7 +43,7 @@ jobs:
- name: Create Release
uses: ncipollo/release-action@v1
with:
artifacts: "classic/benchmark/dist/*"
artifacts: "benchmark/dist/*"
token: ${{ secrets.GITHUB_TOKEN }}
draft: false
generateReleaseNotes: false
@@ -51,5 +51,5 @@ jobs:
commit: master
- name: Build and publish
working-directory: ./classic/benchmark/
working-directory: ./benchmark/
run: poetry publish -u __token__ -p ${{ secrets.PYPI_API_TOKEN }}

View File

@@ -1,4 +1,4 @@
name: Repo - Close stale issues
name: 'Close stale issues'
on:
schedule:
- cron: '30 1 * * *'

View File

@@ -1,18 +1,18 @@
name: Classic - Forge CI
name: Forge CI
on:
push:
branches: [ master, development, ci-test* ]
paths:
- '.github/workflows/classic-forge-ci.yml'
- 'classic/forge/**'
- '!classic/forge/tests/vcr_cassettes'
- '.github/workflows/forge-ci.yml'
- 'forge/**'
- '!forge/tests/vcr_cassettes'
pull_request:
branches: [ master, development, release-* ]
paths:
- '.github/workflows/classic-forge-ci.yml'
- 'classic/forge/**'
- '!classic/forge/tests/vcr_cassettes'
- '.github/workflows/forge-ci.yml'
- 'forge/**'
- '!forge/tests/vcr_cassettes'
concurrency:
group: ${{ format('forge-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
@@ -21,7 +21,7 @@ concurrency:
defaults:
run:
shell: bash
working-directory: classic/forge
working-directory: forge
jobs:
test:
@@ -110,7 +110,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ runner.os == 'macOS' && '~/Library/Caches/pypoetry' || '~/.cache/pypoetry' }}
key: poetry-${{ runner.os }}-${{ hashFiles('classic/forge/poetry.lock') }}
key: poetry-${{ runner.os }}-${{ hashFiles('forge/poetry.lock') }}
- name: Install Poetry (Unix)
if: runner.os != 'Windows'
@@ -233,4 +233,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: test-logs
path: classic/forge/logs/
path: forge/logs/

View File

@@ -1,4 +1,4 @@
name: Classic - Frontend CI/CD
name: Frontend CI/CD
on:
push:
@@ -7,11 +7,11 @@ on:
- development
- 'ci-test*' # This will match any branch that starts with "ci-test"
paths:
- 'classic/frontend/**'
- 'frontend/**'
- '.github/workflows/frontend-ci.yml'
pull_request:
paths:
- 'classic/frontend/**'
- 'frontend/**'
- '.github/workflows/frontend-ci.yml'
jobs:
@@ -34,7 +34,7 @@ jobs:
- name: Build Flutter to Web
run: |
cd classic/frontend
cd frontend
flutter build web --base-href /app/
# - name: Commit and Push to ${{ env.BUILD_BRANCH }}
@@ -42,7 +42,7 @@ jobs:
# run: |
# git config --local user.email "action@github.com"
# git config --local user.name "GitHub Action"
# git add classic/frontend/build/web
# git add frontend/build/web
# git checkout -B ${{ env.BUILD_BRANCH }}
# git commit -m "Update frontend build to ${GITHUB_SHA:0:7}" -a
# git push -f origin ${{ env.BUILD_BRANCH }}
@@ -51,7 +51,7 @@ jobs:
if: github.event_name == 'push'
uses: peter-evans/create-pull-request@v6
with:
add-paths: classic/frontend/build/web
add-paths: frontend/build/web
base: ${{ github.ref_name }}
branch: ${{ env.BUILD_BRANCH }}
delete-branch: true

133
.github/workflows/hackathon.yml vendored Normal file
View File

@@ -0,0 +1,133 @@
name: Hackathon
on:
workflow_dispatch:
inputs:
agents:
description: "Agents to run (comma-separated)"
required: false
default: "autogpt" # Default agents if none are specified
jobs:
matrix-setup:
runs-on: ubuntu-latest
# Service containers to run with `matrix-setup`
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: postgres
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
env-name: ${{ steps.set-matrix.outputs.env-name }}
steps:
- id: set-matrix
run: |
if [ "${{ github.event_name }}" == "schedule" ]; then
echo "::set-output name=env-name::production"
echo "::set-output name=matrix::[ 'irrelevant']"
elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
IFS=',' read -ra matrix_array <<< "${{ github.event.inputs.agents }}"
matrix_string="[ \"$(echo "${matrix_array[@]}" | sed 's/ /", "/g')\" ]"
echo "::set-output name=env-name::production"
echo "::set-output name=matrix::$matrix_string"
else
echo "::set-output name=env-name::testing"
echo "::set-output name=matrix::[ 'irrelevant' ]"
fi
tests:
environment:
name: "${{ needs.matrix-setup.outputs.env-name }}"
needs: matrix-setup
env:
min-python-version: "3.10"
name: "${{ matrix.agent-name }}"
runs-on: ubuntu-latest
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_PASSWORD: postgres
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps tcp port 5432 on service container to the host
- 5432:5432
timeout-minutes: 50
strategy:
fail-fast: false
matrix:
agent-name: ${{fromJson(needs.matrix-setup.outputs.matrix)}}
steps:
- name: Print Environment Name
run: |
echo "Matrix Setup Environment Name: ${{ needs.matrix-setup.outputs.env-name }}"
- name: Check Docker Container
id: check
run: docker ps
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
- name: Set up Python ${{ env.min-python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.min-python-version }}
- id: get_date
name: Get date
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python -
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: v18.15
- name: Run benchmark
run: |
link=$(jq -r '.["github_repo_url"]' arena/$AGENT_NAME.json)
branch=$(jq -r '.["branch_to_benchmark"]' arena/$AGENT_NAME.json)
git clone "$link" -b "$branch" "$AGENT_NAME"
cd $AGENT_NAME
cp ./$AGENT_NAME/.env.example ./$AGENT_NAME/.env || echo "file not found"
./run agent start $AGENT_NAME
cd ../benchmark
poetry install
poetry run agbenchmark --no-dep
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
SERP_API_KEY: ${{ secrets.SERP_API_KEY }}
SERPAPI_API_KEY: ${{ secrets.SERP_API_KEY }}
WEAVIATE_API_KEY: ${{ secrets.WEAVIATE_API_KEY }}
WEAVIATE_URL: ${{ secrets.WEAVIATE_URL }}
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
GOOGLE_CUSTOM_SEARCH_ENGINE_ID: ${{ secrets.GOOGLE_CUSTOM_SEARCH_ENGINE_ID }}
AGENT_NAME: ${{ matrix.agent-name }}

View File

@@ -1,56 +0,0 @@
name: Platform - AutoGPT Builder Infra
on:
push:
branches: [ master ]
paths:
- '.github/workflows/autogpt-infra-ci.yml'
- 'autogpt_platform/infra/**'
pull_request:
paths:
- '.github/workflows/autogpt-infra-ci.yml'
- 'autogpt_platform/infra/**'
defaults:
run:
shell: bash
working-directory: autogpt_platform/infra
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: TFLint
uses: pauloconnor/tflint-action@v0.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tflint_path: terraform/
tflint_recurse: true
tflint_changed_only: false
- name: Set up Helm
uses: azure/setup-helm@v4.2.0
with:
version: v3.14.4
- name: Set up chart-testing
uses: helm/chart-testing-action@v2.6.0
- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }})
if [[ -n "$changed" ]]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Run chart-testing (lint)
if: steps.list-changed.outputs.changed == 'true'
run: ct lint --target-branch ${{ github.event.repository.default_branch }}

View File

@@ -1,12 +1,12 @@
name: Repo - Pull Request auto-label
name: "Pull Request auto-label"
on:
# So that PRs touching the same files as the push are updated
push:
branches: [ master, development, release-* ]
paths-ignore:
- 'classic/forge/tests/vcr_cassettes'
- 'classic/benchmark/reports/**'
- 'forge/tests/vcr_cassettes'
- 'benchmark/reports/**'
# So that the `dirtyLabel` is removed if conflicts are resolve
# We recommend `pull_request_target` so that github secrets are available.
# In `pull_request` we wouldn't be able to change labels of fork PRs

View File

@@ -1,24 +1,24 @@
name: Classic - Python checks
name: Python checks
on:
push:
branches: [ master, development, ci-test* ]
paths:
- '.github/workflows/lint-ci.yml'
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- 'classic/benchmark/**'
- 'autogpt/**'
- 'forge/**'
- 'benchmark/**'
- '**.py'
- '!classic/forge/tests/vcr_cassettes'
- '!forge/tests/vcr_cassettes'
pull_request:
branches: [ master, development, release-* ]
paths:
- '.github/workflows/lint-ci.yml'
- 'classic/original_autogpt/**'
- 'classic/forge/**'
- 'classic/benchmark/**'
- 'autogpt/**'
- 'forge/**'
- 'benchmark/**'
- '**.py'
- '!classic/forge/tests/vcr_cassettes'
- '!forge/tests/vcr_cassettes'
concurrency:
group: ${{ format('lint-ci-{0}', github.head_ref && format('{0}-{1}', github.event_name, github.event.pull_request.number) || github.sha) }}
@@ -40,18 +40,18 @@ jobs:
uses: dorny/paths-filter@v3
with:
filters: |
original_autogpt:
- classic/original_autogpt/autogpt/**
- classic/original_autogpt/tests/**
- classic/original_autogpt/poetry.lock
autogpt:
- autogpt/autogpt/**
- autogpt/tests/**
- autogpt/poetry.lock
forge:
- classic/forge/forge/**
- classic/forge/tests/**
- classic/forge/poetry.lock
- forge/forge/**
- forge/tests/**
- forge/poetry.lock
benchmark:
- classic/benchmark/agbenchmark/**
- classic/benchmark/tests/**
- classic/benchmark/poetry.lock
- benchmark/agbenchmark/**
- benchmark/tests/**
- benchmark/poetry.lock
outputs:
changed-parts: ${{ steps.changes-in.outputs.changes }}
@@ -89,23 +89,23 @@ jobs:
# Install dependencies
- name: Install Python dependencies
run: poetry -C classic/${{ matrix.sub-package }} install
run: poetry -C ${{ matrix.sub-package }} install
# Lint
- name: Lint (isort)
run: poetry run isort --check .
working-directory: classic/${{ matrix.sub-package }}
working-directory: ${{ matrix.sub-package }}
- name: Lint (Black)
if: success() || failure()
run: poetry run black --check .
working-directory: classic/${{ matrix.sub-package }}
working-directory: ${{ matrix.sub-package }}
- name: Lint (Flake8)
if: success() || failure()
run: poetry run flake8 .
working-directory: classic/${{ matrix.sub-package }}
working-directory: ${{ matrix.sub-package }}
types:
needs: get-changed-parts
@@ -141,11 +141,11 @@ jobs:
# Install dependencies
- name: Install Python dependencies
run: poetry -C classic/${{ matrix.sub-package }} install
run: poetry -C ${{ matrix.sub-package }} install
# Typecheck
- name: Typecheck
if: success() || failure()
run: poetry run pyright
working-directory: classic/${{ matrix.sub-package }}
working-directory: ${{ matrix.sub-package }}

View File

@@ -1,4 +1,4 @@
name: Repo - Github Stats
name: github-repo-stats
on:
schedule:

View File

@@ -1,31 +0,0 @@
name: Repo - PR Status Checker
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
status-check:
name: Check PR Status
runs-on: ubuntu-latest
steps:
# - name: Wait some time for all actions to start
# run: sleep 30
- uses: actions/checkout@v4
# with:
# fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: Check PR Status
run: |
echo "Current directory before running Python script:"
pwd
echo "Attempting to run Python script:"
python .github/workflows/scripts/check_actions_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,109 +1,55 @@
import json
import os
import requests
import sys
import time
from typing import Dict, List, Tuple
# GitHub API endpoint
api_url = os.environ["GITHUB_API_URL"]
repo = os.environ["GITHUB_REPOSITORY"]
sha = os.environ["GITHUB_SHA"]
def get_environment_variables() -> Tuple[str, str, str, str, str]:
"""Retrieve and return necessary environment variables."""
try:
with open(os.environ["GITHUB_EVENT_PATH"]) as f:
event = json.load(f)
# GitHub token for authentication
github_token = os.environ["GITHUB_TOKEN"]
sha = event["pull_request"]["head"]["sha"]
# API endpoint for check runs for the specific SHA
endpoint = f"{api_url}/repos/{repo}/commits/{sha}/check-runs"
return (
os.environ["GITHUB_API_URL"],
os.environ["GITHUB_REPOSITORY"],
sha,
os.environ["GITHUB_TOKEN"],
os.environ["GITHUB_RUN_ID"],
)
except KeyError as e:
print(f"Error: Missing required environment variable or event data: {e}")
sys.exit(1)
# Set up headers for authentication
headers = {
"Authorization": f"token {github_token}",
"Accept": "application/vnd.github.v3+json"
}
# Make the API request
response = requests.get(endpoint, headers=headers)
def make_api_request(url: str, headers: Dict[str, str]) -> Dict:
"""Make an API request and return the JSON response."""
try:
print("Making API request to:", url)
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"Error: API request failed. {e}")
sys.exit(1)
if response.status_code != 200:
print(f"Error: Unable to fetch check runs data. Status code: {response.status_code}")
sys.exit(1)
check_runs = response.json()["check_runs"]
def process_check_runs(check_runs: List[Dict]) -> Tuple[bool, bool]:
"""Process check runs and return their status."""
runs_in_progress = False
all_others_passed = True
# Flag to track if all other check runs have passed
all_others_passed = True
for run in check_runs:
if str(run["name"]) != "Check PR Status":
status = run["status"]
conclusion = run["conclusion"]
# Current run id
current_run_id = os.environ["GITHUB_RUN_ID"]
if status == "completed":
if conclusion not in ["success", "skipped", "neutral"]:
all_others_passed = False
print(
f"Check run {run['name']} (ID: {run['id']}) has conclusion: {conclusion}"
)
else:
runs_in_progress = True
print(f"Check run {run['name']} (ID: {run['id']}) is still {status}.")
for run in check_runs:
if str(run["id"]) != current_run_id:
status = run["status"]
conclusion = run["conclusion"]
if status == "completed":
if conclusion not in ["success", "skipped", "neutral"]:
all_others_passed = False
print(f"Check run {run['name']} (ID: {run['id']}) has conclusion: {conclusion}")
else:
print(
f"Skipping check run {run['name']} (ID: {run['id']}) as it is the current run."
)
print(f"Check run {run['name']} (ID: {run['id']}) is still {status}.")
all_others_passed = False
return runs_in_progress, all_others_passed
def main():
api_url, repo, sha, github_token, current_run_id = get_environment_variables()
endpoint = f"{api_url}/repos/{repo}/commits/{sha}/check-runs"
headers = {
"Accept": "application/vnd.github.v3+json",
}
if github_token:
headers["Authorization"] = f"token {github_token}"
print(f"Current run ID: {current_run_id}")
while True:
data = make_api_request(endpoint, headers)
check_runs = data["check_runs"]
print("Processing check runs...")
print(check_runs)
runs_in_progress, all_others_passed = process_check_runs(check_runs)
if not runs_in_progress:
break
print(
"Some check runs are still in progress. Waiting 3 minutes before checking again..."
)
time.sleep(180)
if all_others_passed:
print("All other completed check runs have passed. This check passes.")
sys.exit(0)
else:
print("Some check runs have failed or have not completed. This check fails.")
sys.exit(1)
if __name__ == "__main__":
main()
if all_others_passed:
print("All other completed check runs have passed. This check passes.")
sys.exit(0)
else:
print("Some check runs have failed or have not completed. This check fails.")
sys.exit(1)

51
.github/workflows/workflow-checker.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: PR Status Checker
on:
workflow_run:
workflows: ["*"]
types:
- completed
jobs:
status-check:
name: Check Actions Status
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: Debug Information
run: |
echo "Event name: ${{ github.event_name }}"
echo "Workflow: ${{ github.workflow }}"
echo "Action: ${{ github.action }}"
echo "Actor: ${{ github.actor }}"
echo "Repository: ${{ github.repository }}"
echo "Ref: ${{ github.ref }}"
echo "Head ref: ${{ github.head_ref }}"
echo "Base ref: ${{ github.base_ref }}"
echo "Event payload:"
cat $GITHUB_EVENT_PATH
- name: Debug File Structure
run: |
echo "Current directory:"
pwd
echo "Directory contents:"
ls -R
echo "GitHub workspace:"
echo $GITHUB_WORKSPACE
echo "GitHub workspace contents:"
ls -R $GITHUB_WORKSPACE
- name: Check Actions Status
run: |
echo "Current directory before running Python script:"
pwd
echo "Attempting to run Python script:"
python .github/scripts/check_actions_status.py
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

8
.gitignore vendored
View File

@@ -1,7 +1,7 @@
## Original ignores
.github_access_token
classic/original_autogpt/keys.py
classic/original_autogpt/*.json
autogpt/keys.py
autogpt/*.json
auto_gpt_workspace/*
*.mpeg
.env
@@ -157,7 +157,7 @@ openai/
CURRENT_BULLETIN.md
# AgBenchmark
classic/benchmark/agbenchmark/reports/
agbenchmark/reports/
# Nodejs
package-lock.json
@@ -170,4 +170,4 @@ pri*
ig*
.github_access_token
LICENSE.rtf
autogpt_platform/autogpt_server/settings.py
rnd/autogpt_server/settings.py

7
.gitmodules vendored
View File

@@ -1,6 +1,3 @@
[submodule "classic/forge/tests/vcr_cassettes"]
path = classic/forge/tests/vcr_cassettes
[submodule "forge/tests/vcr_cassettes"]
path = forge/tests/vcr_cassettes
url = https://github.com/Significant-Gravitas/Auto-GPT-test-cassettes
[submodule "autogpt_platform/supabase"]
path = autogpt_platform/supabase
url = https://github.com/supabase/supabase.git

View File

@@ -16,22 +16,22 @@ repos:
hooks:
- id: isort-autogpt
name: Lint (isort) - AutoGPT
entry: poetry -C classic/original_autogpt run isort
files: ^classic/original_autogpt/
entry: poetry -C autogpt run isort
files: ^autogpt/
types: [file, python]
language: system
- id: isort-forge
name: Lint (isort) - Forge
entry: poetry -C classic/forge run isort
files: ^classic/forge/
entry: poetry -C forge run isort
files: ^forge/
types: [file, python]
language: system
- id: isort-benchmark
name: Lint (isort) - Benchmark
entry: poetry -C classic/benchmark run isort
files: ^classic/benchmark/
entry: poetry -C benchmark run isort
files: ^benchmark/
types: [file, python]
language: system
@@ -52,20 +52,20 @@ repos:
- id: flake8
name: Lint (Flake8) - AutoGPT
alias: flake8-autogpt
files: ^classic/original_autogpt/(autogpt|scripts|tests)/
args: [--config=classic/original_autogpt/.flake8]
files: ^autogpt/(autogpt|scripts|tests)/
args: [--config=autogpt/.flake8]
- id: flake8
name: Lint (Flake8) - Forge
alias: flake8-forge
files: ^classic/forge/(forge|tests)/
args: [--config=classic/forge/.flake8]
files: ^forge/(forge|tests)/
args: [--config=forge/.flake8]
- id: flake8
name: Lint (Flake8) - Benchmark
alias: flake8-benchmark
files: ^classic/benchmark/(agbenchmark|tests)/((?!reports).)*[/.]
args: [--config=classic/benchmark/.flake8]
files: ^benchmark/(agbenchmark|tests)/((?!reports).)*[/.]
args: [--config=benchmark/.flake8]
- repo: local
# To have watertight type checking, we check *all* the files in an affected
@@ -74,10 +74,10 @@ repos:
- id: pyright
name: Typecheck - AutoGPT
alias: pyright-autogpt
entry: poetry -C classic/original_autogpt run pyright
entry: poetry -C autogpt run pyright
args: [-p, autogpt, autogpt]
# include forge source (since it's a path dependency) but exclude *_test.py files:
files: ^(classic/original_autogpt/((autogpt|scripts|tests)/|poetry\.lock$)|classic/forge/(classic/forge/.*(?<!_test)\.py|poetry\.lock)$)
files: ^(autogpt/((autogpt|scripts|tests)/|poetry\.lock$)|forge/(forge/.*(?<!_test)\.py|poetry\.lock)$)
types: [file]
language: system
pass_filenames: false
@@ -85,9 +85,9 @@ repos:
- id: pyright
name: Typecheck - Forge
alias: pyright-forge
entry: poetry -C classic/forge run pyright
entry: poetry -C forge run pyright
args: [-p, forge, forge]
files: ^classic/forge/(classic/forge/|poetry\.lock$)
files: ^forge/(forge/|poetry\.lock$)
types: [file]
language: system
pass_filenames: false
@@ -95,9 +95,9 @@ repos:
- id: pyright
name: Typecheck - Benchmark
alias: pyright-benchmark
entry: poetry -C classic/benchmark run pyright
entry: poetry -C benchmark run pyright
args: [-p, benchmark, benchmark]
files: ^classic/benchmark/(agbenchmark/|tests/|poetry\.lock$)
files: ^benchmark/(agbenchmark/|tests/|poetry\.lock$)
types: [file]
language: system
pass_filenames: false
@@ -106,22 +106,22 @@ repos:
hooks:
- id: pytest-autogpt
name: Run tests - AutoGPT (excl. slow tests)
entry: bash -c 'cd classic/original_autogpt && poetry run pytest --cov=autogpt -m "not slow" tests/unit tests/integration'
entry: bash -c 'cd autogpt && poetry run pytest --cov=autogpt -m "not slow" tests/unit tests/integration'
# include forge source (since it's a path dependency) but exclude *_test.py files:
files: ^(classic/original_autogpt/((autogpt|tests)/|poetry\.lock$)|classic/forge/(classic/forge/.*(?<!_test)\.py|poetry\.lock)$)
files: ^(autogpt/((autogpt|tests)/|poetry\.lock$)|forge/(forge/.*(?<!_test)\.py|poetry\.lock)$)
language: system
pass_filenames: false
- id: pytest-forge
name: Run tests - Forge (excl. slow tests)
entry: bash -c 'cd classic/forge && poetry run pytest --cov=forge -m "not slow"'
files: ^classic/forge/(classic/forge/|tests/|poetry\.lock$)
entry: bash -c 'cd forge && poetry run pytest --cov=forge -m "not slow"'
files: ^forge/(forge/|tests/|poetry\.lock$)
language: system
pass_filenames: false
- id: pytest-benchmark
name: Run tests - Benchmark
entry: bash -c 'cd classic/benchmark && poetry run pytest --cov=benchmark'
files: ^classic/benchmark/(agbenchmark/|tests/|poetry\.lock$)
entry: bash -c 'cd benchmark && poetry run pytest --cov=benchmark'
files: ^benchmark/(agbenchmark/|tests/|poetry\.lock$)
language: system
pass_filenames: false

View File

@@ -1,53 +1,39 @@
{
"folders": [
{
"name": "autogpt_server",
"path": "../autogpt_platform/autogpt_server"
"name": "autogpt",
"path": "../autogpt"
},
{
"name": "autogpt_builder",
"path": "../autogpt_platform/autogpt_builder"
},
{
"name": "market",
"path": "../autogpt_platform/market"
},
{
"name": "lib",
"path": "../autogpt_platform/autogpt_libs"
},
{
"name": "infra",
"path": "../autogpt_platform/infra"
"name": "benchmark",
"path": "../benchmark"
},
{
"name": "docs",
"path": "../docs"
},
{
"name": "forge",
"path": "../forge"
},
{
"name": "frontend",
"path": "../frontend"
},
{
"name": "autogpt_server",
"path": "../rnd/autogpt_server"
},
{
"name": "autogpt_builder",
"path": "../rnd/autogpt_builder"
},
{
"name": "[root]",
"path": ".."
},
{
"name": "classic - autogpt",
"path": "../classic/original_autogpt"
},
{
"name": "classic - benchmark",
"path": "../classic/benchmark"
},
{
"name": "classic - forge",
"path": "../classic/forge"
},
{
"name": "classic - frontend",
"path": "../classic/frontend"
},
}
],
"settings": {
"python.analysis.typeCheckingMode": "basic"
},
"settings": {},
"extensions": {
"recommendations": [
"charliermarsh.ruff",

View File

@@ -29,7 +29,7 @@ ENV PATH="$POETRY_HOME/bin:$PATH"
RUN poetry config installer.max-workers 10
WORKDIR /app/autogpt
COPY original_autogpt/pyproject.toml original_autogpt/poetry.lock ./
COPY autogpt/pyproject.toml autogpt/poetry.lock ./
# Include forge so it can be used as a path dependency
COPY forge/ ../forge
@@ -42,17 +42,19 @@ ENTRYPOINT ["poetry", "run", "autogpt"]
CMD []
# dev build -> include everything
FROM autogpt-base AS autogpt-dev
FROM autogpt-base as autogpt-dev
RUN poetry install --no-cache --no-root \
&& rm -rf $(poetry env info --path)/src
ONBUILD COPY original_autogpt/ ./
ONBUILD COPY autogpt/ ./
# release build -> include bare minimum
FROM autogpt-base AS autogpt-release
FROM autogpt-base as autogpt-release
RUN poetry install --no-cache --no-root --without dev \
&& rm -rf $(poetry env info --path)/src
ONBUILD COPY original_autogpt/ ./autogpt
ONBUILD COPY original_autogpt/README.md ./README.md
ONBUILD COPY autogpt/autogpt/ ./autogpt
ONBUILD COPY autogpt/scripts/ ./scripts
ONBUILD COPY autogpt/plugins/ ./plugins
ONBUILD COPY autogpt/README.md ./README.md
ONBUILD RUN mkdir ./data
FROM autogpt-${BUILD_TYPE} AS autogpt

View File

@@ -55,16 +55,15 @@ Be part of the revolution! **AutoGPT** is here to stay, at the forefront of AI i
## 🤖 AutoGPT Classic
> Below is information about the classic version of AutoGPT.
**🛠️ [Build your own Agent - Quickstart](classic/FORGE-QUICKSTART.md)**
**🛠️ [Build your own Agent - Quickstart](FORGE-QUICKSTART.md)**
### 🏗️ Forge
**Forge your own agent!** &ndash; Forge is a ready-to-go toolkit to build your own agent application. It handles most of the boilerplate code, letting you channel all your creativity into the things that set *your* agent apart. All tutorials are located [here](https://medium.com/@aiedge/autogpt-forge-e3de53cc58ec). Components from [`forge`](/classic/forge/) can also be used individually to speed up development and reduce boilerplate in your agent project.
**Forge your own agent!** &ndash; Forge is a ready-to-go template for your agent application. All the boilerplate code is already handled, letting you channel all your creativity into the things that set *your* agent apart. All tutorials are located [here](https://medium.com/@aiedge/autogpt-forge-e3de53cc58ec). Components from the [`forge.sdk`](/forge/forge/sdk) can also be used individually to speed up development and reduce boilerplate in your agent project.
🚀 [**Getting Started with Forge**](https://github.com/Significant-Gravitas/AutoGPT/blob/master/classic/forge/tutorials/001_getting_started.md) &ndash;
🚀 [**Getting Started with Forge**](https://github.com/Significant-Gravitas/AutoGPT/blob/master/forge/tutorials/001_getting_started.md) &ndash;
This guide will walk you through the process of creating your own agent and using the benchmark and user interface.
📘 [Learn More](https://github.com/Significant-Gravitas/AutoGPT/tree/master/classic/forge) about Forge
📘 [Learn More](https://github.com/Significant-Gravitas/AutoGPT/tree/master/forge) about Forge
### 🎯 Benchmark
@@ -84,7 +83,7 @@ This guide will walk you through the process of creating your own agent and usin
The frontend works out-of-the-box with all agents in the repo. Just use the [CLI] to run your agent of choice!
📘 [Learn More](https://github.com/Significant-Gravitas/AutoGPT/tree/master/classic/frontend) about the Frontend
📘 [Learn More](https://github.com/Significant-Gravitas/AutoGPT/tree/master/frontend) about the Frontend
### ⌨️ CLI

View File

@@ -1,2 +1,2 @@
[run]
[run]
relative_files = true

View File

@@ -105,7 +105,6 @@
## HUGGINGFACE_API_TOKEN - HuggingFace API token (Default: None)
# HUGGINGFACE_API_TOKEN=
### Stable Diffusion (IMAGE_PROVIDER=sdwebui)
## SD_WEBUI_AUTH - Stable Diffusion Web UI username:password pair (Default: None)

View File

@@ -1,6 +1,6 @@
## Original ignores
classic/original_autogpt/keys.py
classic/original_autogpt/*.json
autogpt/keys.py
autogpt/*.json
*.mpeg
.env
azure.yaml

View File

@@ -120,9 +120,9 @@ by default on `http://localhost:8000`.
For more comprehensive instructions, see the [user guide][docs/usage].
[docs]: https://docs.agpt.co/autogpt
[docs/setup]: https://docs.agpt.co/classic/original_autogpt/setup
[docs/usage]: https://docs.agpt.co/classic/original_autogpt/usage
[docs/plugins]: https://docs.agpt.co/classic/original_autogpt/plugins
[docs/setup]: https://docs.agpt.co/autogpt/setup
[docs/usage]: https://docs.agpt.co/autogpt/usage
[docs/plugins]: https://docs.agpt.co/autogpt/plugins
## 📚 Resources
* 📔 AutoGPT [project wiki](https://github.com/Significant-Gravitas/AutoGPT/wiki)

View File

@@ -34,4 +34,4 @@ class MyAgent(Agent):
self.my_component = MyComponent()
```
For more customization, you can override the `propose_action` and `execute` or even subclass `BaseAgent` directly. This way you can have full control over the agent's components and behavior. Have a look at the [implementation of Agent](https://github.com/Significant-Gravitas/AutoGPT/tree/master/classic/original_autogpt/agents/agent.py) for more details.
For more customization, you can override the `propose_action` and `execute` or even subclass `BaseAgent` directly. This way you can have full control over the agent's components and behavior. Have a look at the [implementation of Agent](https://github.com/Significant-Gravitas/AutoGPT/tree/master/autogpt/autogpt/agents/agent.py) for more details.

View File

@@ -23,6 +23,7 @@ from forge.components.code_executor.code_executor import (
CodeExecutorComponent,
CodeExecutorConfiguration,
)
from forge.components.code_flow_executor import CodeFlowExecutionComponent
from forge.components.context.context import AgentContext, ContextComponent
from forge.components.file_manager import FileManagerComponent
from forge.components.git_operations import GitOperationsComponent
@@ -40,7 +41,6 @@ from forge.llm.providers import (
ChatModelResponse,
MultiProvider,
)
from forge.llm.providers.utils import function_specs_from_commands
from forge.models.action import (
ActionErrorResult,
ActionInterruptedByHuman,
@@ -56,6 +56,7 @@ from forge.utils.exceptions import (
)
from pydantic import Field
from .prompt_strategies.code_flow import CodeFlowAgentPromptStrategy
from .prompt_strategies.one_shot import (
OneShotAgentActionProposal,
OneShotAgentPromptStrategy,
@@ -96,11 +97,14 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]):
llm_provider: MultiProvider,
file_storage: FileStorage,
app_config: AppConfig,
prompt_strategy_class: type[
OneShotAgentPromptStrategy | CodeFlowAgentPromptStrategy
] = CodeFlowAgentPromptStrategy,
):
super().__init__(settings)
self.llm_provider = llm_provider
prompt_config = OneShotAgentPromptStrategy.default_configuration.model_copy(
prompt_config = prompt_strategy_class.default_configuration.model_copy(
deep=True
)
prompt_config.use_functions_api = (
@@ -108,7 +112,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]):
# Anthropic currently doesn't support tools + prefilling :(
and self.llm.provider_name != "anthropic"
)
self.prompt_strategy = OneShotAgentPromptStrategy(prompt_config, logger)
self.prompt_strategy = prompt_strategy_class(prompt_config, logger)
self.commands: list[Command] = []
# Components
@@ -145,6 +149,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]):
self.watchdog = WatchdogComponent(settings.config, settings.history).run_after(
ContextComponent
)
self.code_flow_executor = CodeFlowExecutionComponent(lambda: self.commands)
self.event_history = settings.history
self.app_config = app_config
@@ -185,7 +190,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]):
task=self.state.task,
ai_profile=self.state.ai_profile,
ai_directives=directives,
commands=function_specs_from_commands(self.commands),
commands=self.commands,
include_os_info=include_os_info,
)
@@ -201,9 +206,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]):
if exception:
prompt.messages.append(ChatMessage.system(f"Error: {exception}"))
response: ChatModelResponse[
OneShotAgentActionProposal
] = await self.llm_provider.create_chat_completion(
response: ChatModelResponse = await self.llm_provider.create_chat_completion(
prompt.messages,
model_name=self.llm.name,
completion_parser=self.prompt_strategy.parse_response_content,
@@ -281,7 +284,7 @@ class Agent(BaseAgent[OneShotAgentActionProposal], Configurable[AgentSettings]):
except AgentException:
raise
except Exception as e:
raise CommandExecutionError(str(e))
raise CommandExecutionError(str(e)) from e
def _get_command(self, command_name: str) -> Command:
for command in reversed(self.commands):

View File

@@ -0,0 +1,355 @@
import inspect
import re
from logging import Logger
from typing import Callable, Iterable, Sequence, get_args, get_origin
from forge.command import Command
from forge.components.code_flow_executor import CodeFlowExecutionComponent
from forge.config.ai_directives import AIDirectives
from forge.config.ai_profile import AIProfile
from forge.json.parsing import extract_dict_from_json
from forge.llm.prompting import ChatPrompt, LanguageModelClassification, PromptStrategy
from forge.llm.prompting.utils import indent
from forge.llm.providers.schema import (
AssistantChatMessage,
AssistantFunctionCall,
ChatMessage,
)
from forge.models.config import SystemConfiguration
from forge.models.json_schema import JSONSchema
from forge.utils.exceptions import InvalidAgentResponseError
from forge.utils.function.code_validation import CodeValidator
from forge.utils.function.model import FunctionDef
from pydantic import BaseModel, Field
from autogpt.agents.prompt_strategies.one_shot import (
AssistantThoughts,
OneShotAgentActionProposal,
OneShotAgentPromptConfiguration,
)
_RESPONSE_INTERFACE_NAME = "AssistantResponse"
class CodeFlowAgentActionProposal(BaseModel):
thoughts: AssistantThoughts
immediate_plan: str = Field(
...,
description="We will be running an iterative process to execute the plan, "
"Write the partial / immediate plan to execute your plan as detailed and "
"efficiently as possible without the help of the reasoning/intelligence. "
"The plan should describe the output of the immediate plan, so that the next "
"iteration can be executed by taking the output into account. "
"Try to do as much as possible without making any assumption or uninformed "
"guesses. Avoid large output at all costs!!!\n"
"Format: Objective[Objective of this iteration, explain what's the use of this "
"iteration for the next one] Plan[Plan that does not require any reasoning or "
"intelligence] Output[Output of the plan / should be small, avoid whole file "
"output]",
)
python_code: str = Field(
...,
description=(
"Write the fully-functional Python code of the immediate plan. "
"The output will be an `async def main() -> str` function of the immediate "
"plan that return the string output, the output will be passed into the "
"LLM context window so avoid returning the whole content!. "
"Use ONLY the listed available functions and built-in Python features. "
"Leverage the given magic functions to implement function calls for which "
"the arguments can't be determined yet. "
"Example:`async def main() -> str:\n"
" return await provided_function('arg1', 'arg2').split('\\n')[0]`"
),
)
FINAL_INSTRUCTION: str = (
"You have to give the answer in the from of JSON schema specified previously. "
"For the `python_code` field, you have to write Python code to execute your plan "
"as efficiently as possible. Your code will be executed directly without any "
"editing, if it doesn't work you will be held responsible. "
"Use ONLY the listed available functions and built-in Python features. "
"Do not make uninformed assumptions "
"(e.g. about the content or format of an unknown file). Leverage the given magic "
"functions to implement function calls for which the arguments can't be determined "
"yet. Reduce the amount of unnecessary data passed into these magic functions "
"where possible, because magic costs money and magically processing large amounts "
"of data is expensive. If you think are done with the task, you can simply call "
"finish(reason='your reason') to end the task, "
"a function that has one `finish` command, don't mix finish with other functions! "
"If you still need to do other functions, "
"let the next cycle execute the `finish` function. "
"Avoid hard-coding input values as input, and avoid returning large outputs. "
"The code that you have been executing in the past cycles can also be buggy, "
"so if you see undesired output, you can always try to re-plan, and re-code. "
)
class CodeFlowAgentPromptStrategy(PromptStrategy):
default_configuration: OneShotAgentPromptConfiguration = (
OneShotAgentPromptConfiguration()
)
def __init__(
self,
configuration: SystemConfiguration,
logger: Logger,
):
self.config = configuration
self.response_schema = JSONSchema.from_dict(
CodeFlowAgentActionProposal.model_json_schema()
)
self.logger = logger
self.commands: Sequence[Command] = [] # Sequence -> disallow list modification
@property
def llm_classification(self) -> LanguageModelClassification:
return LanguageModelClassification.SMART_MODEL # FIXME: dynamic switching
def build_prompt(
self,
*,
messages: list[ChatMessage],
task: str,
ai_profile: AIProfile,
ai_directives: AIDirectives,
commands: Sequence[Command],
**extras,
) -> ChatPrompt:
"""Constructs and returns a prompt with the following structure:
1. System prompt
3. `cycle_instruction`
"""
system_prompt, response_prefill = self.build_system_prompt(
ai_profile=ai_profile,
ai_directives=ai_directives,
commands=commands,
)
self.commands = commands
final_instruction_msg = ChatMessage.system(FINAL_INSTRUCTION)
return ChatPrompt(
messages=[
ChatMessage.system(system_prompt),
ChatMessage.user(f'"""{task}"""'),
*messages,
*(
[final_instruction_msg]
if not any(m.role == "assistant" for m in messages)
else []
),
],
prefill_response=response_prefill,
)
def build_system_prompt(
self,
ai_profile: AIProfile,
ai_directives: AIDirectives,
commands: Iterable[Command],
) -> tuple[str, str]:
"""
Builds the system prompt.
Returns:
str: The system prompt body
str: The desired start for the LLM's response; used to steer the output
"""
response_fmt_instruction, response_prefill = self.response_format_instruction()
system_prompt_parts = (
self._generate_intro_prompt(ai_profile)
+ [
"## Your Task\n"
"The user will specify a task for you to execute, in triple quotes,"
" in the next message. Your job is to complete the task, "
"and terminate when your task is done."
]
+ ["## Available Functions\n" + self._generate_function_headers(commands)]
+ ["## RESPONSE FORMAT\n" + response_fmt_instruction]
)
# Join non-empty parts together into paragraph format
return (
"\n\n".join(filter(None, system_prompt_parts)).strip("\n"),
response_prefill,
)
def response_format_instruction(self) -> tuple[str, str]:
response_schema = self.response_schema.model_copy(deep=True)
assert response_schema.properties
# Unindent for performance
response_format = re.sub(
r"\n\s+",
"\n",
response_schema.to_typescript_object_interface(_RESPONSE_INTERFACE_NAME),
)
response_prefill = f'{{\n "{list(response_schema.properties.keys())[0]}":'
return (
(
f"YOU MUST ALWAYS RESPOND WITH A JSON OBJECT OF THE FOLLOWING TYPE:\n"
f"{response_format}"
),
response_prefill,
)
def _generate_intro_prompt(self, ai_profile: AIProfile) -> list[str]:
"""Generates the introduction part of the prompt.
Returns:
list[str]: A list of strings forming the introduction part of the prompt.
"""
return [
f"You are {ai_profile.ai_name}, {ai_profile.ai_role.rstrip('.')}.",
# "Your decisions must always be made independently without seeking "
# "user assistance. Play to your strengths as an LLM and pursue "
# "simple strategies with no legal complications.",
]
def _generate_function_headers(self, commands: Iterable[Command]) -> str:
function_stubs: list[str] = []
annotation_types_in_context: set[type] = set()
for f in commands:
# Add source code of non-builtin types from function signatures
new_annotation_types = extract_annotation_types(f.method).difference(
annotation_types_in_context
)
new_annotation_types_src = [
f"# {a.__module__}.{a.__qualname__}\n{inspect.getsource(a)}"
for a in new_annotation_types
]
annotation_types_in_context.update(new_annotation_types)
param_descriptions = "\n".join(
f"{param.name}: {param.spec.description}"
for param in f.parameters
if param.spec.description
)
full_function_stub = (
("\n".join(new_annotation_types_src) + "\n" + f.header).strip()
+ "\n"
+ indent(
(
'"""\n'
f"{f.description}\n\n"
f"Params:\n{indent(param_descriptions)}\n"
'"""\n'
"pass"
),
)
)
function_stubs.append(full_function_stub)
return "\n\n\n".join(function_stubs)
async def parse_response_content(
self,
response: AssistantChatMessage,
) -> OneShotAgentActionProposal:
if not response.content:
raise InvalidAgentResponseError("Assistant response has no text content")
self.logger.debug(
"LLM response content:"
+ (
f"\n{response.content}"
if "\n" in response.content
else f" '{response.content}'"
)
)
assistant_reply_dict = extract_dict_from_json(response.content)
parsed_response = CodeFlowAgentActionProposal.model_validate(
assistant_reply_dict
)
if not parsed_response.python_code:
raise ValueError("python_code is empty")
available_functions = {
c.name: FunctionDef(
name=c.name,
arg_types=[(p.name, p.spec.python_type) for p in c.parameters],
arg_descs={p.name: p.spec.description for p in c.parameters},
arg_defaults={
p.name: p.spec.default or "None"
for p in c.parameters
if p.spec.default or not p.spec.required
},
return_type=c.return_type,
return_desc="Output of the function",
function_desc=c.description,
is_async=c.is_async,
)
for c in self.commands
}
available_functions.update(
{
"main": FunctionDef(
name="main",
arg_types=[],
arg_descs={},
return_type="str",
return_desc="Output of the function",
function_desc="The main function to execute the plan",
is_async=True,
)
}
)
code_validation = await CodeValidator(
function_name="main",
available_functions=available_functions,
).validate_code(parsed_response.python_code)
clean_response = response.model_copy()
clean_response.content = parsed_response.model_dump_json(indent=4)
# TODO: prevent combining finish with other functions
if _finish_call := re.search(
r"finish\((reason=)?(.*?)\)", code_validation.functionCode
):
finish_reason = _finish_call.group(2)[1:-1] # remove quotes
result = OneShotAgentActionProposal(
thoughts=parsed_response.thoughts,
use_tool=AssistantFunctionCall(
name="finish",
arguments={"reason": finish_reason},
),
raw_message=clean_response,
)
else:
result = OneShotAgentActionProposal(
thoughts=parsed_response.thoughts,
use_tool=AssistantFunctionCall(
name=CodeFlowExecutionComponent.execute_code_flow.name,
arguments={
"python_code": code_validation.functionCode,
"plan_text": parsed_response.immediate_plan,
},
),
raw_message=clean_response,
)
return result
def extract_annotation_types(func: Callable) -> set[type]:
annotation_types = set()
for annotation in inspect.get_annotations(func).values():
annotation_types.update(_get_nested_types(annotation))
return annotation_types
def _get_nested_types(annotation: type) -> Iterable[type]:
if _args := get_args(annotation):
for a in _args:
yield from _get_nested_types(a)
if not _is_builtin_type(_a := get_origin(annotation) or annotation):
yield _a
def _is_builtin_type(_type: type):
"""Check if a given type is a built-in type."""
import sys
return _type.__module__ in sys.stdlib_module_names

View File

@@ -6,6 +6,7 @@ import re
from logging import Logger
import distro
from forge.command import Command
from forge.config.ai_directives import AIDirectives
from forge.config.ai_profile import AIProfile
from forge.json.parsing import extract_dict_from_json
@@ -16,6 +17,7 @@ from forge.llm.providers.schema import (
ChatMessage,
CompletionModelFunction,
)
from forge.llm.providers.utils import function_specs_from_commands
from forge.models.action import ActionProposal
from forge.models.config import SystemConfiguration, UserConfigurable
from forge.models.json_schema import JSONSchema
@@ -27,13 +29,21 @@ _RESPONSE_INTERFACE_NAME = "AssistantResponse"
class AssistantThoughts(ModelWithSummary):
past_action_summary: str = Field(
...,
description="Summary of the last action you took, if there is none, "
"you can leave it empty",
)
observations: str = Field(
description="Relevant observations from your last action (if any)"
description="Relevant observations from your last actions (if any)"
)
text: str = Field(description="Thoughts")
reasoning: str = Field(description="Reasoning behind the thoughts")
self_criticism: str = Field(description="Constructive self-criticism")
plan: list[str] = Field(description="Short list that conveys the long-term plan")
plan: list[str] = Field(
description="Short list that conveys the long-term plan, "
"considering the progress on your task so far",
)
speak: str = Field(description="Summary of thoughts, to say to user")
def summary(self) -> str:
@@ -101,7 +111,7 @@ class OneShotAgentPromptStrategy(PromptStrategy):
@property
def llm_classification(self) -> LanguageModelClassification:
return LanguageModelClassification.FAST_MODEL # FIXME: dynamic switching
return LanguageModelClassification.SMART_MODEL # FIXME: dynamic switching
def build_prompt(
self,
@@ -110,7 +120,7 @@ class OneShotAgentPromptStrategy(PromptStrategy):
task: str,
ai_profile: AIProfile,
ai_directives: AIDirectives,
commands: list[CompletionModelFunction],
commands: list[Command],
include_os_info: bool,
**extras,
) -> ChatPrompt:
@@ -118,10 +128,11 @@ class OneShotAgentPromptStrategy(PromptStrategy):
1. System prompt
3. `cycle_instruction`
"""
functions = function_specs_from_commands(commands)
system_prompt, response_prefill = self.build_system_prompt(
ai_profile=ai_profile,
ai_directives=ai_directives,
commands=commands,
functions=functions,
include_os_info=include_os_info,
)
@@ -135,14 +146,14 @@ class OneShotAgentPromptStrategy(PromptStrategy):
final_instruction_msg,
],
prefill_response=response_prefill,
functions=commands if self.config.use_functions_api else [],
functions=functions if self.config.use_functions_api else [],
)
def build_system_prompt(
self,
ai_profile: AIProfile,
ai_directives: AIDirectives,
commands: list[CompletionModelFunction],
functions: list[CompletionModelFunction],
include_os_info: bool,
) -> tuple[str, str]:
"""
@@ -162,7 +173,7 @@ class OneShotAgentPromptStrategy(PromptStrategy):
self.config.body_template.format(
constraints=format_numbered_list(ai_directives.constraints),
resources=format_numbered_list(ai_directives.resources),
commands=self._generate_commands_list(commands),
commands=self._generate_commands_list(functions),
best_practices=format_numbered_list(ai_directives.best_practices),
)
]

View File

@@ -23,6 +23,7 @@ from forge.agent_protocol.models import (
TaskRequestBody,
TaskStepsListResponse,
)
from forge.components.code_flow_executor import CodeFlowExecutionComponent
from forge.file_storage import FileStorage
from forge.llm.providers import ModelProviderBudget, MultiProvider
from forge.models.action import ActionErrorResult, ActionSuccessResult
@@ -97,9 +98,7 @@ class AgentProtocolServer:
app.include_router(router, prefix="/ap/v1")
script_dir = os.path.dirname(os.path.realpath(__file__))
frontend_path = (
pathlib.Path(script_dir)
.joinpath("../../../classic/frontend/build/web")
.resolve()
pathlib.Path(script_dir).joinpath("../../../frontend/build/web").resolve()
)
if os.path.exists(frontend_path):
@@ -300,11 +299,16 @@ class AgentProtocolServer:
else ""
)
output += f"{assistant_response.thoughts.speak}\n\n"
output += (
f"Next Command: {next_tool_to_use}"
if next_tool_to_use.name != ASK_COMMAND
else next_tool_to_use.arguments["question"]
)
if next_tool_to_use.name == CodeFlowExecutionComponent.execute_code_flow.name:
code = next_tool_to_use.arguments["python_code"]
plan = next_tool_to_use.arguments["plan_text"]
output += f"Code for next step:\n```py\n# {plan}\n\n{code}\n```"
else:
output += (
f"Next Command: {next_tool_to_use}"
if next_tool_to_use.name != ASK_COMMAND
else next_tool_to_use.arguments["question"]
)
additional_output = {
**(

View File

@@ -148,7 +148,7 @@ async def assert_config_has_required_llm_api_keys(config: AppConfig) -> None:
)
logger.info(
"For further instructions: "
"https://docs.agpt.co/classic/original_autogpt/setup/#anthropic"
"https://docs.agpt.co/autogpt/setup/#anthropic"
)
raise ValueError("Anthropic is unavailable: can't load credentials") from e
@@ -176,15 +176,14 @@ async def assert_config_has_required_llm_api_keys(config: AppConfig) -> None:
logger.error("Set your Groq API key in .env or as an environment variable")
logger.info(
"For further instructions: "
+ "https://docs.agpt.co/classic/original_autogpt/setup/#groq"
"For further instructions: https://docs.agpt.co/autogpt/setup/#groq"
)
raise ValueError("Groq is unavailable: can't load credentials")
except AuthenticationError as e:
logger.error("The Groq API key is invalid!")
logger.info(
"For instructions to get and set a new API key: "
"https://docs.agpt.co/classic/original_autogpt/setup/#groq"
"https://docs.agpt.co/autogpt/setup/#groq"
)
raise ValueError("Groq is unavailable: invalid API key") from e
@@ -203,15 +202,14 @@ async def assert_config_has_required_llm_api_keys(config: AppConfig) -> None:
"Set your OpenAI API key in .env or as an environment variable"
)
logger.info(
"For further instructions: "
+ "https://docs.agpt.co/classic/original_autogpt/setup/#openai"
"For further instructions: https://docs.agpt.co/autogpt/setup/#openai"
)
raise ValueError("OpenAI is unavailable: can't load credentials")
except AuthenticationError as e:
logger.error("The OpenAI API key is invalid!")
logger.info(
"For instructions to get and set a new API key: "
"https://docs.agpt.co/classic/original_autogpt/setup/#openai"
"https://docs.agpt.co/autogpt/setup/#openai"
)
raise ValueError("OpenAI is unavailable: invalid API key") from e

View File

@@ -630,6 +630,9 @@ def update_user(
command_args: The arguments for the command.
assistant_reply_dict: The assistant's reply.
"""
from forge.components.code_flow_executor import CodeFlowExecutionComponent
from forge.llm.prompting.utils import indent
logger = logging.getLogger(__name__)
print_assistant_thoughts(
@@ -644,15 +647,29 @@ def update_user(
# First log new-line so user can differentiate sections better in console
print()
safe_tool_name = remove_ansi_escape(action_proposal.use_tool.name)
logger.info(
f"COMMAND = {Fore.CYAN}{safe_tool_name}{Style.RESET_ALL} "
f"ARGUMENTS = {Fore.CYAN}{action_proposal.use_tool.arguments}{Style.RESET_ALL}",
extra={
"title": "NEXT ACTION:",
"title_color": Fore.CYAN,
"preserve_color": True,
},
)
if safe_tool_name == CodeFlowExecutionComponent.execute_code_flow.name:
plan = action_proposal.use_tool.arguments["plan_text"]
code = action_proposal.use_tool.arguments["python_code"]
logger.info(
f"\n{indent(code, f'{Fore.GREEN}>>> {Fore.RESET}')}\n",
extra={
"title": "PROPOSED ACTION:",
"title_color": Fore.GREEN,
"preserve_color": True,
},
)
logger.debug(
f"{plan}\n", extra={"title": "EXPLANATION:", "title_color": Fore.YELLOW}
)
else:
logger.info(
str(action_proposal.use_tool),
extra={
"title": "PROPOSED ACTION:",
"title_color": Fore.GREEN,
"preserve_color": True,
},
)
async def get_user_feedback(
@@ -732,6 +749,12 @@ def print_assistant_thoughts(
)
if isinstance(thoughts, AssistantThoughts):
if thoughts.observations:
print_attribute(
"OBSERVATIONS",
remove_ansi_escape(thoughts.observations),
title_color=Fore.YELLOW,
)
print_attribute(
"REASONING", remove_ansi_escape(thoughts.reasoning), title_color=Fore.YELLOW
)
@@ -753,7 +776,7 @@ def print_assistant_thoughts(
line.strip(), extra={"title": "- ", "title_color": Fore.GREEN}
)
print_attribute(
"CRITICISM",
"SELF-CRITICISM",
remove_ansi_escape(thoughts.self_criticism),
title_color=Fore.YELLOW,
)
@@ -764,7 +787,7 @@ def print_assistant_thoughts(
speak(assistant_thoughts_speak)
else:
print_attribute(
"SPEAK", assistant_thoughts_speak, title_color=Fore.YELLOW
"TL;DR", assistant_thoughts_speak, title_color=Fore.YELLOW
)
else:
speak(thoughts_text)

View File

@@ -22,7 +22,7 @@ logger = logging.getLogger(__name__)
def get_bulletin_from_web():
try:
response = requests.get(
"https://raw.githubusercontent.com/Significant-Gravitas/AutoGPT/master/classic/original_autogpt/BULLETIN.md" # noqa: E501
"https://raw.githubusercontent.com/Significant-Gravitas/AutoGPT/master/autogpt/BULLETIN.md" # noqa: E501
)
if response.status_code == 200:
return response.text
@@ -45,7 +45,7 @@ def vcs_state_diverges_from_master() -> bool:
"""
Returns whether a git repo is present and contains changes that are not in `master`.
"""
paths_we_care_about = "classic/original_autogpt/classic/original_autogpt/**/*.py"
paths_we_care_about = "autogpt/autogpt/**/*.py"
try:
repo = Repo(search_parent_directories=True)

View File

@@ -14,7 +14,7 @@ services:
ports:
- "8000:8000"
volumes:
- ./:/app/classic/original_autogpt/
- ./:/app/autogpt/
- ./docker-compose.yml:/app/docker-compose.yml:ro
# - ./Dockerfile:/app/Dockerfile:ro
profiles: ["exclude-from-up"]
@@ -33,8 +33,8 @@ services:
entrypoint: ["poetry", "run"]
command: ["pytest", "-v"]
volumes:
- ./autogpt:/app/classic/original_autogpt/autogpt
- ./tests:/app/classic/original_autogpt/tests
- ./autogpt:/app/autogpt/autogpt
- ./tests:/app/autogpt/tests
depends_on:
- minio
profiles: ["exclude-from-up"]

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -348,10 +348,10 @@ tiktoken = ">=0.7.0,<1.0.0"
toml = "^0.10.2"
uvicorn = {version = ">=0.23.2,<1", extras = ["standard"]}
watchdog = "4.0.0"
webdriver-manager = "^4.0.2"
webdriver-manager = "^4.0.1"
[package.extras]
benchmark = ["agbenchmark @ file:///home/reinier/code/agpt/AutoGPT/classic/benchmark"]
benchmark = ["agbenchmark @ file:///Users/czerwinski/Projects/AutoGPT/benchmark"]
[package.source]
type = "directory"
@@ -4216,7 +4216,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"]
name = "ptyprocess"
version = "0.7.0"
description = "Run a subprocess in a pseudo terminal"
optional = true
optional = false
python-versions = "*"
files = [
{file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
@@ -5212,6 +5212,32 @@ files = [
[package.dependencies]
pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.4.4"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.4.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:29d44ef5bb6a08e235c8249294fa8d431adc1426bfda99ed493119e6f9ea1bf6"},
{file = "ruff-0.4.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c4efe62b5bbb24178c950732ddd40712b878a9b96b1d02b0ff0b08a090cbd891"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8e2f1e8fc12d07ab521a9005d68a969e167b589cbcaee354cb61e9d9de9c15"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:60ed88b636a463214905c002fa3eaab19795679ed55529f91e488db3fe8976ab"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b90fc5e170fc71c712cc4d9ab0e24ea505c6a9e4ebf346787a67e691dfb72e85"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8e7e6ebc10ef16dcdc77fd5557ee60647512b400e4a60bdc4849468f076f6eef"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9ddb2c494fb79fc208cd15ffe08f32b7682519e067413dbaf5f4b01a6087bcd"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c51c928a14f9f0a871082603e25a1588059b7e08a920f2f9fa7157b5bf08cfe9"},
{file = "ruff-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5eb0a4bfd6400b7d07c09a7725e1a98c3b838be557fee229ac0f84d9aa49c36"},
{file = "ruff-0.4.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b1867ee9bf3acc21778dcb293db504692eda5f7a11a6e6cc40890182a9f9e595"},
{file = "ruff-0.4.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1aecced1269481ef2894cc495647392a34b0bf3e28ff53ed95a385b13aa45768"},
{file = "ruff-0.4.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9da73eb616b3241a307b837f32756dc20a0b07e2bcb694fec73699c93d04a69e"},
{file = "ruff-0.4.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:958b4ea5589706a81065e2a776237de2ecc3e763342e5cc8e02a4a4d8a5e6f95"},
{file = "ruff-0.4.4-py3-none-win32.whl", hash = "sha256:cb53473849f011bca6e754f2cdf47cafc9c4f4ff4570003a0dad0b9b6890e876"},
{file = "ruff-0.4.4-py3-none-win_amd64.whl", hash = "sha256:424e5b72597482543b684c11def82669cc6b395aa8cc69acc1858b5ef3e5daae"},
{file = "ruff-0.4.4-py3-none-win_arm64.whl", hash = "sha256:39df0537b47d3b597293edbb95baf54ff5b49589eb7ff41926d8243caa995ea6"},
{file = "ruff-0.4.4.tar.gz", hash = "sha256:f87ea42d5cdebdc6a69761a9d0bc83ae9b3b30d0ad78952005ba6568d6c022af"},
]
[[package]]
name = "s3transfer"
version = "0.10.0"
@@ -6416,13 +6442,13 @@ wasabi = ">=0.9.1,<1.2.0"
[[package]]
name = "webdriver-manager"
version = "4.0.2"
version = "4.0.1"
description = "Library provides the way to automatically manage drivers for different browsers"
optional = false
python-versions = ">=3.7"
files = [
{file = "webdriver_manager-4.0.2-py2.py3-none-any.whl", hash = "sha256:75908d92ecc45ff2b9953614459c633db8f9aa1ff30181cefe8696e312908129"},
{file = "webdriver_manager-4.0.2.tar.gz", hash = "sha256:efedf428f92fd6d5c924a0d054e6d1322dd77aab790e834ee767af392b35590f"},
{file = "webdriver_manager-4.0.1-py2.py3-none-any.whl", hash = "sha256:d7970052295bb9cda2c1a24cf0b872dd2c41ababcc78f7b6b8dc37a41e979a7e"},
{file = "webdriver_manager-4.0.1.tar.gz", hash = "sha256:25ec177c6a2ce9c02fb8046f1b2732701a9418d6a977967bb065d840a3175d87"},
]
[package.dependencies]
@@ -6758,4 +6784,4 @@ benchmark = ["agbenchmark"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "b3d4efee5861b32152024dada1ec61f4241122419cb538012c00a6ed55ac8a4b"
content-hash = "c729e10fd5ac85400d2499397974d1b1831fed3b591657a2fea9e86501b96e19"

View File

@@ -30,9 +30,12 @@ gitpython = "^3.1.32"
hypercorn = "^0.14.4"
openai = "^1.7.2"
orjson = "^3.8.10"
ptyprocess = "^0.7.0"
pydantic = "^2.7.2"
pyright = "^1.1.364"
python-dotenv = "^1.0.0"
requests = "*"
ruff = "^0.4.4"
sentry-sdk = "^1.40.4"
# Benchmarking
@@ -47,7 +50,6 @@ black = "^23.12.1"
flake8 = "^7.0.0"
isort = "^5.13.1"
pre-commit = "*"
pyright = "^1.1.364"
# Type stubs
types-colorama = "*"
@@ -88,4 +90,4 @@ skip_glob = ["data"]
[tool.pyright]
pythonVersion = "3.10"
exclude = ["data/**", "**/node_modules", "**/__pycache__", "**/.*"]
ignore = ["../classic/forge/**"]
ignore = ["../forge/**"]

View File

@@ -55,7 +55,7 @@ async def generate_release_notes(repo_path: Optional[str | Path] = None):
git_log = repo.git.log(
f"{last_release_tag.name}...{new_release_ref}",
"classic/original_autogpt/",
"autogpt/",
no_merges=True,
follow=True,
)
@@ -81,7 +81,7 @@ EXAMPLE_RELEASE_NOTES = """
First some important notes w.r.t. using the application:
* `run.sh` has been renamed to `autogpt.sh`
* The project has been restructured. The AutoGPT Agent is now located in `autogpt`.
* The application no longer uses a single workspace for all tasks. Instead, every task that you run the agent on creates a new workspace folder. See the [usage guide](https://docs.agpt.co/classic/original_autogpt/usage/#workspace) for more information.
* The application no longer uses a single workspace for all tasks. Instead, every task that you run the agent on creates a new workspace folder. See the [usage guide](https://docs.agpt.co/autogpt/usage/#workspace) for more information.
## New features ✨
@@ -94,7 +94,7 @@ First some important notes w.r.t. using the application:
* **Resuming agents 🔄**
In TTY mode, the application will now save the agent's state when quitting, and allows resuming where you left off at a later time!
* **GCS and S3 workspace backends 📦**
To further support running the application as part of a larger system, Google Cloud Storage and S3 workspace backends were added. Configuration options for this can be found in [`.env.template`](/classic/original_autogpt/.env.template).
To further support running the application as part of a larger system, Google Cloud Storage and S3 workspace backends were added. Configuration options for this can be found in [`.env.template`](/autogpt/.env.template).
* **Documentation Rewrite 📖**
The [documentation](https://docs.agpt.co) has been restructured and mostly rewritten to clarify and simplify the instructions, and also to accommodate the other subprojects that are now in the repo.
* **New Project CLI 🔧**

View File

@@ -80,7 +80,7 @@ def main(
):
return
# Go to classic/original_autogpt/scripts/llamafile/
# Go to autogpt/scripts/llamafile/
os.chdir(Path(__file__).resolve().parent)
on_windows = platform.system() == "Windows"

View File

@@ -59,10 +59,7 @@ txt_to_rtf("../LICENSE", license_file)
setup(
executables=[
Executable(
"classic/original_autogpt/__main__.py",
target_name="autogpt",
base="console",
icon=icon,
"autogpt/__main__.py", target_name="autogpt", base="console", icon=icon
),
],
options={

Some files were not shown because too many files have changed in this diff Show More