outbound-sales-agent

agent
Guvenlik Denetimi
Uyari
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.

SUMMARY

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.

README.md

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 into
config/icp.yaml. The LLM tiebreaker system prompt is templated via
config/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 in
config/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 with
python 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:

  1. Interviews you about your CRM's API shape.
  2. Generates clients/crm/<vendor>_provider.py against the contract
    (using clients/crm/fake_provider.py as the structural template and
    clients/crm/attio_provider.py as a worked example of vendor-JSON
    normalization).
  3. Registers the new adapter in clients/crm/factory.py.
  4. Iterates until tests/crm/test_provider_contract.py is 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-root
content/ 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's field_mapping / stage_mapping are now consumed; two
    residuals remain — the stage_field slug is still fixed to stage, and a
    renamed linkedin_url slug covers reads but not the person-upsert write path.
  • The filter DSL passed to query_object_records is 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_nav degree-check backend)

Contributing & security

  • CONTRIBUTING.md — local setup, the quality gates, and
    how to add a CRM adapter via the CRMProvider conformance 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)

Sonuc bulunamadi