loopengt 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- loopengt-0.1.0/.github/workflows/ci.yml +94 -0
- loopengt-0.1.0/.github/workflows/workflow.yml +55 -0
- loopengt-0.1.0/.gitignore +165 -0
- loopengt-0.1.0/.loopengt/config.toml +20 -0
- loopengt-0.1.0/.loopengt/prompts/LOOPENGT.md +12 -0
- loopengt-0.1.0/ACCEPTANCE_TESTS.md +36 -0
- loopengt-0.1.0/ARCHITECTURE.md +91 -0
- loopengt-0.1.0/LICENSE +674 -0
- loopengt-0.1.0/LOOPENGT_ENTERPRISE_ROADMAP.md +74 -0
- loopengt-0.1.0/LOOPENGT_FULL_ANTIGRAVITY_PROMPT.md +525 -0
- loopengt-0.1.0/PKG-INFO +275 -0
- loopengt-0.1.0/README.md +214 -0
- loopengt-0.1.0/SPEC_DEV.md +74 -0
- loopengt-0.1.0/TASK_PLAN.md +57 -0
- loopengt-0.1.0/docs/index.md +25 -0
- loopengt-0.1.0/docs/mcp_guide.md +113 -0
- loopengt-0.1.0/docs/plugin_dev.md +120 -0
- loopengt-0.1.0/examples/basic_loop.py +27 -0
- loopengt-0.1.0/examples/multi_agent_loop.py +44 -0
- loopengt-0.1.0/loopengt.md +39 -0
- loopengt-0.1.0/plugins/loopeng-plugin-antigravity/README.md +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-antigravity/loopeng_plugin_antigravity/__init__.py +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-antigravity/loopeng_plugin_antigravity/adapter.py +20 -0
- loopengt-0.1.0/plugins/loopeng-plugin-antigravity/pyproject.toml +16 -0
- loopengt-0.1.0/plugins/loopeng-plugin-claude-code/README.md +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-claude-code/loopeng_plugin_claude_code/__init__.py +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-claude-code/loopeng_plugin_claude_code/adapter.py +20 -0
- loopengt-0.1.0/plugins/loopeng-plugin-claude-code/pyproject.toml +16 -0
- loopengt-0.1.0/plugins/loopeng-plugin-codex/README.md +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-codex/loopeng_plugin_codex/__init__.py +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-codex/loopeng_plugin_codex/adapter.py +20 -0
- loopengt-0.1.0/plugins/loopeng-plugin-codex/pyproject.toml +16 -0
- loopengt-0.1.0/plugins/loopeng-plugin-cursor/README.md +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-cursor/loopeng_plugin_cursor/__init__.py +3 -0
- loopengt-0.1.0/plugins/loopeng-plugin-cursor/loopeng_plugin_cursor/adapter.py +20 -0
- loopengt-0.1.0/plugins/loopeng-plugin-cursor/pyproject.toml +16 -0
- loopengt-0.1.0/pyproject.toml +123 -0
- loopengt-0.1.0/src/loopengt/__init__.py +31 -0
- loopengt-0.1.0/src/loopengt/adapters/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/adapters/antigravity/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/adapters/antigravity/adapter.py +55 -0
- loopengt-0.1.0/src/loopengt/adapters/antigravity/commands.py +21 -0
- loopengt-0.1.0/src/loopengt/adapters/base.py +51 -0
- loopengt-0.1.0/src/loopengt/adapters/claude_code/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/adapters/claude_code/adapter.py +55 -0
- loopengt-0.1.0/src/loopengt/adapters/claude_code/commands.py +16 -0
- loopengt-0.1.0/src/loopengt/adapters/codex/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/adapters/codex/adapter.py +52 -0
- loopengt-0.1.0/src/loopengt/adapters/codex/commands.py +16 -0
- loopengt-0.1.0/src/loopengt/adapters/cursor/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/adapters/cursor/adapter.py +56 -0
- loopengt-0.1.0/src/loopengt/adapters/cursor/commands.py +29 -0
- loopengt-0.1.0/src/loopengt/adapters/generic/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/adapters/generic/terminal.py +82 -0
- loopengt-0.1.0/src/loopengt/cli/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/cli/commands/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/cli/commands/design.py +171 -0
- loopengt-0.1.0/src/loopengt/cli/commands/doctor.py +110 -0
- loopengt-0.1.0/src/loopengt/cli/commands/eval.py +105 -0
- loopengt-0.1.0/src/loopengt/cli/commands/init.py +131 -0
- loopengt-0.1.0/src/loopengt/cli/commands/mcp_serve.py +57 -0
- loopengt-0.1.0/src/loopengt/cli/commands/run.py +99 -0
- loopengt-0.1.0/src/loopengt/cli/commands/template.py +145 -0
- loopengt-0.1.0/src/loopengt/cli/commands/trace.py +114 -0
- loopengt-0.1.0/src/loopengt/cli/formatters.py +125 -0
- loopengt-0.1.0/src/loopengt/cli/main.py +66 -0
- loopengt-0.1.0/src/loopengt/core/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/core/evals/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/core/evals/judges.py +216 -0
- loopengt-0.1.0/src/loopengt/core/evals/metrics.py +119 -0
- loopengt-0.1.0/src/loopengt/core/evals/regression.py +157 -0
- loopengt-0.1.0/src/loopengt/core/memory/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/core/memory/retrieval.py +124 -0
- loopengt-0.1.0/src/loopengt/core/memory/store.py +184 -0
- loopengt-0.1.0/src/loopengt/core/memory/summarizer.py +97 -0
- loopengt-0.1.0/src/loopengt/core/models/__init__.py +43 -0
- loopengt-0.1.0/src/loopengt/core/models/agent.py +126 -0
- loopengt-0.1.0/src/loopengt/core/models/loop_spec.py +251 -0
- loopengt-0.1.0/src/loopengt/core/models/policy.py +131 -0
- loopengt-0.1.0/src/loopengt/core/models/state.py +271 -0
- loopengt-0.1.0/src/loopengt/core/models/tool.py +105 -0
- loopengt-0.1.0/src/loopengt/core/runtime/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/core/runtime/checkpoint.py +152 -0
- loopengt-0.1.0/src/loopengt/core/runtime/executor.py +463 -0
- loopengt-0.1.0/src/loopengt/core/runtime/handoff.py +139 -0
- loopengt-0.1.0/src/loopengt/core/runtime/scheduler.py +168 -0
- loopengt-0.1.0/src/loopengt/core/tracing/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/core/tracing/events.py +95 -0
- loopengt-0.1.0/src/loopengt/core/tracing/exporters.py +158 -0
- loopengt-0.1.0/src/loopengt/core/tracing/store.py +202 -0
- loopengt-0.1.0/src/loopengt/mcp/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/mcp/client/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/mcp/client/manager.py +118 -0
- loopengt-0.1.0/src/loopengt/mcp/client/tools.py +107 -0
- loopengt-0.1.0/src/loopengt/mcp/server/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/mcp/server/prompts.py +82 -0
- loopengt-0.1.0/src/loopengt/mcp/server/resources.py +75 -0
- loopengt-0.1.0/src/loopengt/mcp/server/server.py +50 -0
- loopengt-0.1.0/src/loopengt/mcp/server/tools.py +214 -0
- loopengt-0.1.0/src/loopengt/mcp/shared/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/mcp/shared/schemas.py +91 -0
- loopengt-0.1.0/src/loopengt/plugins/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/plugins/base.py +90 -0
- loopengt-0.1.0/src/loopengt/plugins/loader.py +130 -0
- loopengt-0.1.0/src/loopengt/plugins/manifest.py +70 -0
- loopengt-0.1.0/src/loopengt/plugins/registry.py +146 -0
- loopengt-0.1.0/src/loopengt/prompts/LOOPENGT.md +60 -0
- loopengt-0.1.0/src/loopengt/prompts/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/storage/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/storage/jsonl.py +84 -0
- loopengt-0.1.0/src/loopengt/storage/sqlite.py +102 -0
- loopengt-0.1.0/src/loopengt/templates/__init__.py +1 -0
- loopengt-0.1.0/src/loopengt/templates/builtins/handoff_loop/LOOPENGS.md +10 -0
- loopengt-0.1.0/src/loopengt/templates/builtins/planner_executor/LOOPENGS.md +29 -0
- loopengt-0.1.0/src/loopengt/templates/builtins/research_architect/LOOPENGS.md +17 -0
- loopengt-0.1.0/src/loopengt/templates/builtins/reviewer_retry/LOOPENGS.md +29 -0
- loopengt-0.1.0/src/loopengt/templates/builtins/supervisor_workers/LOOPENGS.md +29 -0
- loopengt-0.1.0/src/loopengt/templates/loader.py +38 -0
- loopengt-0.1.0/src/loopengt/templates/registry.py +85 -0
- loopengt-0.1.0/tests/__init__.py +1 -0
- loopengt-0.1.0/tests/unit/test_cli.py +88 -0
- loopengt-0.1.0/tests/unit/test_executor.py +119 -0
- loopengt-0.1.0/tests/unit/test_models.py +235 -0
- loopengt-0.1.0/tests/unit/test_plugins.py +61 -0
- loopengt-0.1.0/uv.lock +2130 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
name: Lint & Type Check
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v4
|
|
22
|
+
|
|
23
|
+
- name: Set up Python
|
|
24
|
+
uses: actions/setup-python@v5
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.12"
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: uv pip install --system -e ".[dev]"
|
|
30
|
+
|
|
31
|
+
- name: Ruff check
|
|
32
|
+
run: ruff check src/ tests/
|
|
33
|
+
|
|
34
|
+
- name: Ruff format check
|
|
35
|
+
run: ruff format --check src/ tests/
|
|
36
|
+
|
|
37
|
+
- name: Mypy
|
|
38
|
+
run: mypy src/loopengt/ --ignore-missing-imports
|
|
39
|
+
|
|
40
|
+
test:
|
|
41
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
strategy:
|
|
44
|
+
matrix:
|
|
45
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@v4
|
|
48
|
+
|
|
49
|
+
- name: Install uv
|
|
50
|
+
uses: astral-sh/setup-uv@v4
|
|
51
|
+
|
|
52
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
53
|
+
uses: actions/setup-python@v5
|
|
54
|
+
with:
|
|
55
|
+
python-version: ${{ matrix.python-version }}
|
|
56
|
+
|
|
57
|
+
- name: Install dependencies
|
|
58
|
+
run: uv pip install --system -e ".[dev]"
|
|
59
|
+
|
|
60
|
+
- name: Run tests
|
|
61
|
+
run: pytest tests/ -v --tb=short --cov=loopengt --cov-report=xml
|
|
62
|
+
|
|
63
|
+
- name: Upload coverage
|
|
64
|
+
if: matrix.python-version == '3.12'
|
|
65
|
+
uses: codecov/codecov-action@v4
|
|
66
|
+
with:
|
|
67
|
+
file: coverage.xml
|
|
68
|
+
|
|
69
|
+
build:
|
|
70
|
+
name: Build Package
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
needs: [lint, test]
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v4
|
|
75
|
+
|
|
76
|
+
- name: Install uv
|
|
77
|
+
uses: astral-sh/setup-uv@v4
|
|
78
|
+
|
|
79
|
+
- name: Build
|
|
80
|
+
run: |
|
|
81
|
+
uv build
|
|
82
|
+
for dir in plugins/*/; do
|
|
83
|
+
if [ -f "$dir/pyproject.toml" ]; then
|
|
84
|
+
echo "Building plugin in $dir..."
|
|
85
|
+
uv build --directory "$dir" --out-dir dist/
|
|
86
|
+
fi
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
- name: Upload artifact
|
|
91
|
+
uses: actions/upload-artifact@v4
|
|
92
|
+
with:
|
|
93
|
+
name: dist
|
|
94
|
+
path: dist/
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
name: Build
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v4
|
|
20
|
+
|
|
21
|
+
- name: Build package
|
|
22
|
+
run: |
|
|
23
|
+
uv build
|
|
24
|
+
for dir in plugins/*/; do
|
|
25
|
+
if [ -f "$dir/pyproject.toml" ]; then
|
|
26
|
+
echo "Building plugin in $dir..."
|
|
27
|
+
uv build --directory "$dir" --out-dir dist/
|
|
28
|
+
fi
|
|
29
|
+
done
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
- name: Upload artifact
|
|
33
|
+
uses: actions/upload-artifact@v4
|
|
34
|
+
with:
|
|
35
|
+
name: dist
|
|
36
|
+
path: dist/
|
|
37
|
+
|
|
38
|
+
publish:
|
|
39
|
+
name: Publish to PyPI
|
|
40
|
+
needs: build
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
environment: pypi
|
|
43
|
+
permissions:
|
|
44
|
+
id-token: write
|
|
45
|
+
steps:
|
|
46
|
+
- name: Download artifact
|
|
47
|
+
uses: actions/download-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: dist
|
|
50
|
+
path: dist/
|
|
51
|
+
|
|
52
|
+
- name: Publish to PyPI
|
|
53
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
54
|
+
with:
|
|
55
|
+
skip-existing: true
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.pyc
|
|
4
|
+
*.pyo
|
|
5
|
+
*.pyd
|
|
6
|
+
|
|
7
|
+
# C extensions
|
|
8
|
+
*.so
|
|
9
|
+
|
|
10
|
+
# Distribution / packaging
|
|
11
|
+
.Python
|
|
12
|
+
build/
|
|
13
|
+
develop-eggs/
|
|
14
|
+
dist/
|
|
15
|
+
downloads/
|
|
16
|
+
eggs/
|
|
17
|
+
.eggs/
|
|
18
|
+
lib/
|
|
19
|
+
lib64/
|
|
20
|
+
parts/
|
|
21
|
+
sdist/
|
|
22
|
+
var/
|
|
23
|
+
wheels/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
/*.manifest
|
|
34
|
+
/*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
cover/
|
|
54
|
+
|
|
55
|
+
# Translations
|
|
56
|
+
*.mo
|
|
57
|
+
*.pot
|
|
58
|
+
|
|
59
|
+
# Django stuff:
|
|
60
|
+
*.log
|
|
61
|
+
local_settings.py
|
|
62
|
+
db.sqlite3
|
|
63
|
+
db.sqlite3-journal
|
|
64
|
+
|
|
65
|
+
# Flask stuff:
|
|
66
|
+
instance/
|
|
67
|
+
.webassets-cache
|
|
68
|
+
|
|
69
|
+
# Scrapy stuff:
|
|
70
|
+
.scrapy
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# PyBuilder
|
|
76
|
+
.pybuilder/
|
|
77
|
+
target/
|
|
78
|
+
|
|
79
|
+
# Jupyter Notebook
|
|
80
|
+
.ipynb_checkpoints
|
|
81
|
+
|
|
82
|
+
# IPython
|
|
83
|
+
profile_default/
|
|
84
|
+
ipython_config.py
|
|
85
|
+
|
|
86
|
+
# pyenv
|
|
87
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
88
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
89
|
+
# .python-version
|
|
90
|
+
|
|
91
|
+
# pipenv
|
|
92
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
93
|
+
# However, in case of collaboration, if delegates have different python versions passed
|
|
94
|
+
# to --python flag, pipenv will throw an warning and refuse to install dependencies.
|
|
95
|
+
# In that case, uncomment the next line to ignore Pipfile.lock.
|
|
96
|
+
#Pipfile.lock
|
|
97
|
+
|
|
98
|
+
# poetry
|
|
99
|
+
# Similar to Pipenv, Pyproject.toml should be version controlled.
|
|
100
|
+
# poetry.lock and poetry.toml may be ignored or committed.
|
|
101
|
+
#poetry.lock
|
|
102
|
+
#poetry.toml
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Poetry and Pipenv, pyproject.toml should be version controlled.
|
|
106
|
+
# pdm.lock may be ignored or committed.
|
|
107
|
+
#pdm.lock
|
|
108
|
+
.pdm-plugins/
|
|
109
|
+
.pdm-python
|
|
110
|
+
|
|
111
|
+
# PEP 582; used by e.g. github.com/lincolnloop/layman and github.com/pdm-project/pdm
|
|
112
|
+
__pypackages__/
|
|
113
|
+
|
|
114
|
+
# Celery stuff
|
|
115
|
+
celerybeat-schedule
|
|
116
|
+
celerybeat.pid
|
|
117
|
+
|
|
118
|
+
# SageMath parsed files
|
|
119
|
+
*.sage.py
|
|
120
|
+
|
|
121
|
+
# Environments
|
|
122
|
+
.env
|
|
123
|
+
.venv
|
|
124
|
+
env/
|
|
125
|
+
venv/
|
|
126
|
+
ENV/
|
|
127
|
+
env.bak/
|
|
128
|
+
venv.bak/
|
|
129
|
+
|
|
130
|
+
# Spyder project settings
|
|
131
|
+
.spyderproject
|
|
132
|
+
.spyproject
|
|
133
|
+
|
|
134
|
+
# Rope project settings
|
|
135
|
+
.ropeproject
|
|
136
|
+
|
|
137
|
+
# mkdocs documentation
|
|
138
|
+
/site/
|
|
139
|
+
|
|
140
|
+
# mypy
|
|
141
|
+
.mypy_cache/
|
|
142
|
+
.dmypy.json
|
|
143
|
+
dmypy.json
|
|
144
|
+
|
|
145
|
+
# Pyre type checker
|
|
146
|
+
.pyre/
|
|
147
|
+
|
|
148
|
+
# pytype static type analyzer
|
|
149
|
+
.pytype/
|
|
150
|
+
|
|
151
|
+
# Cython debug symbols
|
|
152
|
+
cython_debug/
|
|
153
|
+
|
|
154
|
+
# PyCharm
|
|
155
|
+
.idea/
|
|
156
|
+
|
|
157
|
+
# VS Code
|
|
158
|
+
.vscode/
|
|
159
|
+
|
|
160
|
+
# LOOPENGT run traces and temporary databases
|
|
161
|
+
.loopengt/runs/
|
|
162
|
+
.loopengt/*.db
|
|
163
|
+
.loopengt/*.sqlite
|
|
164
|
+
loop.yaml
|
|
165
|
+
LOOP_DESIGN.md
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Loop Engineering configuration
|
|
2
|
+
|
|
3
|
+
[general]
|
|
4
|
+
default_pattern = "sequential"
|
|
5
|
+
trace_format = "jsonl"
|
|
6
|
+
|
|
7
|
+
[llm]
|
|
8
|
+
provider = "openai"
|
|
9
|
+
model = "gpt-4o"
|
|
10
|
+
temperature = 0.7
|
|
11
|
+
# api_key_env = "OPENAI_API_KEY"
|
|
12
|
+
|
|
13
|
+
[mcp]
|
|
14
|
+
transport = "stdio"
|
|
15
|
+
host = "localhost"
|
|
16
|
+
port = 8765
|
|
17
|
+
|
|
18
|
+
[tracing]
|
|
19
|
+
backend = "jsonl"
|
|
20
|
+
directory = "runs"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# LOOPENGT — Loop Engineering Architect
|
|
2
|
+
|
|
3
|
+
You are the Loop Engineering Architect. Given a goal, you design
|
|
4
|
+
the optimal agent loop by selecting the right pattern, defining
|
|
5
|
+
agents, steps, tools, and policies.
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
1. Minimal agents — each must justify its existence
|
|
9
|
+
2. Clear handoff contracts between steps
|
|
10
|
+
3. Verification gates at critical boundaries
|
|
11
|
+
4. Graceful degradation on failure
|
|
12
|
+
5. Observable by default (structured traces)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Acceptance Tests: LOOPENGT Platform
|
|
2
|
+
|
|
3
|
+
This document outlines the strict criteria that must be met before the platform is considered fully implemented and ready for release.
|
|
4
|
+
|
|
5
|
+
## General Requirements
|
|
6
|
+
1. `uv pip install -e .` (or `pip install -e .`) works without errors.
|
|
7
|
+
2. `loopengt` CLI is globally accessible.
|
|
8
|
+
3. CI passes lint (`ruff check`), type-check (`mypy`), tests (`pytest`), and build.
|
|
9
|
+
4. Docs explain architecture, plugin development, and MCP usage.
|
|
10
|
+
|
|
11
|
+
## CLI & Core Flow
|
|
12
|
+
- [ ] `loopengt init` successfully scaffolds the `.loopengt/` directory with `config.toml`, prompts, and templates.
|
|
13
|
+
- [ ] `loopengt design "code review loop"` queries the configured LLM and generates a valid `LOOP_DESIGN.md` and `loop.yaml`.
|
|
14
|
+
- [ ] `loopengt run loop.yaml` parses the generated config, initializes the agents, invokes the LLM, and successfully runs the loop.
|
|
15
|
+
- [ ] Execution gracefully halts upon hitting a defined stop condition or turn limit.
|
|
16
|
+
- [ ] Execution traces are saved correctly to `.loopengt/runs/<id>.json`.
|
|
17
|
+
- [ ] `loopengt trace <run_id>` reads the trace and outputs it to the console in a human-readable format.
|
|
18
|
+
- [ ] `loopengt eval <run_id>` reads the trace, queries an LLM evaluator, and reports the run score.
|
|
19
|
+
|
|
20
|
+
## Templates
|
|
21
|
+
- [ ] At least one built-in template (e.g., `planner-executor`) can be executed end-to-end without failing.
|
|
22
|
+
- [ ] `loopengt template list` returns the built-in templates.
|
|
23
|
+
|
|
24
|
+
## MCP Functionality
|
|
25
|
+
- [ ] `loopengt mcp serve` starts a standard stdio MCP server.
|
|
26
|
+
- [ ] External clients (like Cursor or Claude Code) can list exposed tools (`design_loop`, `run_loop`).
|
|
27
|
+
- [ ] Executing `run_loop` via MCP successfully triggers a background run and returns the run ID.
|
|
28
|
+
|
|
29
|
+
## Plugin & Adapter Ecosystem
|
|
30
|
+
- [ ] `loopengt doctor` detects loaded plugins and adapters.
|
|
31
|
+
- [ ] The terminal adapter works out-of-the-box (renders rich output during `loopengt run`).
|
|
32
|
+
- [ ] Skeleton structures exist for `Antigravity`, `Cursor`, `Claude Code`, and `Codex` adapters in the `plugins/` directory.
|
|
33
|
+
|
|
34
|
+
## Quality Gates
|
|
35
|
+
- **Code Quality**: No `type: ignore` without justification.
|
|
36
|
+
- **Test Coverage**: > 80% coverage in `src/loopengt/core/runtime/`.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
LOOPENGT is a framework for designing, orchestrating, and evaluating agent
|
|
6
|
+
loops. It follows a layered architecture with clear separation of concerns.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
┌─────────────────────────────────────────────────────┐
|
|
10
|
+
│ CLI / IDE Adapters │
|
|
11
|
+
│ (Typer, Cursor, Claude Code, Codex) │
|
|
12
|
+
├─────────────────────────────────────────────────────┤
|
|
13
|
+
│ MCP Server │
|
|
14
|
+
│ (FastMCP — tools, resources, prompts) │
|
|
15
|
+
├─────────────────────────────────────────────────────┤
|
|
16
|
+
│ Plugin System │
|
|
17
|
+
│ (Entry-point discovery, hot-reload) │
|
|
18
|
+
├─────────────────────────────────────────────────────┤
|
|
19
|
+
│ Core Runtime │
|
|
20
|
+
│ ┌───────────┬──────────┬──────────┬────────────┐ │
|
|
21
|
+
│ │ Executor │Scheduler │ Handoff │ Checkpoint │ │
|
|
22
|
+
│ └───────────┴──────────┴──────────┴────────────┘ │
|
|
23
|
+
├─────────────────────────────────────────────────────┤
|
|
24
|
+
│ Core Models │
|
|
25
|
+
│ LoopSpec │ AgentRole │ ToolSpec │ Policy │ State │
|
|
26
|
+
├─────────────────────────────────────────────────────┤
|
|
27
|
+
│ Tracing & Memory │
|
|
28
|
+
│ Events │ TraceStore │ Exporters │ MemoryStore │
|
|
29
|
+
├─────────────────────────────────────────────────────┤
|
|
30
|
+
│ Storage │
|
|
31
|
+
│ SQLite │ JSONL │
|
|
32
|
+
└─────────────────────────────────────────────────────┘
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Core Models
|
|
36
|
+
|
|
37
|
+
All configuration is expressed as **Pydantic v2 models** with strict
|
|
38
|
+
validation. The central model is `LoopSpec`, which is the single source
|
|
39
|
+
of truth for a loop's configuration.
|
|
40
|
+
|
|
41
|
+
### Key Models
|
|
42
|
+
|
|
43
|
+
| Model | Purpose |
|
|
44
|
+
|-------|---------|
|
|
45
|
+
| `LoopSpec` | Complete loop definition — agents, steps, tools, policies |
|
|
46
|
+
| `AgentRole` | Agent identity, capabilities, LLM config |
|
|
47
|
+
| `ToolSpec` | Tool definition (MCP, function, or built-in) |
|
|
48
|
+
| `Policy` | Execution constraints — turns, retries, timeouts, gates |
|
|
49
|
+
| `LoopState` | Mutable runtime state for a running loop |
|
|
50
|
+
|
|
51
|
+
## Orchestration Patterns
|
|
52
|
+
|
|
53
|
+
The executor supports five patterns:
|
|
54
|
+
|
|
55
|
+
1. **Sequential** — steps execute in declaration order
|
|
56
|
+
2. **Supervisor-Worker** — a supervisor decides which worker to invoke next
|
|
57
|
+
3. **Parallel Fan-out** — independent steps execute concurrently
|
|
58
|
+
4. **Handoff** — agents pass enriched context to the next agent
|
|
59
|
+
5. **Evaluator-Optimizer** — iterative quality improvement loop
|
|
60
|
+
|
|
61
|
+
## Plugin Architecture
|
|
62
|
+
|
|
63
|
+
Plugins are discovered via Python entry points:
|
|
64
|
+
|
|
65
|
+
- `loopengt.adapters` — IDE/environment adapters
|
|
66
|
+
- `loopengt.mcp_tools` — Additional MCP tools
|
|
67
|
+
- `loopengt.templates` — Loop template packs
|
|
68
|
+
- `loopengt.skills` — Agent skills
|
|
69
|
+
- `loopengt.verifiers` — Custom verification gates
|
|
70
|
+
|
|
71
|
+
## Data Flow
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Goal → LOOPENGT Design → LoopSpec (YAML)
|
|
75
|
+
│
|
|
76
|
+
LoopExecutor.execute()
|
|
77
|
+
│
|
|
78
|
+
┌────────────┼────────────┐
|
|
79
|
+
│ │ │
|
|
80
|
+
Step 1 Step 2 Step N
|
|
81
|
+
(Agent A) (Agent B) (Agent C)
|
|
82
|
+
│ │ │
|
|
83
|
+
└────────────┼────────────┘
|
|
84
|
+
│
|
|
85
|
+
LoopState (completed)
|
|
86
|
+
│
|
|
87
|
+
┌────────────┼────────────┐
|
|
88
|
+
│ │ │
|
|
89
|
+
Trace Metrics Export
|
|
90
|
+
(JSONL) (Evals) (OTel/MD)
|
|
91
|
+
```
|