Metadata-Version: 2.4
Name: personanexus-agentforge
Version: 0.2.2
Summary: Transform job descriptions into deployable AI agent blueprints via PersonaNexus
Project-URL: Homepage, https://github.com/PersonaNexus/agentforge
Project-URL: Documentation, https://github.com/PersonaNexus/agentforge#readme
Project-URL: Repository, https://github.com/PersonaNexus/agentforge
Project-URL: PersonaNexus, https://github.com/PersonaNexus/personanexus
Project-URL: Bug Tracker, https://github.com/PersonaNexus/agentforge/issues
Author: AgentForge Contributors
License: MIT
License-File: LICENSE
Keywords: agent,agentforge,ai,job-description,personanexus,skills
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: anthropic<1.0,>=0.40
Requires-Dist: openai<3.0,>=2.0
Requires-Dist: personanexus<2.0,>=1.4
Requires-Dist: pydantic<3.0,>=2.0
Requires-Dist: pymupdf<2.0,>=1.24
Requires-Dist: python-docx<2.0,>=1.0
Requires-Dist: pyyaml<7.0,>=6.0.1
Requires-Dist: rich<14.0,>=13.0
Requires-Dist: typer<1.0,>=0.9
Provides-Extra: langgraph
Requires-Dist: langchain-anthropic<1.0,>=0.3; extra == 'langgraph'
Requires-Dist: langchain-core<1.0,>=0.3; extra == 'langgraph'
Requires-Dist: langgraph<1.0,>=0.2; extra == 'langgraph'
Provides-Extra: mcp
Requires-Dist: mcp<2.0,>=1.0; extra == 'mcp'
Provides-Extra: web
Requires-Dist: alembic<2.0,>=1.13; extra == 'web'
Requires-Dist: fastapi<1.0,>=0.115; extra == 'web'
Requires-Dist: python-multipart>=0.0.9; extra == 'web'
Requires-Dist: sqlalchemy<3.0,>=2.0; extra == 'web'
Requires-Dist: uvicorn[standard]<1.0,>=0.30; extra == 'web'
Description-Content-Type: text/markdown

# AgentForge

