outbound-sales-agent
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Agent-operated outbound sales engine: LinkedIn + email cadence, two-stage ICP qualifier, learning loop. CRM-agnostic (Attio bundled, adapters generated + conformance-tested). Clone it and let your AI agent onboard you.
outbound-sales-agent
A CRM-agnostic, config-driven autonomous outbound engine extracted from a
production B2B sales system. It runs a staged LinkedIn + email cadence against
your pipeline, qualifies prospects through a two-stage ICP scorer (deterministic
keyword rules + an LLM tiebreaker), and feeds a learning loop that surfaces
response patterns back into ICP tuning. You stand it up against your CRM,
PhantomBuster account, and ICP — the engine's math and cadence logic stay
unchanged.
First time here? Point an AI coding agent at this repo — it reads
AGENTS.md and drives the setup for you. Prefer doing it by
hand? Follow the Getting Started guide.
Quick start (with an AI agent — recommended)
This repo is built to be set up by an AI coding agent. Clone it, open your
agent in the repo root, and ask it to onboard you:
git clone https://github.com/mat-lucie/outbound-agent.git
cd outbound-agent
claude # or any agent that reads AGENTS.md
"Run the /onboard skill and set this up for my CRM and ICP."
The agent reads AGENTS.md automatically, follows the /onboard
interview (skills/onboard/SKILL.md), and walks you from fresh clone to a
safe --dry-run. It interviews you about your CRM, PhantomBuster account,
and ICP — and for a non-Attio CRM it generates the adapter and proves it
against the conformance suite.
Quick start (manual)
git clone https://github.com/mat-lucie/outbound-agent.git
cd outbound-agent
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e '.[dev]'
Then follow GETTING_STARTED.md — fresh clone to your
first safe dry-run in ~60–90 minutes.
Either path produces:
| Output | What it is |
|---|---|
config/crm.yaml |
CRM vendor + credential env-var references |
config/phantombuster.yaml |
PhantomBuster phantom IDs + degree-check backend |
config/icp.yaml |
Your ICP: keywords, weights, thresholds, LLM prompt slots |
.env |
Secrets (API keys, LinkedIn cookies) — never committed |
clients/crm/<vendor>_provider.py |
Generated adapter (non-Attio CRMs only) |
Config model
Every config file has a committed example template (config/*.example.yaml)
and a git-ignored live copy (config/*.yaml). To configure manually without
the onboard skill:
cp config/crm.example.yaml config/crm.yaml
cp config/icp.example.yaml config/icp.yaml
cp config/phantombuster.example.yaml config/phantombuster.yaml
Edit each live copy with your values. Secrets stay in .env — the YAML
files store the name of the environment variable, never the value itself:
# config/crm.yaml
credentials:
api_key_env: ATTIO_API_KEY # ← env var name, not the secret
To override the config directory (e.g. for multi-instance setups):
OUTBOUND_CONFIG_DIR=/path/to/your/config sales daily
See config/README.md for the full convention.
Architecture
PhantomBuster phantoms
└── LinkedIn invites + DMs + inbox scraping
│
▼
outbound-agent CLI (python cli.py / sales <command>)
│
┌────┴───────────────────────────────────┐
│ ICP qualifier (config/icp.yaml) │
│ stage 1: deterministic keyword score │
│ stage 2: LLM tiebreaker │
│ (config/prompts/qualifier.md.j2) │
└────┬───────────────────────────────────┘
│
┌────┴──────────────────┐
│ CRMProvider contract │ clients/crm/base.py
│ (vendor-neutral) │ clients/crm/CONTRACT.md
└────┬──────────────────┘
│
┌────┴──────────────────┐
│ Adapter │ Attio: clients/crm/attio_provider.py
│ (one per vendor) │ Other CRMs: generated by /onboard
└───────────────────────┘
│
conformance gate: tests/crm/test_provider_contract.py
CRM seam. The CRMProvider abstract base (clients/crm/base.py) defines
the method contract. clients/crm/CONTRACT.md documents every method, the
normalized return types (Record, Entry, Stage, RecordInfo), and the
known limitations. The conformance suite (tests/crm/test_provider_contract.py)
is the adapter bar: a generated adapter is "correct" iff it is green here.
Attio is the bundled reference adapter; other CRMs are generated by the/onboard skill and proven against the suite.
ICP qualifier. Scoring math lives in workflows/quality_gate.py and is
unchanged by your configuration — only the source data moves intoconfig/icp.yaml. The LLM tiebreaker system prompt is templated viaconfig/prompts/qualifier.md.j2; your ICP narrative slots (product_summary,geography_requirement, lanes, disqualifiers) render into it while the
JSON output contract stays engine-owned.
PhantomBuster. Six phantoms handle the LinkedIn automation (invite,
message, inbox scrape, degree-check). Non-secret IDs live inconfig/phantombuster.yaml; secrets (API key, cookies) stay in .env. First-
time setup: docs/onboarding/phantombuster-setup.md.
Secrets gate. scripts/check_no_secrets.py scans the repo tree for known
secret-value patterns. It runs as a pytest target and can be used as a
pre-commit hook.
Running the engine
The CLI entry point is installed as sales (or run directly withpython cli.py). Key commands:
| Command | What it does |
|---|---|
sales daily |
Daily cadence: invite new prospects (Part A) + send DMs to 1st-degree connections (Part B). Add --dry-run to print what would happen without sending. |
sales weekly |
Weekly prospecting: export new profiles from Sales Navigator, score against ICP, add passing prospects to the pipeline. |
sales report |
Print (or email) a pipeline summary. |
sales learn |
Learning loop: analyse response patterns, surface ICP signal. |
sales pipeline |
Print live pipeline state. |
sales check-responses |
Detect replies and advance stages. |
sales health-check |
Verify CRM + PhantomBuster connectivity. |
sales backfill-export |
Export the current pipeline to CSV. |
sales weekly-finalize |
Finalize a weekly batch: score + enrich + push to CRM. |
sales sales-approve |
Operator review queue: approve/reject borderline prospects. |
Run sales --help or sales <command> --help for all flags.
To verify the suite is green:
python -m pytest -q
Expected: all tests pass (3,400+ passed, ~15 skipped, 0 failed).
Bring your own CRM
Attio is the bundled reference adapter. Other CRMs are generated by the/onboard skill, which:
- Interviews you about your CRM's API shape.
- Generates
clients/crm/<vendor>_provider.pyagainst the contract
(usingclients/crm/fake_provider.pyas the structural template andclients/crm/attio_provider.pyas a worked example of vendor-JSON
normalization). - Registers the new adapter in
clients/crm/factory.py. - Iterates until
tests/crm/test_provider_contract.pyis green.
Read clients/crm/CONTRACT.md for the full method map, normalized types, and
known limitations before generating an adapter. The conformance suite
(tests/crm/test_provider_contract.py) is the definitive adapter bar.
This is proven: the onboarding agent has successfully generated a passing
adapter for a Pipedrive-shaped CRM.
Reference operator: examples/acme/
examples/acme/ is a fully synthetic reference operator (a fictional
B2B SaaS company): a worked example of a complete config + content set —
ICP definition, personas, message/email sequences, target list — with
fabricated data and no real business intelligence. It is not loaded at
runtime; the test suite pins to it. Replace the shipped repo-rootcontent/ and sales-program.md with your own before running in
production; see the known limitations.
Known limitations
See docs/LIMITATIONS.md for a full list of current
edges, especially:
config/crm.yaml'sfield_mapping/stage_mappingare now consumed; two
residuals remain — thestage_fieldslug is still fixed tostage, and a
renamedlinkedin_urlslug covers reads but not the person-upsert write path.- The filter DSL passed to
query_object_recordsis Attio-native, so a non-Attio
adapter must translate it (the conformance suite only tests flat equality). - The write path (
AttioWriter) is not yet fully behind the vendor-neutral seam;
a handful of workflows still reach the inner Attio client via an escape hatch. - Email and Google Sheets export are not yet abstracted behind a provider. The
email path is now compliance-capable (suppression on send,List-Unsubscribe
mailto header, CAN-SPAM footer + a fail-loud postal-address gate, opt-out CLI),
but you must configure and operate it — see COMPLIANCE.md.
Requirements
- Python 3.11+
- PhantomBuster account (paid plan with the six phantoms above)
- A CRM with an API (Attio bundled; others via
/onboard) - LinkedIn account (regular seat; Sales Navigator optional for the
sales_navdegree-check backend)
Contributing & security
- CONTRIBUTING.md — local setup, the quality gates, and
how to add a CRM adapter via theCRMProviderconformance suite. - SECURITY.md — how to report a vulnerability and how secrets
are kept out of the repo. - COMPLIANCE.md — LinkedIn-ToS and CAN-SPAM/GDPR posture,
what the engine enforces, and what you must operate yourself.
License
MIT — see LICENSE.
Automating LinkedIn outreach can violate LinkedIn's Terms of Service, and cold
email is regulated (CAN-SPAM, GDPR, and local law). You are solely responsible
for how you use this software. Read COMPLIANCE.md and the
safety notes in GETTING_STARTED.md
before sending.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi