forge-agent-runtime 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.
Files changed (44) hide show
  1. forge_agent_runtime-0.1.0/.env.example +41 -0
  2. forge_agent_runtime-0.1.0/.github/workflows/ci.yml +97 -0
  3. forge_agent_runtime-0.1.0/.github/workflows/publish.yml +115 -0
  4. forge_agent_runtime-0.1.0/.gitignore +16 -0
  5. forge_agent_runtime-0.1.0/CONTRIBUTING.md +24 -0
  6. forge_agent_runtime-0.1.0/LICENSE +17 -0
  7. forge_agent_runtime-0.1.0/PKG-INFO +364 -0
  8. forge_agent_runtime-0.1.0/README.md +304 -0
  9. forge_agent_runtime-0.1.0/ROADMAP.md +41 -0
  10. forge_agent_runtime-0.1.0/docs/architecture.md +70 -0
  11. forge_agent_runtime-0.1.0/docs/providers.md +46 -0
  12. forge_agent_runtime-0.1.0/docs/publishing.md +73 -0
  13. forge_agent_runtime-0.1.0/docs/sandbox.md +117 -0
  14. forge_agent_runtime-0.1.0/docs/security.md +47 -0
  15. forge_agent_runtime-0.1.0/pyproject.toml +71 -0
  16. forge_agent_runtime-0.1.0/src/forge_runtime/__init__.py +32 -0
  17. forge_agent_runtime-0.1.0/src/forge_runtime/api.py +139 -0
  18. forge_agent_runtime-0.1.0/src/forge_runtime/cli.py +400 -0
  19. forge_agent_runtime-0.1.0/src/forge_runtime/config.py +41 -0
  20. forge_agent_runtime-0.1.0/src/forge_runtime/evaluation.py +22 -0
  21. forge_agent_runtime-0.1.0/src/forge_runtime/graph.py +85 -0
  22. forge_agent_runtime-0.1.0/src/forge_runtime/models.py +137 -0
  23. forge_agent_runtime-0.1.0/src/forge_runtime/orchestrator.py +289 -0
  24. forge_agent_runtime-0.1.0/src/forge_runtime/providers/__init__.py +1 -0
  25. forge_agent_runtime-0.1.0/src/forge_runtime/providers/anthropic_provider.py +256 -0
  26. forge_agent_runtime-0.1.0/src/forge_runtime/providers/base.py +10 -0
  27. forge_agent_runtime-0.1.0/src/forge_runtime/providers/factory.py +46 -0
  28. forge_agent_runtime-0.1.0/src/forge_runtime/providers/mock.py +24 -0
  29. forge_agent_runtime-0.1.0/src/forge_runtime/providers/openai_provider.py +264 -0
  30. forge_agent_runtime-0.1.0/src/forge_runtime/registry.py +245 -0
  31. forge_agent_runtime-0.1.0/src/forge_runtime/sandbox.py +872 -0
  32. forge_agent_runtime-0.1.0/src/forge_runtime/sandbox_assets/Dockerfile +51 -0
  33. forge_agent_runtime-0.1.0/src/forge_runtime/sandbox_assets/__init__.py +1 -0
  34. forge_agent_runtime-0.1.0/src/forge_runtime/storage.py +82 -0
  35. forge_agent_runtime-0.1.0/src/forge_runtime/workspace.py +280 -0
  36. forge_agent_runtime-0.1.0/tests/test_api.py +60 -0
  37. forge_agent_runtime-0.1.0/tests/test_cli.py +71 -0
  38. forge_agent_runtime-0.1.0/tests/test_config.py +41 -0
  39. forge_agent_runtime-0.1.0/tests/test_graph.py +32 -0
  40. forge_agent_runtime-0.1.0/tests/test_orchestrator.py +37 -0
  41. forge_agent_runtime-0.1.0/tests/test_registry.py +39 -0
  42. forge_agent_runtime-0.1.0/tests/test_sandbox.py +210 -0
  43. forge_agent_runtime-0.1.0/tests/test_storage.py +13 -0
  44. forge_agent_runtime-0.1.0/tests/test_workspace.py +108 -0