> **Repo/Product map:** AgentForge is the product, Python package, and CLI (`agentforge`). The public GitHub repository is [`PersonaNexus/agentforge`](https://github.com/PersonaNexus/agentforge). It was formerly named `AgentSkillFactory`; GitHub redirects old links. See [docs/repo-product-map.md](docs/repo-product-map.md) for the ecosystem map and naming policy.

**v0.2.0** — Transform job descriptions, role descriptions, and operating context into deployable AI agent blueprints via [PersonaNexus](https://github.com/PersonaNexus/personanexus) — and keep them healthy after they ship.

AgentForge reads a job description (txt, md, pdf, docx), extracts skills and role metadata with an LLM, maps them to [PersonaNexus](https://github.com/PersonaNexus/personanexus) personality traits, and outputs a ready-to-use agent identity — including Claude Code skill folders you can drop straight into `.claude/skills/`.

Beyond the one-shot factory, AgentForge ships a **day-2+ tooling line** for the lifecycle that starts after the agent is live: persona drift detection, skill-folder maintenance, multi-agent team synthesis, and JD-corpus observability. See [Day-2+ tooling](#day-2-tooling) below or the [full design doc](docs/day2-products.md).

### PersonaNexus Ecosystem

| Project | Role |
|---------|------|
| [**PersonaNexus**](https://github.com/PersonaNexus/personanexus) | Declarative identity spec — defines *who* an agent is: schema, traits, guardrails, communication style, teams, and evaluation |
| **AgentForge** (this repo) | The factory — *builds operational agents and skills* from job descriptions, role requirements, and team context |
| [**Voice Packs**](https://github.com/PersonaNexus/voice-packs) | Weight-level personality — LoRA adapters that encode authorial voice into model weights ([adapters on HuggingFace](https://huggingface.co/jcrowan3/voice-pack-adapters)) |

Think of PersonaNexus as the schema, AgentForge as the factory, and Voice Packs as the voice.

## Install

PyPI distribution name is **`personanexus-agentforge`** (the bare name `agentforge` is
an unrelated project). The **CLI and import stay `agentforge`**.

```bash
pip install personanexus-agentforge            # core CLI
pip install "personanexus-agentforge[web]"     # adds REST API + web UI
```

Or from source:

```bash
git clone https://github.com/PersonaNexus/agentforge.git
cd agentforge
pip install -e ".[web]"
```

Set an API key:

```bash
export ANTHROPIC_API_KEY=sk-ant-...
# or
export OPENAI_API_KEY=sk-...
```


## Hero path

The shortest path from a job description to a deployable, checked skill:

```bash
pip install "personanexus-agentforge[web]"   # or: uv sync --extra web
export ANTHROPIC_API_KEY=sk-ant-...   # or OPENAI_API_KEY

agentforge forge job_posting.txt -d ./out --skill-folder --check --check-strict
# (or run check separately)
agentforge check ./out/*/SKILL.md --domain "your domain" --strict
agentforge identity validate ./out/*.yaml

# Optional day-2 once the agent is live:
agentforge drill ingest ./out/<skill-folder>
agentforge drill scan ./out/<skill-folder>
agentforge drill propose ./out/<skill-folder>
agentforge drill apply ./out/<skill-folder> --yes --only prune_tools
```

Copy the skill folder into `.claude/skills/` (or your OpenClaw/PersonaNexus deploy path).
See [examples/senior-data-engineer](examples/senior-data-engineer/README.md) for a sanitized golden package.

## Full command reference (advanced)

> Most users only need the **hero path** above. The commands below are for batch/team/day-2/power users.


```bash
# Interactive wizard — guided experience for all commands
agentforge wizard

# Extract skills from a job description
agentforge extract job_posting.txt

# Full pipeline — identity YAML + skill folder + gap analysis
agentforge forge job_posting.txt

# Quick mode (skip culture/mapping/gap analysis)
agentforge forge job_posting.txt --quick

# Deep analysis with per-skill scoring
agentforge forge job_posting.txt --deep

# Batch-process a directory of JDs
agentforge batch ./job_descriptions/ -d ./agents --parallel 4

# Forge a multi-agent team with conductor
agentforge team job_posting.txt -d ./team-output

# Test a forged skill against generated scenarios
agentforge test job_posting.txt

# One-shot quality gate (lint + size + audit)
agentforge check output/SKILL.md
agentforge check .claude/skills/my-agent --identity identity.yaml

# Validate a PersonaNexus identity YAML
agentforge identity validate identity.yaml
```

## Examples & showcase

Public example package (sanitized):

- [Senior Data Engineer example](examples/senior-data-engineer/README.md)

![AgentForge example demo](docs/assets/agentforge-example-demo.gif)

Reproduce the checked-in example artifacts locally:

```bash
uv sync --dev
uv run python scripts/generate_example_artifacts.py
```

Want to add your own example? Use the showcase contribution path:

- [Examples & Showcase guide](docs/showcase.md)

## Python API

```python
from agentforge import LLMClient, SkillExtractor, ForgePipeline, JobDescription

# Extract skills
client = LLMClient(model="claude-sonnet-4-20250514")
extractor = SkillExtractor(client=client)
jd = JobDescription.from_file("job_posting.txt")
result = extractor.extract(jd)

print(result.role.title)
for skill in result.skills:
    print(f"  {skill.name} ({skill.category.value})")

# Full pipeline
pipeline = ForgePipeline.default()
context = pipeline.run({"input_path": "job_posting.txt", "llm_client": client})
print(context["identity_yaml"])
```

## REST API

```bash
agentforge serve                     # http://localhost:8000 (loopback; auth optional)
# Non-loopback binds require a token:
export AGENTFORGE_API_TOKEN=$(openssl rand -hex 32)
agentforge serve --host 0.0.0.0 --no-open
```

Key endpoints:

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/api/extract` | Synchronous skill extraction |
| `POST` | `/api/forge` | Async forge job (returns `job_id`) |
| `GET` | `/api/forge/{job_id}/stream` | SSE progress stream |
| `GET` | `/api/forge/{job_id}/result` | Final result |
| `POST` | `/api/batch` | Batch processing |
| `GET` | `/health` | Health check |
| `GET` | `/api/docs` | OpenAPI / Swagger UI |

## Docker

```bash
export AGENTFORGE_API_TOKEN=$(openssl rand -hex 32)
export ANTHROPIC_API_KEY=sk-ant-...
docker compose up                    # builds and starts on :8000
```

Or build manually:

```bash
docker build -t agentforge .
docker run -p 8000:8000 \
  -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY \
  -e AGENTFORGE_API_TOKEN=$AGENTFORGE_API_TOKEN \
  agentforge
```

See [SECURITY.md](SECURITY.md) for auth defaults.

## MCP Server (agent-to-agent)

AgentForge ships an [MCP](https://modelcontextprotocol.io/) server so other agents (Claude Code, etc.) can call it as a tool.

### Add to Claude Code

In your project's `.mcp.json` or `~/.claude/mcp.json`:

```json
{
  "mcpServers": {
    "agentforge": {
      "command": "python",
      "args": ["-m", "agentforge.mcp_server"]
    }
  }
}
```

### Available tools

| Tool | Description |
|------|-------------|
| `agentforge_extract` | Extract skills/role/traits from job description text |
| `agentforge_forge` | Full pipeline — returns identity YAML, skill folder, gap analysis |
| `agentforge_forge_file` | Same as forge but reads from a file path on disk |

### Run standalone

```bash
python -m agentforge.mcp_server      # stdio transport
```

## Multi-agent teams

Forge a complete agent team from a single JD — each teammate gets a scoped skill, and a conductor agent handles routing and handoffs:

```bash
agentforge team job_posting.txt -d ./team-output
```

Outputs: conductor skill, per-teammate skills, identity YAMLs, and `orchestration.yaml`.

### LangGraph export

Export the team as a runnable LangGraph `StateGraph`:

```bash
agentforge team job_posting.txt -d ./team-output --format langgraph

# Or get both Claude Code skills and LangGraph module
agentforge team job_posting.txt --format both
```

Produces `agent_graph.py` — a self-contained Python module with typed state, agent nodes, conductor routing, and a compiled graph. Requires `pip install "personanexus-agentforge[langgraph]"`.

## Skill testing

Validate a forged skill by running it against auto-generated test scenarios:

```bash
agentforge test job_posting.txt
```

Generates scenarios from trigger mappings, responsibilities, and edge cases. Evaluates responses with LLM-as-judge scoring and produces a pass/fail report.

## Day-2+ tooling

The one-shot `forge` flow stops after the agent ships. Day-2+ commands keep agents and skill folders healthy over time, on a single operating model: **observe → diagnose → propose → test → version**. All four products are deterministic by default; LLM is reserved for experimentation and proposal surfaces.

### `tend` — persona maintenance

Read-only on `SOUL.md`. Snapshots persona artifacts, diffs them, and runs A/B tests against scenario sets with LLM-as-judge.

```bash
agentforge tend ingest <agent-dir>             # snapshot persona artifacts
agentforge tend watch <agent-dir>              # diff snapshots, surface drift + promotion candidates
agentforge tend ab <agent-dir> -v variant.md   # A/B test a SOUL variant on scenarios
agentforge tend version <agent-dir>            # SOUL evolution log (versions.jsonl)
```

All output goes to `<agent>/.tend/`. Snapshots are deterministic — re-ingesting an unchanged agent produces an identical-modulo-timestamp snapshot.

### `drill` — skill-folder maintenance

Counterpart to Tend on the *capability* surface. Auto-detects single-skill folders vs `.claude/skills/`-shaped parents.

```bash
agentforge drill ingest <skill-dir>     # snapshot a skill directory
agentforge drill scan <skill-dir>       # deterministic diagnostics
agentforge drill watch <skill-dir>      # diff snapshots
agentforge drill version <skill-dir>    # inventory evolution log
agentforge drill propose <skill-dir>   # deterministic maintenance plan from scan
```

`drill scan` flags four classes of issue: **missing_file** (folder lacks SKILL.md), **broken_reference** (body cites a path that's not on disk), **bloat** (body word count above threshold), **overlap** (Jaccard similarity between two skill descriptions above threshold), **tool_sprawl** (`allowed-tools` count above threshold or stale entries not mentioned in body). Thresholds are configurable per-run.

### `department` — multi-agent team synthesis

Synthesize a coordinated team from a folder of JDs (one per role, with YAML frontmatter).

```bash
agentforge department scan <jd-folder>          # list the corpus, no LLM
agentforge department analyze <jd-folder>       # extract + cluster skills, write report
agentforge department synthesize <jd-folder> -o <out>            # full team
agentforge department synthesize <jd-folder> -o <out> --use-llm  # + LLM handoff judge + team brief
```

`synthesize` produces per-role identity + decomposed SKILL.md, an `_shared/skills/` library for clusters spanning ≥2 roles, an `_conductor/` agent with a baked-in routing table, an `orchestration.yaml` handoff graph, and a README. With `--use-llm` the handoff edges are LLM-judged and the README gains a written team brief.

### `market` — JD-corpus observability

Aggregate statistics over a JD corpus + agent ↔ market gap analysis.

```bash
agentforge market trends <jd-folder>                                   # top skills, breakdowns, recency split
agentforge market gap <jd-folder> --skill-dir <agent-skills>           # coverage score + market_only / agent_only / shared
agentforge market propose <jd-folder> --skill-dir <agent-skills>       # deterministic coverage proposals from gap
```

`trends` surfaces top skills by frequency and role-share, breakdowns by category / domain / seniority, and a rising-vs-falling skills split when JDs carry `date:` frontmatter. `gap` compares an agent's drill SkillInventory to the corpus's clustered SkillLandscape and emits a coverage score over load-bearing market skills.

### Shared substrate

All four products ride on `agentforge.day2/` — a thin shared package for git-state probes, JSONL evolution logs, frontmatter parsing, finding-list markdown, CLI directory validation, and size-capped + symlink-safe file IO. Designed so future day-2+ products reuse it instead of mirroring helpers.

## Quality & safety tools

Analyze, lint, and validate generated skills:

```bash
# Recommended: one-shot gate (lint + size + audit)
agentforge check output/SKILL.md
agentforge check .claude/skills/my-agent --identity identity.yaml
agentforge check output/SKILL.md --strict --format json   # CI-hard (fails incomplete audits)

# Individual tools
agentforge prompt-size output/SKILL.md
agentforge lint output/SKILL.md
agentforge audit output/SKILL.md --domain "data engineering"
agentforge audit output/SKILL.md --fix --output fixed_SKILL.md
agentforge cost output/SKILL.md --daily-calls 100
agentforge prompt-diff v1/SKILL.md v2/SKILL.md

# Validate PersonaNexus identity YAML only
agentforge identity validate identity.yaml
```

All quality commands support `--format json` for CI integration and return exit code 1 on failure.

Programmatic gate:

```python
from pathlib import Path
from agentforge.analysis.skill_check import SkillChecker, validate_identity_yaml

report = SkillChecker(domain="data engineering").check_paths(Path("SKILL.md"), strict=True)
assert report.passed
ok, msg = validate_identity_yaml(Path("identity.yaml").read_text())
```

## Telemetry & observability

**Default: off.** No metrics files, no network.

Opt into **local** JSONL stage timings (no JD/skill content, no remote export):

```bash
export AGENTFORGE_TELEMETRY_MODE=local
# optional override:
export AGENTFORGE_TELEMETRY_DIR=~/.agentforge/telemetry

agentforge forge job_posting.txt
# → ~/.agentforge/telemetry/events-YYYY-MM-DD.jsonl
```

Pipeline events: `pipeline_start`, per-`stage` (`ok`/`error`/`skipped` + `duration_ms`), `pipeline_end`, and `llm_usage` (token counts when the LLM client is used).
Full design: [docs/telemetry-design.md](docs/telemetry-design.md). Security notes: [SECURITY.md](SECURITY.md).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, gates, and PR expectations.

## Development quality gates

CI runs two jobs:

| Job | What it does |
|-----|----------------|
| **Core** | `uv sync --dev`, full pytest with coverage floor **60%**, Ruff E/F on package, full Ruff on hardened modules, mypy on core modules, package build |
| **Web** | `uv sync --dev --extra web`, `pytest -m web` |

Run the same locally:

```bash
uv sync --dev
uv run pytest -q --cov=agentforge --cov-fail-under=60
uv run ruff check src/agentforge tests --select E,F --ignore E501
uv sync --dev --extra web && uv run pytest -q -m web
uv run --with build python -m build
```

Golden tests lock the public [senior-data-engineer example](examples/senior-data-engineer/README.md) (PersonaNexus identity + skill folder layout + deployment package) **without** live LLM calls.

## Wiki-memory (structured knowledge layer)

Durable, cross-linked knowledge alongside episodic memory. Prefer the main CLI:

```bash
agentforge wiki init --root ~/wiki
agentforge wiki add --title "AI Gateway" --type entity --kind project \
  --fact "Runs on port 8900" --source session:2026-04-04 --root ~/wiki
agentforge wiki candidate --subject "AI Gateway" --claim "Uses Gemma 4 E4B" \
  --type entity --kind project --source session:2026-04-04 --root ~/wiki
agentforge wiki pending --root ~/wiki
agentforge wiki list --root ~/wiki
agentforge wiki promote --accept-all --root ~/wiki
```

(The module entrypoint `python -m agentforge.wiki_memory.cli …` still works.)

**Key features:**
- **Capture → candidate → review → promote** funnel (no silent writes)
- **3-tier entity resolver** (slug → alias → title substring)
- **Provenance on every fact** (source, confidence, date)
- **Exact-dedupe** on claim text, confidence roll-up
- Filesystem-backed markdown with YAML frontmatter
- Audit trail of all review decisions

See `docs/wiki-memory-design.md` for the full design.

## Non-JD input sources

Enrich skills with context beyond the job description:

```bash
# Supplement a forge with Slack history, git logs, runbooks, or meeting notes
agentforge forge job.txt --supplement slack_export.zip --supplement runbook.md
```

Supported sources: Slack JSON exports, git log output, runbook/SOP markdown, meeting notes. Each parser extracts decision patterns, recurring workflows, and domain context that gets merged into the methodology layer.

## Project structure

```
src/agentforge/
├── cli.py                  # Typer CLI (forge + day-2+ sub-apps)
├── cli_wizard.py           # Interactive wizard
├── mcp_server.py           # MCP tool server
├── extraction/             # LLM-powered skill extraction
├── generation/             # Identity & skill file generation
├── ingestion/              # PDF, DOCX, text + Slack, git, runbook, meeting notes
├── llm/                    # LLM client (Anthropic + OpenAI)
├── mapping/                # Skill-to-trait mapping, culture
├── models/                 # Pydantic data models
├── pipeline/               # Composable forge pipeline
├── analysis/               # Gap analysis, skill review, guardrails, linting, cost, prompt size
├── composition/            # Multi-agent team forging, conductor generation
├── testing/                # Skill validation, scenario generation, evaluation
├── corpus/                 # JD-corpus loader (shared by department + market)
├── tend/                   # Day-2+ persona maintenance
├── drill/                  # Day-2+ skill-folder maintenance
├── department/             # Day-2+ multi-agent team synthesis from JD corpus
├── market/                 # Day-2+ JD-corpus observability + agent gap
├── day2/                   # Shared substrate for tend/drill/department/market
├── web/                    # FastAPI app, routes, templates
└── templates/              # Culture templates, prompts
```

## License

MIT — see [LICENSE](LICENSE).
