{
  "markdown": "# agent-estimate\n\n[![PyPI Version](https://img.shields.io/pypi/v/agent-estimate)](https://pypi.org/project/agent-estimate/)\n[![Python Versions](https://img.shields.io/pypi/pyversions/agent-estimate)](https://pypi.org/project/agent-estimate/)\n[![License](https://img.shields.io/pypi/l/agent-estimate)](https://github.com/kiloloop/agent-estimate/blob/main/LICENSE)\n[![CI](https://github.com/kiloloop/agent-estimate/actions/workflows/ci.yml/badge.svg)](https://github.com/kiloloop/agent-estimate/actions/workflows/ci.yml)\n\n**Know before you build.**\n\nPERT estimates for AI-agent tasks — how long, which model's reliable enough, and the human-equivalent cost. In one command.\n\n**[Website](https://kiloloop.com/agent-estimate/)** · [Compare](https://kiloloop.com/agent-estimate/compare/) · [PyPI](https://pypi.org/project/agent-estimate/)\n\n## Why\n\nAI agents can write the code — but *how long will the task actually take?* Manual estimation is slow and biased toward optimism; no estimate means scope creep and missed deadlines. The gap between \"agents can do it\" and \"we know when it'll be done\" is where projects break down.\n\n`agent-estimate` closes that gap in one command: a three-point PERT timeline built from priors drawn from 33 internal coding dispatches and 6 brainstorm dispatches, plus a human-speed comparison so you see the compression before you spend the compute. It sizes the task, picks a tier, routes it to a model, and flags when the work exceeds that model's configured reliability policy — forecasts in seconds, not meetings.\n\nMulti-model matters because the models aren't interchangeable. A measured p80 horizon is the human-expert task duration at which a model is estimated to succeed 80% of the time. The shipped limits below are instead provenance-labeled local policy (unmeasured), because current models such as Opus 4.7 and GPT-5.5 do not have matching published measurements. agent-estimate models the whole fleet, not a single agent — so the number reflects who actually runs the work.\n\n## Quick Start\n\n> First estimate: 30 seconds to install. Every one after: instant.\n\n### With your agent (recommended)\n\nPaste this into your Claude Code or Codex session:\n\n~~~\nInstall the agent-estimate plugin (https://github.com/kiloloop/agent-estimate) and\nestimate this task for me: \"Implement OAuth 2.0 flow (Google + GitHub)\". Tell me the\nexpected time, the human-speed equivalent, and the compression ratio.\n~~~\n\nYour agent installs the tool, runs the estimate, and reads back the numbers. Nothing to memorize — describe the task in plain English and let the agent translate to flags.\n\nFor a whole backlog:\n\n~~~\nEstimate every open issue in this repo with agent-estimate, group them into parallel\nwaves, and tell me the total wall-clock time for a 3-agent fleet versus doing them\nsequentially myself.\n~~~\n\n### Manual\n\n```bash\npip install agent-estimate\nagent-estimate estimate \"your task description here\"\n```\n\nNo config required — sensible defaults for a 3-agent fleet (Claude, Codex, Gemini). Point it at a file or GitHub issues when you're ready:\n\n```bash\nagent-estimate estimate --file tasks.txt\nagent-estimate estimate --repo myorg/myrepo --issues 11,12,14\nagent-estimate session --agents 3 --rounds 2 --type review\n```\n\n### v0.8 forecast contract\n\nThe v0.8 source introduces a versioned request for callers that already know the\ntask and executor. These features are not in the published v0.7.5 package; use an\ninstallation from this checkout until v0.8 is released. Bare task descriptions,\ntext files, and GitHub issue input remain available.\n\n| Contract | Owns |\n|----------|------|\n| `TaskSpec` | Task facts, required capabilities, dependencies, and independent scope estimates |\n| `ExecutionProfile` | Runtime and model identity, configuration provenance, context, modifiers, and review plan |\n| `AdmissionEnvelope` | Declared minute/file caps and optional replayable cap calculations |\n| `ForecastRecord` | Expected wall minutes, expected files, additive review minutes, and forecast provenance |\n\nThe [typed contracts](src/agent_estimate/contract/schema.py) are frozen, reject\nunknown fields and non-finite numbers, and require explicit schema versions.\nModel identity must be either a supplied identifier or an `unknown_reason`;\nselecting an agent does not establish its serving model. IDs are caller supplied.\nThe library also exposes `OutcomeObservation` with nullable future actuals slots;\nit does not ingest actuals or persist binding receipts.\n\nFrom the repository root, with the matching package installed, run the complete\nchecked-in [request example](examples/estimate-request.yaml):\n\n```bash\nagent-estimate estimate --spec examples/estimate-request.yaml --format json\n```\n\nThe JSON includes `\"schema_version\": \"agent-estimate/report/v1\"`, assigns\n`Add input validation` to `Codex`, and reports `forecast.basis: expected-wall`.\nThe example's 90-minute admission cap does not determine its expected minutes.\n`--spec` emits the versioned report; library callers can construct the separate\n`ForecastRecord` with `forecast_from_report` in `agent_estimate.contract.duration`.\n\n`--spec` accepts one full `EstimateRequest` containing `task_spec`,\n`execution_profile`, and `admission`, plus an optional `token_prior`. It can be\ncombined with `--config`, `--format`, `--compact`, and `--title`. Put task facts,\nscope, and modifiers in the request; alternate input sources and history flags\ncannot be combined with `--spec`. Conflicts and invalid fields exit 2. It does\nnot read ambient `data.json` history.\nThe named agent must exist in the selected fleet and satisfy every required\ncapability. `config_profile` records provenance; `--config` selects the actual\nfleet file. This single-task CLI path requires empty `dependency_task_ids` and\n`execution_profile.estimate_multiplier: 1.0`; use the configured agent's\n`estimate_multiplier` for [profile adjustments](#agent-fleet).\n\nContext identity belongs to `execution_profile.context.context_key`. An explicit\n`modifiers.warm_context` takes precedence: pairing it with\n`context.implicit_co_dispatch: true` is rejected to prevent double counting.\nReview intent is additive: supported plans are no review, one or two standard or\ncomplex rounds, or three standard rounds. Unsupported plans exit 2.\n\n**Expected values and caps.** Reports label duration `expected-wall`, with\n`source` and `as_of` provenance (an unknown date stays null). Expected wall minutes\ninclude work and additive review. Score matching actual wall minutes against\nindependent expected minutes, never `declared_cap_minutes` or a cap divided by\nguessed headroom. File expectations likewise come from task scope, not file caps.\nThe `validate` command uses `actual_total_minutes` for `expected-wall` observations\nand `actual_work_minutes` for `expected-work`; cap-only and cap-derived inputs are\nrejected. Wall scoring is report-only in the current calibration store. Legacy\n`estimated_minutes` means expected work only, and `calibrate --basis expected-work`\nis an explicit attestation that every stored estimate is expected work rather\nthan a cap; inspect the rows before using it. Without that attestation,\n`calibrate` exits 2 with guidance on stderr.\n\n**Token honesty.** Typed forecasts default to `tokens.basis: unavailable`, with\nnull `expected_tokens_total` and `expected_tokens_output`. Total means processed\ntokens including cache carry; output is a separate count included in total.\nA caller-supplied prior uses `basis: local-policy`, a source, date, population,\nand a mandatory population mismatch warning. An absent count stays unavailable;\nzero is a supplied count. These are not calibrated forecasts. JSON includes\n`forecast.tokens` only when a prior is supplied; Markdown then shows both slots\nand their provenance. There are **no packaged token priors or numeric rates**.\nSee the [explicitly uncalibrated rate-shape example](docs/token-forecast-priors.md#rate-shape-example-only--not-calibrated)\nfor caller-owned policy inputs.\n\nUpgrading configuration or JSON consumers? Read the\n[v0.8 migration notes](docs/migration-v0.8.md) for the two removed surfaces.\n\n## How It Works\n\nagent-estimate produces three-point [PERT](https://en.wikipedia.org/wiki/Program_evaluation_and_review_technique) estimates from agent-work priors, not human-duration estimates:\n\n- **Tier classification** — auto-sizes tasks XS→XL from complexity signals\n- **PERT math** — optimistic / most-likely / pessimistic, weighted to an expected value\n- **Human comparison** — a per-task-type multiplier, so you see the compression\n- **Reliability policies** — warns when friction-adjusted work exceeds a provenance-labeled model limit\n- **Wave planning** — schedules independent tasks in parallel across the fleet\n- **Review overhead** — models review cycles as additive cost (`standard`, `complex`, `3-round`)\n- **Modifiers** — `--spec-clarity`, `--warm-context`, `--agent-fit` tune the estimate\n\n### Task types\n\n| Type | Flag | Models |\n|------|------|--------|\n| Coding | (default) | Feature work, fixes, refactors |\n| Research | `--type research` | Audits, investigations, analysis |\n| Documentation | `--type documentation` | API docs, guides, changelogs |\n| Brainstorm | `--type brainstorm` | Ideation, spikes, design exploration |\n| Config/SRE | `--type config` | Deploys, infra, CI/CD |\n| Frontend/UI | `--type frontend` | Content patches vs. component builds |\n| App dev | `--type app_dev` | App shells, desktop/mobile builds |\n\n### Reliability policy defaults\n\n| Model | Work limit | Basis |\n|-------|------------|-------|\n| Opus 4.7 | 90 min | Local policy (unmeasured) |\n| GPT-5.5 | 90 min | Local policy (unmeasured) |\n| GPT-5.4 | 60 min | Local policy (unmeasured) |\n| Gemini 3.1 Pro | 45 min | Local policy (unmeasured) |\n| Sonnet 4.6 | 30 min | Local policy (unmeasured) |\n| Haiku 4.5 | 15 min | Local policy (unmeasured) |\n\nEvery row records `basis`, `source`, `source_version`, and `as_of` in `metr_thresholds.yaml`; the defaults above come from the agent-estimate v0.7.5 local-policy registry as of 2026-08-23. `opus_4_x` is a forward-compatible alias that resolves to the current Opus policy. Legacy keys (`opus_4_6`, GPT-5/5.2/5.3, Gemini 3 Pro, Sonnet) stay supported. The bundled thinking-level baseline is Claude Code high and Codex extra-high — shift with `--spec-clarity` and `--warm-context` for other setups.\n\n## Examples\n\nReal estimates from production use — including the misses.\n\n**The tool, estimating its own docs.** We sized this v0.7.0 skill-and-README refresh at ~30 minutes. It took 28.\n\n**An honest over-estimate.** We pre-registered a UI mockup build at ~95 minutes with no prior app-dev data. Two agents did it in parallel in 12 and 25 minutes — a 4–8x over-estimate. agent-estimate now ships an `app_dev` prior shaped by that result. The miss stays in the README because calibration means showing where you were wrong.\n\n**Three tasks, three agents, in parallel** — what the tool prints, including the reliability-policy flags. Input is the three-task `tasks.txt` from [`examples/multi-agent.md`](./examples/multi-agent.md); the output below is captured from a real run, trimmed to the timeline and warnings (the full report — per-task PERT table, wave plan, assumptions, and agent loads — is in that example):\n\n```text\n$ agent-estimate estimate --file tasks.txt\n\n## Timeline Summary\n\n| Metric | Value |\n| --- | --- |\n| Best case | 44.7m |\n| Expected case | 75.4m |\n| Worst case | 117.2m |\n| Human-speed equivalent | 473.1m |\n| Compression ratio | 6.28x |\n| Review overhead (per-task, pre-amortization) | 45m |\n\n## Reliability Horizon Warnings\n\n- **Add known_debt.md as standard protocol memory file**: Work estimate (60.4m) exceeds gpt_5_4 local reliability policy (unmeasured) (60m). Consider splitting the task.\n- **Write quickstart guide with protocol comparison table**: Work estimate (60.4m) exceeds gemini_3_1_pro local reliability policy (unmeasured) (45m). Consider splitting the task.\n```\n\n~75 minutes wall-clock versus the work-only human equivalent, at an estimated $3.51 fleet cost — plus policy flags when assigned work exceeds a model's configured limit, so you split it or add a checkpoint before dispatching. Human review is modeled separately. The same three tasks were later run by real agents; the retro is in the example file. More in [`examples/`](./examples/) — coding S/M, research, documentation, multi-agent.\n\n## Integrations\n\n### Claude Code plugin\n\n```\n/plugin marketplace add kiloloop/agent-estimate\n/plugin install agent-estimate@agent-estimate-marketplace\n```\n\n```\n/estimate Add a login page with OAuth\n/estimate --file spec.md\n/estimate --issues 1,2,3 --repo myorg/myrepo\n/estimate validate observation.yaml\n/estimate calibrate\n```\n\n### GitHub Action\n\nAvailable on the [GitHub Marketplace](https://github.com/marketplace/actions/agent-estimate):\n\n```yaml\n- uses: kiloloop/agent-estimate@v0\n  with:\n    issues: '11,12,14'\n```\n\nThe report goes wherever `output-mode` points: the job summary (`summary`, the default), a PR comment (`pr-comment`), an issue comment (`issue-comment`), or a step output for downstream steps (`step-output`) — combinable with `+` (e.g. `summary+pr-comment`).\n\nThe Action accepts GitHub issue input; it has no `spec` or token-prior input.\nThe [forecast contract](#v08-forecast-contract) describes the CLI's\n`--spec` path, expected-versus-cap scoring, and token provenance. The Action's\n`expected-minutes` output is expected wall time, not an admission cap.\n\n#### Permissions and comment identity\n\nGrant only the permissions required by the selected output modes:\n\n| Output mode | Required `permissions:` |\n|-------------|--------------------------|\n| `summary` | `issues: read` when issue input comes from a private repository |\n| `pr-comment` | `issues: read` when issue input comes from a private repository, plus `pull-requests: write` |\n| `issue-comment` | `issues: write` |\n| `step-output` | `issues: read` when issue input comes from a private repository |\n\nAdd `contents: read` only when the calling workflow uses `actions/checkout`; the Action itself does not require a checkout. Combined modes need the union of their rows.\n\nUse the default `${{ github.token }}` or a GitHub App installation token for\ncomment updates. The upsert filter selects only bot-authored comments with the\nAction's marker. A personal access token (PAT) posts as its human owner, so its\ncomments are never selected for later updates. Repeated PAT runs create new\ncomments when there is no matching bot-authored comment to update. Existing\nPAT-authored comments are never adopted, even by a later run using a bot token.\nGranting write permissions does not change the comment author's identity.\n\nBy default, the Action installs `agent-estimate` from its own checked-out\n`GITHUB_ACTION_PATH`, so the Python implementation stays coupled to the\n`uses:` ref. Set `version` only when you deliberately want a published package\nversion instead. Each run exposes the resolved `package-version` and\n`install-source`; Markdown reports repeat both values in their footer.\n\nOn offline self-hosted runners, allow the source install's isolated build\nenvironment to resolve `hatchling>=1.32,<2` and the package dependencies from a\nconfigured package index or cache. Merely checking out the Action does not\npre-provision the build backend used by pip's PEP 517 isolation.\n\n<details>\n<summary>Estimate on every PR</summary>\n\n```yaml\nname: Estimate\non:\n  pull_request:\n    types: [opened, synchronize]\n\npermissions:\n  contents: read\n  issues: read\n  pull-requests: write\n\njobs:\n  estimate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v7\n      - uses: kiloloop/agent-estimate@v0\n        with:\n          issues: '11,12,14'\n          output-mode: summary+pr-comment\n```\n\n</details>\n\n<details>\n<summary>Auto-estimate on label</summary>\n\nLabel an issue `estimate` and the Action posts or updates one marked estimate comment (the label match is exact and case-sensitive):\n\n```yaml\nname: Auto-estimate\non:\n  issues:\n    types: [labeled]\n\npermissions:\n  contents: read\n  issues: write\n\njobs:\n  estimate:\n    if: github.event.label.name == 'estimate'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: kiloloop/agent-estimate@v0\n        with:\n          issues: ${{ github.event.issue.number }}\n          output-mode: issue-comment\n          title: 'Agent Estimate — issue #${{ github.event.issue.number }}'\n```\n\nThis repo runs it on itself — see [`.github/workflows/auto-estimate.yml`](.github/workflows/auto-estimate.yml).\n\n</details>\n\n<details>\n<summary>Gate on the estimate (JSON step output)</summary>\n\nWith `format: json` the Action exposes `expected-minutes` as a step output — use it to gate or route downstream steps:\n\n```yaml\nname: Estimate gate\non:\n  issues:\n    types: [labeled]\n\npermissions:\n  issues: read\n\njobs:\n  gate:\n    if: github.event.label.name == 'estimate'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: kiloloop/agent-estimate@v0\n        id: estimate\n        with:\n          issues: ${{ github.event.issue.number }}\n          format: json\n          output-mode: step-output\n      - name: Flag oversized tasks\n        if: steps.estimate.outputs.expected-minutes != '' && fromJSON(steps.estimate.outputs.expected-minutes) > 120\n        env:\n          AE_MINUTES: ${{ steps.estimate.outputs.expected-minutes }}\n        run: echo \"::warning::Expected ${AE_MINUTES} min — consider splitting before dispatching an agent.\"\n```\n\nThe full JSON report is available as `steps.estimate.outputs.report` for custom processing.\nIts footer records `engine_version` and `registry_version`. Agent-load rows expose\nthe five-minute-turn estimate as `heuristic_cost`; consumers of the removed\n`estimated_cost` alias must use `heuristic_cost`.\n\n</details>\n\n<details>\n<summary>Action inputs and outputs</summary>\n\n| Input | Required | Default | Description |\n|-------|----------|---------|-------------|\n| `issues` | yes | — | GitHub issue numbers (comma-separated) |\n| `repo` | no | current repo | GitHub repo (owner/name) |\n| `format` | no | `markdown` | Output format: `markdown` or `json` |\n| `output-mode` | no | `summary` | `summary`, `pr-comment`, `issue-comment`, `step-output`, or a `+`-joined combo |\n| `config` | no | — | Path to agent config YAML |\n| `title` | no | `Agent Estimate Report` | Report title |\n| `review-mode` | no | `standard` | Review tier: `none`, `standard`, `complex`, `3-round` |\n| `spec-clarity` | no | `1.0` | Spec clarity modifier (0.3–1.3) |\n| `warm-context` | no | `1.0` | Warm context modifier (0.3–1.15) |\n| `agent-fit` | no | `1.0` | Agent fit modifier (0.9–1.2) |\n| `task-type` | no | — | Category: `coding`, `brainstorm`, `research`, `config`, `documentation`, `frontend`, `app_dev` |\n| `python-version` | no | `3.12` | Python version to use |\n| `version` | no | Action ref | Published `agent-estimate` version override |\n| `token` | no | `${{ github.token }}` | GitHub token |\n\n| Output | Description |\n|--------|-------------|\n| `report` | Full estimation report content |\n| `expected-minutes` | Expected minutes (when `format: json`) |\n| `package-version` | Resolved `agent-estimate` package version used by the run |\n| `install-source` | `action-path` by default, or `version-override` when `version` is set |\n\n</details>\n\n### Skill layout\n\nSkills follow the [oacp-skills](https://github.com/kiloloop/oacp-skills) convention:\n\n```\nskills/estimate/\n  skill.yaml            # machine-readable metadata\n  README.md             # human-readable docs\n  shared/INTENT.md      # shared intent across runtimes\n  claude/SKILL.md       # Claude Code skill definition\n  codex/SKILL.md        # Codex skill definition\n```\n\nBoth runtime slices cover the same CLI (`estimate`, `validate`, `calibrate`), phrased for their respective ecosystems.\n\n## Configuration\n\n### Agent fleet\n\nPass a config to model your own fleet:\n\n```yaml\nagents:\n  - name: Claude\n    capabilities: [planning, implementation, review]\n    parallelism: 2\n    cost_per_turn: 0.12\n    model_tier: frontier\n  - name: Codex\n    capabilities: [implementation, debugging, testing]\n    parallelism: 3\n    cost_per_turn: 0.08\n    model_tier: production\n    estimate_multiplier: 1.0\nsettings:\n  friction_multiplier: 1.15\n  inter_wave_overhead: 0.25\n  metr_fallback_threshold: 45.0\n```\n\nConfigs containing `settings.review_overhead` now exit 2 before model validation,\neven if its value is zero or null. Delete the key and select additive review\noverhead with `--review-mode` (or the request's review plan with `--spec`).\n\nEach agent's optional `estimate_multiplier` is a finite positive number, default\n`1.0`. The pipeline assigns tasks first, calls the assigned profile's\n`adjust_estimate` once per task, then scales work and its PERT range by the resulting\nfactor. It updates wave timing, reliability warnings and heuristic cost without\nreassigning tasks or scaling review overhead, inter-wave gaps, or human-equivalent\nwork. Structural profile plugins retain their own hook and replace same-name YAML\nprofiles; their result must be finite positive work (zero only for zero work).\nWhen an adjustment changes work, reports show the applied factor and the work\nminutes before and after adjustment.\n\nWith `--spec`, `task_spec.required_capabilities` must all be available on the named\nconfigured agent. An unsatisfiable requirement exits 2 instead of selecting another\nagent. Library callers can continue setting `TaskNode.required_capabilities` directly.\n\n```bash\nagent-estimate estimate \"Ship packaging flow\" --config ./my_agents.yaml\n```\n\n### Output formats\n\n```bash\nagent-estimate estimate \"Refactor auth pipeline\" --format json   # machine-readable\nagent-estimate estimate --repo myorg/myrepo --issues 11,12,14    # from GitHub issues\nagent-estimate estimate --file tasks.txt                          # from file\nagent-estimate estimate \"Follow-up fix\" --history-file data.json  # auto warm-context\n```\n\nWhen `--warm-context` is omitted, the CLI can auto-infer it from `--history-file`;\nif no history file is passed and `./data.json` exists, that file is used as the\ndefault dispatch history source.\n\n### Session estimates\n\nUse `agent-estimate session` for coordinated workflows where multiple agents run\nrounds of brainstorm, review, research, documentation, config, or coding work:\n\n```bash\nagent-estimate session --agents 3 --rounds 2 --type review\nagent-estimate session --agents 4 --rounds 1 --per-round-minutes 25 --format json\n```\n\nThe command reports wall-clock time, total agent-minutes, coordination overhead,\nand per-round breakdowns.\n\n### Calibration\n\nValidate estimates against observed outcomes and build a calibration database:\n\n```bash\nagent-estimate validate observation.yaml --db ~/.agent-estimate/calibration.db\n```\n\n## Project\n\n- **[Website](https://kiloloop.com/agent-estimate/)** — landing page, live demo, and the [estimate comparison view](https://kiloloop.com/agent-estimate/compare/).\n- **[OACP](https://github.com/kiloloop/oacp)** — coordinate the agents you just estimated. Open Agent Coordination Protocol for multi-agent async workflows.\n- **[oacp-skills](https://github.com/kiloloop/oacp-skills)** — the skill bundle agent-estimate's `/estimate` ships in.\n- **[kiloloop](https://github.com/kiloloop)** — the rest of the ecosystem.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for the full workflow.\n\n```bash\npip install -e '.[dev]'\nruff check .\npytest -q\n```\n\n## Community\n\n- [Code of Conduct](./CODE_OF_CONDUCT.md)\n- [Security Policy](./SECURITY.md)\n- [Support](./SUPPORT.md)\n- [Changelog](./CHANGELOG.md)\n\n## License\n\nApache License 2.0\n",
  "bytes": 23588,
  "sha": "c882ffd676f55c7e474d04d28dcc514c4c13b4c0f7a4032f4975d4cd59907e3d",
  "repo_slug": "haoranc/agent-estimate",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_haoranc_agent_estimate_agent_estimate_b36613b0/readme"
}