@@ -0,0 +1,41 @@
1
+ # Runtime
2
+ FORGE_ENV=development
3
+ FORGE_LOG_LEVEL=INFO
4
+ FORGE_DATABASE_URL=sqlite:///./.forge/forge.db
5
+ FORGE_WORKSPACE_ROOT=.
6
+ FORGE_MAX_PARALLEL_TASKS=4
7
+ FORGE_TASK_TIMEOUT_SECONDS=900
8
+
9
+ # Sandboxed command execution for OpenAI/Anthropic agents (requires Docker)
10
+ FORGE_SANDBOX_NETWORK=bridge
11
+ FORGE_SANDBOX_ENABLED=true
12
+ FORGE_SANDBOX_IMAGE=forge-runtime-sandbox:internet-v1
13
+ FORGE_SANDBOX_DOCKER_BINARY=docker
14
+ FORGE_SANDBOX_CPU_LIMIT=2
15
+ FORGE_SANDBOX_MEMORY_MB=2048
16
+ FORGE_SANDBOX_PIDS_LIMIT=128
17
+ FORGE_SANDBOX_DEFAULT_TIMEOUT_SECONDS=180
18
+ FORGE_SANDBOX_MAX_TIMEOUT_SECONDS=600
19
+ FORGE_SANDBOX_OUTPUT_CHARS=24000
20
+ FORGE_SANDBOX_MAX_SNAPSHOT_FILES=5000
21
+ FORGE_SANDBOX_MAX_SNAPSHOT_MB=512
22
+ FORGE_DEFAULT_PROVIDER=mock
23
+
24
+ # AgentForge registry: auto uses the installed agentforge-toolkit wheel first.
25
+ # Set source=local and path to a repository checkout to override packaged assets.
26
+ FORGE_AGENTFORGE_SOURCE=auto
27
+ FORGE_AGENTFORGE_REPOSITORY=https://github.com/mhingan/agent-forge
28
+ FORGE_AGENTFORGE_REF=main
29
+ FORGE_AGENTFORGE_LOCAL_PATH=
30
+
31
+ # Hosted model providers (optional)
32
+ OPENAI_API_KEY=
33
+ OPENAI_MODEL=gpt-4.1
34
+ OPENAI_BASE_URL=
35
+ ANTHROPIC_API_KEY=
36
+ ANTHROPIC_MODEL=claude-sonnet-4-5
37
+
38
+ # Local HTTP API (install forge-runtime[api] to use forge serve)
39
+ FORGE_API_HOST=127.0.0.1
40
+ FORGE_API_PORT=8787
41
+ FORGE_API_TOKEN=
@@ -0,0 +1,97 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ python-version: ["3.11", "3.12", "3.13"]
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+ cache: pip
25
+ - name: Install runtime, toolkit and test dependencies
26
+ run: python -m pip install -e ".[dev,api]"
27
+ - name: Lint and import normalization
28
+ run: |
29
+ ruff check . --fix
30
+ ruff check .
31
+ - name: Test
32
+ run: pytest --cov=forge_runtime --cov-report=term-missing
33
+
34
+ sandbox-integration:
35
+ runs-on: ubuntu-latest
36
+ steps:
37
+ - uses: actions/checkout@v4
38
+ - uses: actions/setup-python@v5
39
+ with:
40
+ python-version: "3.12"
41
+ cache: pip
42
+ - name: Install Forge Runtime
43
+ run: python -m pip install -e ".[dev,api]"
44
+ - name: Build disposable agent toolchain image
45
+ run: forge sandbox build
46
+ - name: Verify Docker image and daemon
47
+ run: forge sandbox check
48
+ - name: Verify internet access inside sandbox
49
+ run: forge sandbox run -- curl --fail --silent --show-error --max-time 15 -I https://pypi.org
50
+ - name: Run complete suite inside sandbox
51
+ run: forge sandbox run -- bash -lc "PYTHONPATH=src python -m pytest -q"
52
+ - name: Lint inside sandbox
53
+ run: forge sandbox run -- ruff check src tests
54
+ - name: Verify read-write sandbox changes are applied
55
+ run: |
56
+ forge sandbox run --read-write -- python -c "from pathlib import Path; Path('.forge-sandbox-write-check').write_text('ok', encoding='utf-8')"
57
+ test "$(cat .forge-sandbox-write-check)" = "ok"
58
+ rm .forge-sandbox-write-check
59
+ - name: Verify read-only sandbox changes are discarded
60
+ run: |
61
+ forge sandbox run -- python -c "from pathlib import Path; Path('.forge-sandbox-readonly-check').write_text('must-not-escape', encoding='utf-8')"
62
+ test ! -e .forge-sandbox-readonly-check
63
+
64
+ package:
65
+ name: Build PyPI distributions
66
+ runs-on: ubuntu-latest
67
+ steps:
68
+ - uses: actions/checkout@v4
69
+ - uses: actions/setup-python@v5
70
+ with:
71
+ python-version: "3.12"
72
+ - name: Install packaging tools
73
+ run: python -m pip install --upgrade build twine
74
+ - name: Build wheel and source distribution
75
+ run: python -m build
76
+ - name: Validate distribution metadata
77
+ run: python -m twine check dist/*
78
+ - name: Verify bundled sandbox Dockerfile
79
+ run: |
80
+ python - <<'PY'
81
+ import glob
82
+ import tarfile
83
+ import zipfile
84
+
85
+ wheels = glob.glob("dist/*.whl")
86
+ sdists = glob.glob("dist/*.tar.gz")
87
+ assert len(wheels) == 1, f"Expected one wheel, found {wheels}"
88
+ assert len(sdists) == 1, f"Expected one sdist, found {sdists}"
89
+ with zipfile.ZipFile(wheels[0]) as wheel:
90
+ assert "forge_runtime/sandbox_assets/Dockerfile" in wheel.namelist()
91
+ with tarfile.open(sdists[0], "r:gz") as sdist:
92
+ assert any(
93
+ name.endswith("/src/forge_runtime/sandbox_assets/Dockerfile")
94
+ for name in sdist.getnames()
95
+ )
96
+ print("Wheel and sdist both contain the sandbox Dockerfile.")
97
+ PY
@@ -0,0 +1,115 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ concurrency:
11
+ group: pypi-${{ github.event.release.tag_name }}
12
+ cancel-in-progress: false
13
+
14
+ jobs:
15
+ build:
16
+ name: Build and validate distributions
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - name: Check out release source
20
+ uses: actions/checkout@v4
21
+ - name: Set up Python
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+ - name: Verify release tag matches package version
26
+ env:
27
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
28
+ run: |
29
+ python - <<'PY'
30
+ import os
31
+ import tomllib
32
+ from pathlib import Path
33
+
34
+ version = tomllib.loads(Path("pyproject.toml").read_text())["project"]["version"]
35
+ expected = f"v{version}"
36
+ actual = os.environ["RELEASE_TAG"]
37
+ if actual != expected:
38
+ raise SystemExit(
39
+ f"Release tag {actual!r} does not match package version {expected!r}."
40
+ )
41
+ print(f"Preparing forge-agent-runtime {version}")
42
+ PY
43
+ - name: Install packaging tools
44
+ run: python -m pip install --upgrade build twine
45
+ - name: Check initial PyPI project name availability
46
+ if: github.event.release.tag_name == 'v0.1.0'
47
+ run: |
48
+ python - <<'PY'
49
+ import urllib.error
50
+ import urllib.request
51
+
52
+ url = "https://pypi.org/pypi/forge-agent-runtime/json"
53
+ try:
54
+ with urllib.request.urlopen(url, timeout=15) as response:
55
+ if response.status == 200:
56
+ raise SystemExit(
57
+ "forge-agent-runtime is already registered on PyPI. "
58
+ "Choose a different distribution name before publishing."
59
+ )
60
+ except urllib.error.HTTPError as exc:
61
+ if exc.code != 404:
62
+ raise
63
+ print("forge-agent-runtime is not currently registered on PyPI.")
64
+ PY
65
+ - name: Build wheel and source distribution
66
+ run: python -m build
67
+ - name: Validate distribution metadata
68
+ run: python -m twine check dist/*
69
+ - name: Verify bundled sandbox Dockerfile
70
+ run: |
71
+ python - <<'PY'
72
+ import glob
73
+ import tarfile
74
+ import zipfile
75
+
76
+ wheels = glob.glob("dist/*.whl")
77
+ sdists = glob.glob("dist/*.tar.gz")
78
+ assert len(wheels) == 1, f"Expected one wheel, found {wheels}"
79
+ assert len(sdists) == 1, f"Expected one sdist, found {sdists}"
80
+
81
+ with zipfile.ZipFile(wheels[0]) as wheel:
82
+ assert "forge_runtime/sandbox_assets/Dockerfile" in wheel.namelist()
83
+
84
+ with tarfile.open(sdists[0], "r:gz") as sdist:
85
+ assert any(
86
+ name.endswith("/src/forge_runtime/sandbox_assets/Dockerfile")
87
+ for name in sdist.getnames()
88
+ )
89
+ print("Wheel and sdist both contain the sandbox Dockerfile.")
90
+ PY
91
+ - name: Upload distributions
92
+ uses: actions/upload-artifact@v4
93
+ with:
94
+ name: python-package-distributions
95
+ path: dist/
96
+ if-no-files-found: error
97
+ retention-days: 7
98
+
99
+ publish:
100
+ name: Publish to PyPI
101
+ needs: build
102
+ runs-on: ubuntu-latest
103
+ environment:
104
+ name: pypi
105
+ url: https://pypi.org/p/forge-agent-runtime
106
+ permissions:
107
+ id-token: write
108
+ steps:
109
+ - name: Download distributions
110
+ uses: actions/download-artifact@v4
111
+ with:
112
+ name: python-package-distributions
113
+ path: dist/
114
+ - name: Publish with PyPI Trusted Publishing
115
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,16 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .pytest_cache/
4
+ .coverage
5
+ htmlcov/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .venv/
9
+ venv/
10
+ .env
11
+ .env.*
12
+ !.env.example
13
+ dist/
14
+ build/
15
+ *.egg-info/
16
+ .DS_Store
@@ -0,0 +1,24 @@
1
+ # Contributing
2
+
3
+ ## Setup
4
+
5
+ ```bash
6
+ python -m pip install -e ".[dev,api,openai]"
7
+ ```
8
+
9
+ ## Quality gates
10
+
11
+ ```bash
12
+ pytest
13
+ ruff check .
14
+ ```
15
+
16
+ ## Expectations
17
+
18
+ - Keep runtime contracts independent from provider SDKs and API frameworks.
19
+ - Do not invent AgentForge fields: integrate against the published 1.1.0 catalog and package API.
20
+ - Validate every generated plan before dispatch.
21
+ - Keep workspace file tools confined to the configured root; do not enable shell, network or deployment tools without a separately reviewed sandbox and permission model.
22
+ - Add regression coverage for dependency ordering, concurrency, retries, failure propagation, registry compatibility and API authorization.
23
+ - Update README, docs, roadmap and .env.example when behavior or configuration changes.
24
+ - Never commit API keys, personal data, provider secrets or customer project context.
@@ -0,0 +1,17 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mihaita Hingan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -0,0 +1,364 @@
1
+ Metadata-Version: 2.5
2
+ Name: forge-agent-runtime
3
+ Version: 0.1.0
4
+ Summary: Docker-isolated multi-agent orchestration runtime for the AgentForge ecosystem
5
+ Project-URL: Homepage, https://github.com/mhingan/forge-runtime
6
+ Project-URL: Repository, https://github.com/mhingan/forge-runtime
7
+ Project-URL: Issues, https://github.com/mhingan/forge-runtime/issues
8
+ Author: Mihaita Hingan
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Mihaita Hingan
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26
+ License-File: LICENSE
27
+ Keywords: agentforge,agents,coding-agent,llm,multi-agent,orchestration
28
+ Classifier: Development Status :: 3 - Alpha
29
+ Classifier: Environment :: Console
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Operating System :: OS Independent
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.11
35
+ Classifier: Programming Language :: Python :: 3.12
36
+ Classifier: Programming Language :: Python :: 3.13
37
+ Classifier: Topic :: Software Development :: Build Tools
38
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
39
+ Requires-Python: >=3.11
40
+ Requires-Dist: agentforge-toolkit==1.1.0
41
+ Requires-Dist: httpx<1,>=0.27
42
+ Requires-Dist: pydantic-settings<3,>=2.2
43
+ Requires-Dist: pydantic<3,>=2.7
44
+ Requires-Dist: rich<15,>=13.7
45
+ Requires-Dist: typer<1,>=0.12
46
+ Provides-Extra: anthropic
47
+ Requires-Dist: anthropic<1,>=0.28; extra == 'anthropic'
48
+ Provides-Extra: api
49
+ Requires-Dist: fastapi<1,>=0.115; extra == 'api'
50
+ Requires-Dist: uvicorn[standard]<1,>=0.30; extra == 'api'
51
+ Provides-Extra: dev
52
+ Requires-Dist: mypy>=1.10; extra == 'dev'
53
+ Requires-Dist: pytest-asyncio<2,>=0.23; extra == 'dev'
54
+ Requires-Dist: pytest-cov<8,>=5; extra == 'dev'
55
+ Requires-Dist: pytest<9,>=8; extra == 'dev'
56
+ Requires-Dist: ruff>=0.5; extra == 'dev'
57
+ Provides-Extra: openai
58
+ Requires-Dist: openai<3,>=1.30; extra == 'openai'
59
+ Description-Content-Type: text/markdown
60
+
61
+ # Forge Runtime
62
+
63
+ **A provider-neutral execution and orchestration engine for the AgentForge ecosystem.**
64
+
65
+ Forge Runtime turns one user goal into a validated multi-agent execution graph. Forge Master selects specialist roles from AgentForge, asks an LLM provider to create a plan, validates the task dependencies, dispatches work concurrently, passes successful dependency results downstream, evaluates task outputs, and persists an execution history.
66
+
67
+ ## AgentForge integration
68
+
69
+ Forge Runtime depends on the published distribution **agentforge-toolkit 1.1.0**. The toolkit exposes its bundled library directory through `agentforge.core.data_root()`; the runtime reads the catalogs and Markdown definitions from that packaged data.
70
+
71
+ | Project | Responsibility |
72
+ |---|---|
73
+ | [AgentForge](https://github.com/mhingan/agent-forge) / [PyPI](https://pypi.org/project/agentforge-toolkit/1.1.0/) | Agent roles, skills, rules, workflows, catalogs, provider-specific coding-agent installation |
74
+ | **Forge Runtime** | Forge Master, planning, DAG scheduling, dispatch, model-provider calls, state, evaluation, API and execution reports |
75
+
76
+ The runtime does not call an undocumented AgentForge registry class or assume the toolkit is a hosted service. The adapter uses the package's real `data_root()` entry point. A local repository checkout and GitHub raw source are also supported.
77
+
78
+ ## Runtime capabilities
79
+
80
+ - **Forge Master:** central coordinator for each execution run.
81
+ - **AgentForge registry:** reads packaged roles, skills, rules and workflow playbooks.
82
+ - **Planning:** OpenAI and Anthropic providers produce a structured execution plan; mock provider supports deterministic smoke tests.
83
+ - **Task graph:** validates unique IDs, known roles/skills, dependencies, cycles and task limits before dispatch.
84
+ - **Parallel scheduler:** independent tasks run concurrently under a configurable semaphore.
85
+ - **Dependency context:** successful outputs are passed to tasks that depend on them.
86
+ - **Workspace tools:** OpenAI and Anthropic agents can list, read, search and (for `read-write` roles) write files in a configured project workspace.
87
+ - **Sandbox executor:** LLM agents can run tests, install dependencies and use the internet from disposable Docker containers with resource limits and controlled change-back.
88
+ - **Retries and deadlines:** bounded attempts and per-task timeouts.
89
+ - **Failure propagation:** tasks that depend on failed work are marked blocked.
90
+ - **Evaluation:** baseline output validation behind a replaceable evaluator contract.
91
+ - **Persistence:** SQLite records runs, task states, outputs and execution events.
92
+ - **CLI and HTTP API:** inspect the registry, submit work and inspect run history.
93
+
94
+ ## Architecture
95
+
96
+ ```text
97
+ User goal / CLI / HTTP API
98
+ |
99
+ v
100
+ FORGE MASTER
101
+ |
102
+ Load AgentForge toolkit data
103
+ |
104
+ LLM planner / Mock planner
105
+ |
106
+ Validate execution DAG
107
+ |
108
+ Task scheduler
109
+ / | \
110
+ v v v
111
+ Architect Backend Product ...
112
+ | | |
113
+ +----------+-----------+
114
+ |
115
+ Dependency result hand-off
116
+ |
117
+ Evaluator / Retry
118
+ |
119
+ SQLite store
120
+ |
121
+ Run report + event history
122
+ ```
123
+
124
+ AgentForge profiles and skills are untrusted model context, not executable permissions. OpenAI and Anthropic providers can modify ordinary files only inside `FORGE_WORKSPACE_ROOT`, and only when the selected role is `read-write`. Commands run inside Docker, never directly on the host. Git commit/push, browser, deployment and arbitrary MCP tools are not provided.
125
+
126
+ ## Requirements
127
+
128
+ - Python 3.11+
129
+ - AgentForge Toolkit 1.1.0 (installed automatically as a project dependency)
130
+ - An API key only when using OpenAI or Anthropic
131
+
132
+ ## Install from source
133
+
134
+ ```bash
135
+ git clone https://github.com/mhingan/forge-runtime.git
136
+ cd forge-runtime
137
+ python -m venv .venv
138
+ source .venv/bin/activate
139
+ python -m pip install -e ".[openai]"
140
+ ```
141
+
142
+ The dependency installation also installs `agentforge-toolkit==1.1.0`. No separate AgentForge clone is required for the standard configuration.
143
+
144
+
145
+ ## Install from PyPI
146
+
147
+ Once the first release is published:
148
+
149
+ ```bash
150
+ python -m pip install "forge-agent-runtime[openai]"
151
+ forge setup
152
+ forge run "Inspect this project, implement the requested feature and run the tests"
153
+ ```
154
+
155
+ For Anthropic, install `forge-agent-runtime[anthropic]`. The PyPI distribution is named `forge-agent-runtime`; the Python import package remains `forge_runtime`, and the command-line executable remains `forge`.
156
+
157
+ ## Quick start — two commands after installation
158
+
159
+ From the project directory, run:
160
+
161
+ ```bash
162
+ # Prompts for your OpenAI key, saves it safely in .env, and builds the Docker image
163
+ forge setup
164
+
165
+ # Give Forge a task; agents can edit files, install dependencies and access the internet
166
+ forge run "Inspect this project, implement the missing features and run the tests"
167
+ ```
168
+
169
+ Use `forge setup --provider anthropic` for Anthropic, or `forge setup --provider mock` for a no-key demo. Setup builds the sandbox image only once; later runs reuse it.
170
+
171
+ The sandbox uses Docker's `bridge` network by default, which enables outbound internet access for commands such as `curl`, `wget`, `pip install`, `npm install` and Git operations. Set `FORGE_SANDBOX_NETWORK=none` in `.env` to run offline.
172
+
173
+ ## First run — mock provider
174
+
175
+ ```bash
176
+ forge registry validate
177
+ forge agent list
178
+ forge skill list
179
+ forge rule list
180
+ forge workflow list
181
+
182
+ forge run "Design a secure REST API for an e-commerce platform" --provider mock
183
+ forge runs list
184
+ ```
185
+
186
+ Mock mode verifies registry loading, planning, graph validation, scheduling, persistence and event creation without making model API calls. Its outputs are clearly marked as demonstrations; it does not produce real code changes.
187
+
188
+ ## Run with an LLM
189
+
190
+ For OpenAI:
191
+
192
+ ```bash
193
+ export OPENAI_API_KEY="..."
194
+ export FORGE_DEFAULT_PROVIDER=openai
195
+ forge run "Build a secure customer management API with tests"
196
+ ```
197
+
198
+ Or choose a provider per run:
199
+
200
+ ```bash
201
+ forge run "Review the backend architecture" --provider openai
202
+ forge run "Plan a Flutter application" --provider anthropic
203
+ ```
204
+
205
+ Optional provider installs:
206
+
207
+ ```bash
208
+ python -m pip install -e ".[openai]"
209
+ python -m pip install -e ".[anthropic]"
210
+ ```
211
+
212
+ The LLM providers have bounded workspace and Docker command tools, but no direct host shell or deployment access. Their command execution runs in disposable containers.
213
+
214
+ ## Workspace access for coding tasks
215
+
216
+ OpenAI and Anthropic providers expose bounded workspace tools during specialist execution:
217
+
218
+ | Tool | Capability | AgentForge permission |
219
+ |---|---|---|
220
+ | `workspace_list_files` | List project files | read-only and read-write |
221
+ | `workspace_read_file` | Read UTF-8 source files | read-only and read-write |
222
+ | `workspace_search_files` | Search source text | read-only and read-write |
223
+ | `workspace_write_file` | Create or replace UTF-8 files | read-write only |
224
+ | `workspace_run_command` | Run allowlisted developer commands in isolated Docker | read-only and read-write |
225
+
226
+ The default workspace is the directory from which `forge` is launched. Set `FORGE_WORKSPACE_ROOT` to select a specific project. The runtime confines paths to that root and rejects traversal paths, drive-qualified paths, symlinks that escape the root, secret environment files and private-key files. It excludes common dependency/build directories and caps file sizes, search results, tool rounds and total tool calls.
227
+
228
+ Example:
229
+
230
+ ```bash
231
+ export FORGE_WORKSPACE_ROOT="/path/to/my-project"
232
+ export OPENAI_API_KEY="..."
233
+ forge run "Inspect the project, implement a responsive settings page, and add tests" --provider openai
234
+ ```
235
+
236
+ The model can read and write files through workspace tools. Command execution is a separate Docker capability described below. Mock mode never modifies files. Review the resulting diff before using changes in production.
237
+
238
+ ## Sandboxed command execution
239
+
240
+ Install and start Docker Desktop or Docker Engine. The first setup builds a local toolchain image and verifies that the sandbox can reach the internet.
241
+
242
+ ```bash
243
+ # Check the Docker daemon and configured image
244
+ forge sandbox check
245
+
246
+ # Build forge-runtime-sandbox:internet-v1 once
247
+ forge sandbox build
248
+
249
+ # Smoke-test the image
250
+ forge sandbox run -- python --version
251
+ forge sandbox run -- pytest --version
252
+
253
+ # Run the project's tests in a disposable container
254
+ forge sandbox run -- python -m pytest
255
+ ```
256
+
257
+ The LLM providers expose `workspace_run_command`. The tool accepts an argv array, not a raw shell string. Typical commands include `python -m pytest`, `ruff check .`, `mypy`, `npm test`, `node --test` and `make test`. Shells (`bash`/`sh`) are available inside the container for project scripts, but never on the host.
258
+
259
+ The sandbox uses Docker bridge networking for internet access, a read-only container root filesystem, dropped Linux capabilities, `no-new-privileges`, a non-root UID, PID/CPU/memory limits, an execution timeout and capped output. It receives a sanitized temporary copy of the project, excluding `.git`, environment secrets, credentials, private keys, dependency folders and common build caches. With internet enabled, `node_modules` is a temporary writable volume for package installation; in offline mode, an existing local `node_modules` may be mounted read-only. No host API keys or environment variables are forwarded.
260
+
261
+ For AgentForge `read-write` roles, newly created or modified regular files are copied back after the command. Deletions and symlinks are not copied back. For `read-only` roles, all container changes are discarded. A failed test command still returns stdout, stderr and its exit code so the agent can diagnose, fix and rerun.
262
+
263
+ The default image includes Python, pytest, Ruff, mypy, Node.js/npm, Git and common build tools. Projects requiring additional Python, Node or system libraries should customize `src/forge_runtime/sandbox_assets/Dockerfile`, rebuild the image and set `FORGE_SANDBOX_IMAGE` if using a different tag. Runtime containers never pull missing images automatically; run `forge sandbox build` explicitly.
264
+
265
+ Set `FORGE_SANDBOX_ENABLED=false` to remove command execution from model tool schemas. This is a Docker container boundary, not a VM: run Docker Engine on a trusted host, keep it patched and review agent changes before merging.
266
+
267
+ ## Registry source selection
268
+
269
+ The default setting `FORGE_AGENTFORGE_SOURCE=auto` loads the packaged AgentForge data via `agentforge.core.data_root()`.
270
+
271
+ | Setting | Behavior |
272
+ |---|---|
273
+ | `auto` | Use installed toolkit; fall back to GitHub when it is unavailable |
274
+ | `installed` | Require installed `agentforge-toolkit` package data |
275
+ | `local` | Use `FORGE_AGENTFORGE_LOCAL_PATH` |
276
+ | `github` | Fetch catalogs and referenced Markdown from the configured GitHub ref |
277
+
278
+ For a local AgentForge checkout:
279
+
280
+ ```bash
281
+ export FORGE_AGENTFORGE_SOURCE=local
282
+ export FORGE_AGENTFORGE_LOCAL_PATH="../agent-forge"
283
+ forge registry validate
284
+ ```
285
+
286
+ ## Local HTTP API
287
+
288
+ Install the API extra and start the service:
289
+
290
+ ```bash
291
+ python -m pip install -e ".[api]"
292
+ forge serve
293
+ ```
294
+
295
+ Default address: `http://127.0.0.1:8787`. Interactive API documentation is available at `/docs`.
296
+
297
+ | Method | Endpoint | Description |
298
+ |---|---|---|
299
+ | GET | `/health` | Service health |
300
+ | GET | `/v1/agents` | AgentForge agent catalog |
301
+ | GET | `/v1/skills` | AgentForge skill catalog |
302
+ | POST | `/v1/runs` | Submit a goal and execute the run |
303
+ | GET | `/v1/runs` | List recent runs |
304
+ | GET | `/v1/runs/{run_id}` | Read run, task and event records |
305
+
306
+ Example:
307
+
308
+ ```bash
309
+ curl http://127.0.0.1:8787/v1/agents
310
+
311
+ curl -X POST http://127.0.0.1:8787/v1/runs \
312
+ -H "Content-Type: application/json" \
313
+ -d '{"goal":"Plan a secure inventory API","provider":"mock"}'
314
+ ```
315
+
316
+ The API executes a submitted run synchronously and returns the final run record. This is a local control API, not yet a durable background job service. Keep it bound to localhost for personal development. For a network bind, set a strong `FORGE_API_TOKEN`; send it as `X-Forge-API-Key`.
317
+
318
+ ## Configuration
319
+
320
+ See `.env.example` and [the PyPI publishing guide](docs/publishing.md).
321
+
322
+ | Variable | Purpose | Default |
323
+ |---|---|---|
324
+ | `FORGE_DEFAULT_PROVIDER` | Default model provider | `mock` |
325
+ | `FORGE_MAX_PARALLEL_TASKS` | Max concurrent tasks | `4` |
326
+ | `FORGE_TASK_TIMEOUT_SECONDS` | Per-task timeout ceiling | `900` |
327
+ | `FORGE_DATABASE_URL` | SQLite database URL | `sqlite:///./.forge/forge.db` |
328
+ | `FORGE_WORKSPACE_ROOT` | Project directory visible to the runtime | `.` |
329
+ | `FORGE_SANDBOX_ENABLED` | Expose Docker command tool to LLM agents | `true` |
330
+ | `FORGE_SANDBOX_IMAGE` | Prebuilt local Docker image name | `forge-runtime-sandbox:internet-v1` |
331
+ | `FORGE_SANDBOX_NETWORK` | Sandbox network (`bridge` or `none`) | `bridge` |
332
+ | `FORGE_SANDBOX_CPU_LIMIT` / `MEMORY_MB` | Per-container CPU and memory limits | `2` / `2048` |
333
+ | `FORGE_SANDBOX_DEFAULT_TIMEOUT_SECONDS` | Default command timeout | `180` |
334
+ | `FORGE_AGENTFORGE_SOURCE` | Registry source selection | `auto` |
335
+ | `OPENAI_API_KEY` | OpenAI key | unset |
336
+ | `ANTHROPIC_API_KEY` | Anthropic key | unset |
337
+ | `FORGE_API_TOKEN` | HTTP API key for network binds | unset |
338
+
339
+ ## Security and limitations
340
+
341
+ - All user goals, registry files and model outputs are treated as untrusted content.
342
+ - Plans are validated against installed AgentForge role and skill names before any task runs.
343
+ - The scheduler enforces bounded concurrency, retries and timeouts.
344
+ - OpenAI and Anthropic agents can change ordinary files only inside `FORGE_WORKSPACE_ROOT` and only with a `read-write` role; secrets are excluded from workspace tools and sandbox snapshots.
345
+ - Shell/test/build commands run only inside ephemeral Docker containers. Bridge mode provides outbound internet and may reach private/LAN destinations accessible from the Docker host. Use `none` for offline tasks. This is container isolation, not a VM or protection from host-kernel/Docker-daemon vulnerabilities.
346
+ - The sandbox does not provide Git commit/push, deployment, browser access or arbitrary MCP tools. Deletions are not copied back.
347
+ - Tasks flagged as requiring human approval are rejected because the approval subsystem is not enabled yet.
348
+ - SQLite is intended for local and single-process use; it is not a distributed job queue.
349
+ - The baseline evaluator checks output presence and size; it is not a semantic correctness guarantee.
350
+ - The HTTP API should not be exposed publicly without a hardened deployment, authentication, TLS and tenant isolation.
351
+
352
+ ## Development
353
+
354
+ ```bash
355
+ python -m pip install -e ".[dev,api]"
356
+ pytest
357
+ ruff check . --fix && ruff check .
358
+ ```
359
+
360
+ See [architecture](docs/architecture.md), [provider contracts](docs/providers.md), [sandbox details](docs/sandbox.md), [security](docs/security.md), [roadmap](ROADMAP.md) and [contributing](CONTRIBUTING.md).
361
+
362
+ ## License
363
+
364
+ MIT.