mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 04:35:58 -10:00
* fix(code): stop `praisonai code` truncating mid-task and reporting success
Four linked defects meant `praisonai code` could not finish a coding task,
and nothing could tell that it hadn't. All four were reproduced end-to-end
before being changed; each fix has a named test that fails without it
(16/16 mutations killed).
(b) A truncated run reported success. `_run_print_code` classified any
non-empty string as `status: "ok"`, exit 0 — but a budget-exhausted turn
returns a non-empty wrap-up summary, so truncation was indistinguishable
from completion. Measured before:
$ praisonai code -p --output json "...make the tests pass"
{"result": "Tool call limit reached (10 calls)...", "status": "ok"} exit 0
$ pytest -q -> 6 failed, 2 passed
Now `status: "truncated"` and exit 2, reusing `run._run_was_truncated`
rather than adding a second, drifting guard. Same run after: exit 2.
(c) `--dangerously-skip-approval` did not skip approval. It set
PRAISON_APPROVAL_MODE/PRAISONAI_TOOL_SAFETY, which the gate that actually
prompts (the core `@require_approval` decorator, resolving through the
approval registry backend) never reads. With stdin at /dev/null every
prompt was auto-denied, so the agent could not run one shell command —
while still exiting 0. Measured on one task, stdin /dev/null:
before 2 prompts / 2 denials / `1 failed`; after 0 / 0 / `1 passed`.
Fixed by registering AutoApproveBackend the way `--plan` already
registers its own backend — one mechanism, not a second env var. Strictly
opt-in: the safe-by-default branch is unchanged and now also clears a
bypass left by an earlier --no-safe call in the same process. A per-agent
backend (`--plan`, `--agent` scope) still wins, and --plan remains
mutually exclusive with the opt-outs; both are covered by tests.
(a) The step budget was general-purpose, not coding-sized, and unreachable
from the CLI. Two loops enforce different knobs — the LiteLLM loop caps at
`max_tool_calls_per_turn=10` (Gemini-routed run stopped at exactly 10
calls), the OpenAI-native loop at `max_steps`/`max_iter=20` — and
`praisonai code` set neither. Ten calls is "list files, read two files,
one grep"; it cannot reach a test run. Adds `--max-steps` (env fallback
PRAISONAI_CODE_MAX_STEPS) defaulting to 200 for a coding session, raising
*both* knobs, applied to the headless and interactive paths. The core
ExecutionConfig defaults are deliberately left alone so no library user's
behaviour changes. End-to-end on the 8-module repro: previously 6 failed /
2 passed with `status: "ok"`; now 8 passed.
Also fixes the remediation text at run.py:168, which told users to
"Re-run with a higher --max-iter" — a flag with 0 occurrences in the CLI
(control: `--model` = 56).
(d) The gate that would have caught all of this has been red for months. The
Terminal-Bench smoke workflow pinned Python 3.11; harbor requires >=3.12,
so `pip install harbor` resolved to no candidate and every scheduled run
died in ~15s (confirmed 2026-07-27 through 2026-09-07, every week).
RESULTS.md still says `_pending first run_`, accurately: no
Terminal-Bench score has ever been produced. Bumped to 3.12 (verified:
harbor 0.22.0 resolves cleanly on 3.12) and dropped the `|| true` that
would hide a real harness failure. The first honest run may well be red —
that is the point.
Refs #3932
Co-Authored-By: Claude Opus 5 <[email protected]>
* fix(code): apply --max-steps budget on profiled and wrapper-dispatched paths
Closes two Greptile P1 gaps in PR #4930 where the new coding step budget
was silently dropped:
- --profile/--profile-deep built the Agent with no ExecutionConfig, so a
profiled coding run kept the general-purpose core defaults (20 steps /
10 tool calls per turn). Thread build_code_execution_config(max_steps)
into _run_profiled_code.
- The wrapper legacy dispatch (_run_chat_mode / _start_interactive_mode)
never read args.execution, so the common `pip install praisonai`
interactive/single-prompt sessions ignored --max-steps. Thread
args.execution onto the Agent in both interactive_legacy build sites,
mirroring the existing args.agent_approval pattern.
Adds regression tests locking in both paths.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Mervin Praison <[email protected]>
---------
Co-authored-by: Claude Opus 5 <[email protected]>
Co-authored-by: praisonai-triage-agent[bot] <272766704+praisonai-triage-agent[bot]@users.noreply.github.com>
Co-authored-by: Mervin Praison <[email protected]>
Terminal-Bench 2.1 Integration with PraisonAI
This directory contains adapters for benchmarking PraisonAI on Terminal-Bench 2.1 via the Harbor framework. Everything lives in the examples/benchmark layer + CI — there are zero changes to the praisonaiagents / praisonai SDK surface.
Overview
Terminal-Bench 2.1 is the current release of the Laude Institute benchmark for evaluating AI coding agents in real terminal environments. The Harbor framework is the official evaluation harness that abstracts container lifecycle, parallelization, and cloud providers.
Setup
Install Harbor and PraisonAI into one venv and run from the repo root with PYTHONPATH=. so the adapter import path resolves:
pip install harbor
pip install -e src/praisonai-agents -e src/praisonai
export PYTHONPATH=.
Integration Types
0. Code Agent (headline — benchmarks praisonai code)
- File:
praisonai_code_agent.py - Purpose: Installs and drives the terminal-native
praisonai codeassistant headlessly inside the container. - Run:
PYTHONPATH=. harbor run -d terminal-bench/terminal-bench-2-1 \ --agent "examples.terminal_bench.praisonai_code_agent:PraisonAICodeAgent" \ -m openai/gpt-4o-mini \ --ae OPENAI_API_KEY=$OPENAI_API_KEY \ -n 4
1. External Agent (Direct Agent Class)
- File:
praisonai_external_agent.py - Purpose: External agent that uses direct
Agent()class instantiation - Usage: Run with
--agent "module:Class" - Approach: Uses
praisonaiagents.Agentdirectly with a bash tool bridged to Harbor'sexec()
2. Wrapper Agent (CLI-Based)
- File:
praisonai_wrapper_agent.py - Purpose: Uses
praisonai "TASK"CLI pattern instead of direct Agent class - Usage: Run with
--agent-import-path examples.terminal_bench.praisonai_wrapper_agent:PraisonAIWrapperAgent - Approach: Installs
praisonaiCLI inside container and runs tasks via subprocess - Best for: Users who prefer CLI-style interface matching standard
praisonaiusage
3. Installed Agent (Production)
- File:
praisonai_installed_agent.py - Purpose: Production-ready agent installed inside Harbor containers
- Usage: Integrates with Harbor's leaderboard system
Quick Start
Prerequisites
# Install Harbor framework
pip install harbor
# Install PraisonAI with shell tools
pip install praisonaiagents[tools]
Running External Agent (Direct Agent Class)
# Test with oracle agent first
harbor run -d terminal-bench/terminal-bench-2-1 -a oracle
# Run PraisonAI external agent (uses direct Agent() class)
PYTHONPATH=. harbor run -d terminal-bench/terminal-bench-2-1 \
--agent "examples.terminal_bench.praisonai_external_agent:PraisonAIExternalAgent" \
--model openai/gpt-4o-mini \
--ae OPENAI_API_KEY=$OPENAI_API_KEY \
-n 4
Running Wrapper Agent (CLI-Based)
# Run PraisonAI wrapper agent (uses `praisonai "TASK"` CLI pattern)
PYTHONPATH=. harbor run -d terminal-bench/terminal-bench-2-1 \
--agent "examples.terminal_bench.praisonai_wrapper_agent:PraisonAIWrapperAgent" \
--model openai/gpt-4o-mini \
--ae OPENAI_API_KEY=$OPENAI_API_KEY \
-n 4
Running on Cloud (Daytona/E2B/Modal)
PYTHONPATH=. harbor run -d terminal-bench/terminal-bench-2-1 \
--agent "examples.terminal_bench.praisonai_external_agent:PraisonAIExternalAgent" \
--model openai/gpt-4o-mini \
--env daytona -n 32 \
--ae OPENAI_API_KEY=$OPENAI_API_KEY
Key Features
- Shell Execution Bridge: Wraps Harbor's
BaseEnvironment.exec()as PraisonAI tool - Auto-Approval: Bypasses
@require_approvalfor container-isolated execution - Token Tracking: Populates Harbor's
AgentContextwith usage metrics - API Key Forwarding: Supports environment variable injection
- Multi-Agent Support: Can run
AgentTeamandAgentFlowworkflows
Architecture
┌─────────────────────────────────────────┐
│ Harbor Framework │
│ (Terminal-Bench 2.0 Evaluation) │
├─────────────────────────────────────────┤
│ BaseEnvironment.exec() ←→ bash_tool │
├─────────────────────────────────────────┤
│ PraisonAI Agent │
│ • Uses execute_command tool │
│ • Auto-approval for container safety │
│ • Token tracking and metrics │
└─────────────────────────────────────────┘
Files
README.md- This documentationpraisonai_code_agent.py- Headline adapter benchmarkingpraisonai codejob_code_smoke.yaml- Smoke-test job config for the code agentRESULTS.md- Recorded pass-ratespraisonai_external_agent.py- External agent (direct Agent class)praisonai_wrapper_agent.py- Wrapper agent (CLI-based approach)praisonai_installed_agent.py- Installed agent implementationmulti_agent_example.py- Multi-agent team examplejob.yaml- Example Harbor job configurationtest_basic.py- Basic smoke teststest_integration.py- Integration teststest_real_agentic.py- Real agentic tests
Terminal-Bench 2.0 Tasks
The benchmark includes 89 carefully curated tasks covering:
- Compiling code
- Training models
- Setting up servers
- System administration
- File manipulation
- Package management
Each task provides:
- English instruction
- Docker container environment
- Test script (writes reward to
/logs/verifier/reward.txt) - Reference oracle solution
Contributing
- Test changes with oracle agent first:
harbor run -d terminal-bench/terminal-bench-2-1 -a oracle - Run real agentic tests to ensure end-to-end functionality
- Follow PraisonAI's AGENTS.md architecture guidelines
- Add both unit tests and integration tests