Releases: iPythoning/b2b-sdr-agent-template
WhatsApp Onboarding Spec v0.5 — Path D (PulseAgent Multi-Device fetch)
The lowest-friction history-acquisition path so far. Customer scans one fresh QR, waits for WhatsApp Multi-Device sync, then `bootstrap.sh` pulls the resulting .txt files directly from PulseAgent. Zero device backup, zero password, zero USB.
What changed
Added
- `scripts/fetch-from-pa.py` — Client-side downloader that calls PulseAgent's `/whatsapp/export-history` endpoint and unpacks the ZIP into `exports/`. Returns exit code 2 on 404 ("no history imported yet") so wrapper scripts can fall back to backup extraction.
- `bootstrap.sh` — Path B/C now offers a three-way choice: Path D / Auto (v0.4 backup extractor) / Manual. The Path D prompt prints an explicit 6-step prerequisite checklist including the unavoidable "wait 30 min – 6 hours" expectation so no client feels stalled mid-process.
- `docs/UPSTREAM-POLICY.md` — Frozen policy. PulseAgent has zero source-level coupling with upstream openclaw; cherry-pick rules only become necessary if that ever changes. Documents what the OpenClaw Release Routine is allowed to touch (marketing docs only, never customer-running code).
- `docs/CUSTOMER-DELIVERY-GUIDE.md` — Decision tree extended with Q2.5 (Path D eligibility check: SYNC_HISTORY=1, downtime tolerance, fresh-QR willingness, Device History setting).
Backend dependency
Path D requires a PulseAgent deployment with the companion PR merged (iPythoning/PulseAgent#135):
- `whatsapp_history_imports` table
- `POST /v1/relay/history-batch` (Bearer bridge token, idempotent via `UniqueConstraint`)
- `GET /whatsapp/export-history` (Bearer user token, ZIP response)
- whatsapp-relay must run with `SYNC_HISTORY=1`
Why Path D isn't the only path
WhatsApp Multi-Device sync only fires on a fresh QR scan. An already-linked device cannot retroactively backfill history even after `syncFullHistory: true` is set on the relay. So Path D = tear down + re-link = hours of downtime for any tenant whose AI is already running on WhatsApp.
Backup extraction (v0.4) stays the default for tenants who need zero-downtime onboarding. Path D shines for greenfield customers who haven't yet linked their account.
Decision matrix (when to use which)
| Scenario | Recommended path |
|---|---|
| Greenfield customer, comfortable with "wait several hours" | Path D |
| Tenant already running AI on WhatsApp (zero downtime required) | Path B/C (v0.4 backup) |
| Customer's iPhone has "Device History: Last 90 days" set | Path B/C (v0.4) — Path D won't pull more |
| Large account (10k+ messages) | Path B/C (v0.4) — Multi-Device sync is slow/flaky at scale |
| Small/medium account, no time pressure | Either works |
Test plan (before first paid Path D delivery)
- Stand up a tenant relay with `SYNC_HISTORY=1`
- `POST /qr-refresh`, scan QR with a test WhatsApp account
- Verify rows accumulating in `whatsapp_history_imports`
- Pull via `fetch-from-pa.py`, verify .txt format matches what `whatsapp-export-parser.py` expects
- Run end-to-end through profile extractor → miner → KB upload
- Tenant isolation test: confirm tenant A's export doesn't see tenant B's rows
Compatibility
Drop-in extension of v0.4. All prior paths (A/B/C + Auto/Manual) preserved. `fetch-from-pa.py` output is byte-compatible with v0.4 device-backup extractors so the downstream pipeline (parser → profile extractor → miner → upload) is unchanged regardless of source.
See `CHANGELOG.md` → 2026-05-22 v0.5 entry for full details.
WhatsApp Onboarding Spec v0.4 — Backup Extractors
Collapses three external tools (iMazing, adb, wa-crypt-tools UI) into one `bootstrap.sh` prompt sequence. The delivery engineer no longer has to walk the customer through a separate decryption step.
New extractors
-
`extract-ios-backup.py` — Reads an iOS encrypted local backup via `iphone_backup_decrypt`, pulls WhatsApp `ChatStorage.sqlite` out of the `AppDomainGroup-group.net.whatsapp.WhatsApp.shared` domain, schema-probes column names (iOS 16-18 column drift), emits one iOS-format `.txt` per 1-on-1 chat.
- Group chats skipped by default (`--include-groups` to override).
- Media replaced with `` markers; no media files exported.
- Apple Core Data epoch (2001-01-01 UTC) correctly offset.
-
`extract-android-backup.py` — Decrypts `msgstore.db.crypt15` via `wa-crypt-tools`, reads contacts from optional `wa.db`, emits Android-format `.txt`.
- Supports both modern `chat + jid` schema and legacy `chat_list` schema.
- 64-char hex key (from WhatsApp's "Reveal key" UI) required.
- Group chats skipped by default.
Dependency strategy
`requirements-extract.txt` is kept separate from the core `requirements.txt`. Layer-A-only customers (Business API path) never need to install `pycryptodome` / `cffi` and other crypto-native deps. `bootstrap.sh` installs them on-demand only when the customer chooses the "Auto" extraction branch.
Bootstrap flow update
```
Path B/C → "Extraction method?" prompt:
[1] Auto (use built-in extractor — recommended)
[2] Manual (I already have .txt files in exports/)
If Auto:
- Install requirements-extract.txt (one-time)
- iOS: prompt for backup dir + password → extract → exports/
- Android: prompt for crypt15 path + 64-char key → decrypt → exports/
If Manual:
- Same legacy prompt as v0.3
```
Implementation notes
- Schema probing over hardcoded SQL. WhatsApp DB schemas drift across versions (iOS 17+ renamed `ZTEXT` → `ZMESSAGETEXT`; Android added the modern `chat + jid` join table). Both extractors call `PRAGMA table_info` and pick the right column at runtime.
- No media extraction. We replace images / audio / video / documents with `` markers — the LLM pipeline downstream doesn't use media content, and not extracting saves 90% of disk + transfer time.
- iCloud backups out of scope. Need Apple keychain + iCloud auth, requires GUI tools (iMazing) or a private API approach.
Test plan (before first paid delivery)
- Run iOS extractor against your own iPhone encrypted backup
- Run Android extractor against a real `msgstore.db.crypt15`
- Confirm extracted `.txt` round-trips cleanly through `whatsapp-export-parser.py`
Compatibility
Drop-in extension of v0.3. Manual extraction path still works as fallback. No schema changes elsewhere.
See `CHANGELOG.md` → 2026-05-22 v0.4 entry for full details.
WhatsApp Onboarding Spec v0.3 — Layer B/C scripts + PA push
The v0.3 release closes the gap between a spec and a real end-to-end pipeline. `bootstrap.sh` now drives a complete customer delivery in one command — exports go in, MemOS-ready profiles + KB chunks come out, and (optionally) push to PulseAgent on the spot.
Pipeline at a glance
```
exports/.txt
→ parsed/.jsonl (PII-redacted turns)
→ profiles/.yaml Layer A — MemOS
→ golden/.yaml Layer B — sales_playbook (human review gate)
→ layer-c-chunks.jsonl Layer C — conversation_history
→ (optional) push to PulseAgent
```
New scripts
- `mine-golden-segments.py` — Two-pass Layer B miner.
- Pass 1: sliding-window keyword detection across five tag classes (deal_close / objection_resolved / dunning_recovered / relationship_warmup / cross_sell) in EN / ZH / ES
- Pass 2: Claude Haiku 4.5 scores each candidate 1-5, retags false positives, extracts 1-3 concrete tactical moves
- Drops anything < 3, emits YAML with `_human_reviewed: false` flag for the audit step
- `memos-upsert.py` — Posts `profiles/*.yaml` to PulseAgent `/api/memos/upsert`. Respects the strict `_auto_onboard` gate. `--force` for override, `--dry-run` to preview payloads.
- `bulk-embed.py` — Chunks `parsed/*.jsonl` into KB records (chunk_size + overlap configurable). Embedding is deliberately left to the PulseAgent backend so every tenant stays consistent. Two modes: emit JSONL for offline import or `--upload` to push directly.
Config
All three PA-talking scripts honor: CLI flags > `pa-config.json` (cwd or `~`) > `PA_*` env vars. See `samples/pa-config.example.json`.
Fixes
- Export parser MEDIA regex now eats outer `<>` around omitted-media markers — chunked text comes out clean.
- bulk-embed dropped a duplicated media tag in the chunked text body.
Self-test
Validated end-to-end on synthetic iOS + Android exports (`/tmp/wa-selftest`):
- Parser: 2 customers × 19 turns, PII redaction + session split + sender attribution all clean
- Miner: 4 candidate segments emitted dry-run (matches expectations)
- bulk-embed: 5 chunks from 19 turns at `chunk_size=6 overlap=2`
Compatibility
Drop-in extension of v0.2. No schema changes for parser, extractor, or customer profile format. New scripts honor the same salt and the same MemOS upsert convention used in earlier docs.
See `CHANGELOG.md` → 2026-05-21 v0.3 entry for the full list.
WhatsApp Onboarding Spec v0.2 — Customer Delivery Kit
Turns the v0.1 spec into a kit a delivery engineer can actually run on a paying customer in one afternoon.
What's new
One-command bootstrap
```bash
cd whatsapp-old-account-onboarding
bash scripts/bootstrap.sh
```
Interactive, re-runnable. Detects environment, generates a PII salt, asks scenario questions (Business API vs Business App vs personal; iOS vs Android), walks through the extraction path, runs parser + extractor, prints a verification report. State persists in `.bootstrap-state` so an interrupted run resumes cleanly.
Customer delivery guide
`docs/CUSTOMER-DELIVERY-GUIDE.md` (中文) covers:
- Expectation-alignment script — the exact paragraph to put in writing during sales so "WhatsApp Business API has zero history" never becomes a contract dispute
- A/B/C delivery decision tree — Business API customers get a different path from phone-based accounts
- Per-customer deliverables checklist
- Pricing reference points ($500 → $15,000+ tiers)
- Explicit out-of-scope list to prevent scope creep
The historical-data reality check
| Account type | Historical data | New messages |
|---|---|---|
| Business API | ❌ Zero — webhook only delivers post-connection messages | ✅ |
| Business App / Personal |
This is the single biggest pre-sales misconception. v0.2 surfaces it in three places (sales doc, kick-off guide, bootstrap output).
Compatibility
Drop-in extension of v0.1. No changes to parser, extractor, system prompt template, or KB schema.
Changelog
See `CHANGELOG.md` → 2026-05-21 v0.2 entry.
WhatsApp Legacy Account Onboarding Spec v0.1
First-party template extension for porting years of accumulated WhatsApp
B2B sales conversations into an AI Agent's customer memory + style + history.
Not an upstream OpenClaw cherry-pick — independent template add-on.
What's included
whatsapp-old-account-onboarding/
scripts/whatsapp-export-parser.py— iOS+Android dual-format parser for
WhatsApp.txtexports. One-way PII redaction (salted SHA-256), 24h-gap
session segmentation, media reference normalization.scripts/customer-profile-extractor.py— Claude Haiku 4.5 batch profile
extractor. Outputs YAML for MemOS upsert. Strict auto-onboard gate:
red_flagspresent /relationship_score < 6/unfinished_commitments > 2
→ manual review queue.docs/README.md— 8-step delivery SOP: prerequisites → export → parse →
extract → MemOS write → KB ingest → system prompt → pre-launch verification
→ shadow → whitelist → graduated rollout.docs/OpenClaw-knowledge-base-import.md— KB ingestion design for
sales_playbook(cross-customer style/tactics) andconversation_history
(per-customer, hard-isolated bycustomer_hash).docs/system-prompt-template.md— Production system prompt with three
legacy-account identity strategies (transparent / soft / impersonation) and
five pre-launch verification cases.samples/example-customer-profile.yaml— Reference MemOS document shape.docs/README.zh-CN.md— Simplified Chinese mirror of the SOP.
Three-layer architecture
| Layer | Teaches | Storage |
|---|---|---|
| A. Customer profile | Who they are, what they bought, what to avoid | MemOS |
| B. High-conversion playbook | Your style, your tactical moves | KB sales_playbook |
| C. Conversation history | What "last time" actually refers to | KB conversation_history |
Layer A alone delivers roughly 60% of the value if you need a one-week ship.
Safety highlights
- One-way PII salt — back it up; losing it makes customer hashes unreconcilable
- KB
customer_hashfilter enforced at the client layer, not the prompt
(prompt-injection cannot cause cross-customer leaks) - Strict auto-onboard gate routes 30-40% of customers to manual review
- Identity strategy defaults to "AI assistant for " — no full
impersonation (GDPR-safe)
Out of scope (follow-up)
bulk-embed.pyfor Layer C ingestion- MemOS upsert client (placeholder curl in README)
- ADB auto-export script for accounts > 200 customers
Changelog
See CHANGELOG.md → 2026-05-21 entry.
v3.6.0 — Graphify Knowledge Graph + Bilingual Opt-in
What's New
Graphify Knowledge Graph — Sales Intelligence
Integrated graphify for building queryable knowledge graphs from your sales data:
- Product catalog graph → cross-sell paths, product families, spec relationships
- Customer intelligence graph → buying patterns, referral paths, stalled lead recovery
- Market research graph → competitive landscape, expansion opportunities
- Runtime query:
python3 -m graphify query "topic"(BFS/DFS traversal) - Interactive HTML visualization for owner dashboard
- New skill:
skills/graphify/SKILL.md
Operator Bilingual Mode — Now Opt-in
Previously enabled by default, now requires operator_bilingual: true in IDENTITY.md. Prevents unexpected self-chat messages for operators who don't need Chinese translation.
Deploy Improvements
deploy.shauto-uploads all local skills fromskills/directorydeploy.shStep 3b: auto-installs Python3 + graphify on target server
Full Changelog: https://github.com/iPythoning/b2b-sdr-agent-template/blob/main/CHANGELOG.md
v3.4.0 — Operator Bilingual Mode
What's New
Operator Bilingual Mode
Non-English operators can now run a global English-facing SDR without reading English.
How it works:
- Customer sends any language → Agent always replies in English
- After each reply → Agent silently sends Chinese translation via WhatsApp self-chat
- Operator reads Chinese in "Message to myself" — customers only see English
- Owner reports (Pipeline, approvals, notifications) stay in Chinese
No hardcoded numbers, no extra config. Works out of the box with selfChatMode: true.
Files Changed
workspace/AGENTS.md— updated language strategyskills/sdr-humanizer/SKILL.md— bilingual language patternsSKILL.md— added Operator Bilingual Mode to key features
Full Changelog
See CHANGELOG.md
v3.5.0 — OpenClaw 2026.4.2 Compatibility
OpenClaw 2026.4.2 Compatibility
This release confirms full compatibility with OpenClaw 2026.4.2 and adds documentation for new 4.2 features.
Key Changes in OpenClaw 2026.4.2 (Relevant to B2B SDR)
Exec Security — Now Default
security=full with ask=off is now the default in OpenClaw 2026.4.2 core. The explicit exec-approvals.json configuration in deploy.sh is kept for forward-compatibility and clarity.
WhatsApp reactionLevel (New)
OpenClaw 2026.4.2 adds reactionLevel guidance for agent reactions. TOOLS.md now documents the three levels and B2B SDR recommendations:
"none"— default, no reactions"selective"— ✅ on confirmations, 👀 on new inquiries (recommended)"active"— react to all messages
Task Flow (Restored)
Background task orchestration is restored with managed-vs-mirrored sync modes. Useful for long-running lead nurture sequences. No action required — Task Flow is automatically available in 4.2.
No Breaking Changes
The B2B SDR template configuration (WhatsApp, Telegram, CRM, Anti-Amnesia) is fully compatible with 4.2. No migration steps required.
Upgrade
# Update template on existing deployment
curl -fsSL https://raw.githubusercontent.com/iPythoning/b2b-sdr-agent-template/main/install.sh | bashv3.3.1 — OpenClaw 2026.4.1 Compatibility
What's Changed
Fixes compatibility issues introduced by OpenClaw 2026.4.1 update:
Bug Fixes
- Exec approval timeout: Deploy now writes
exec-approvals.jsonwithsecurity=fulldefaults, preventing gateway approval timeouts that blocked all tool execution - Telegram DM blocking: Changed default
dmPolicyfrom"pairing"to"open"so new contacts can message the bot directly - Stale gateway token: Re-deploys now run
openclaw gateway install --forceto refresh embedded tokens
Config Additions
tools.profile: "full"added to generatedopenclaw.jsonallowFrom: ["*"]added to Telegram channel configexec-approvals.jsonauto-generated with full permissions during deploy
Upgrade Notes
For existing deployments, run:
# On your server:
openclaw gateway install --force
openclaw gateway restartOr re-deploy with ./deploy.sh <client-name> to apply all fixes automatically.
v3.3.0 — Dual-Threshold Compression & Memory Ranking
What's New
Cherry-picked 3 ideas from OpenViking Memory Plugin (no new dependencies, no new services).
1. Dual-Threshold Compression
- 50% (BACKGROUND_SAVE): Non-blocking extraction of key facts to ChromaDB — protects critical data early
- 65% (COMPRESS): Full L2 compression via haiku-class model (existing behavior, unchanged)
- Backward-compatible:
TOKEN_THRESHOLDexport still works
2. Recency-Weighted Search Ranking
Replaced simple word-count scoring with 3-factor ranking:
- Lexical overlap (normalized 0-1) × 0.5
- Recency decay (30-day half-life, floor 0.5) × 0.3
- Tag boost (order +0.12, quote +0.10, commitment +0.10, objection +0.08)
Also fixed bug: score + 0.5 was a no-op (not assigned back).
3. Archive Expand Command
chroma:expand <turn_id>
View full original text of any compressed/archived turn by ID.
Config Change
softThresholdTokens: 12000 → 10000 (earlier flush hook trigger for dual-threshold)
Files Changed
| File | Change |
|---|---|
scripts/proactive-summary.mjs |
Dual-threshold logic |
skills/chroma-memory/chroma.mjs |
Ranking + expand + bugfix |
workspace/MEMORY.md |
Updated architecture docs |