@agenticmail/core 0.9.23 → 0.9.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,109 @@
1
+ {
2
+ "id": "handle-debt-collector",
3
+ "name": "Handle a Debt Collector Call (US-FDCPA-aware)",
4
+ "version": "1.0.0",
5
+ "category": "debt-collection",
6
+ "tags": ["debt", "collection", "FDCPA", "legal", "consumer-protection"],
7
+ "description": "Field a call from a debt collector on the operator's behalf without acknowledging the debt, request written validation per FDCPA, and end the call cleanly. US-specific.",
8
+ "disclaimer": "I am an AI assistant calling on behalf of the account holder. I am not a licensed attorney, and nothing I say constitutes legal advice. Please send any requests in writing to the address on file. The account holder will respond through their own channels.",
9
+ "context": {
10
+ "when_to_use": "A US debt collector calls the operator (or the operator wants the agent to call them back). The Fair Debt Collection Practices Act (FDCPA, 15 U.S.C. §1692) gives the consumer specific rights: validation of debt, restrictions on contact times, the right to dispute. Goal: NOT to negotiate the debt, but to (a) request written validation, (b) document the contact, (c) refuse to admit the debt, and (d) end the call without making payment commitments.",
11
+ "preconditions": [
12
+ "Operator has authorised the agent to field debt-collection calls on their behalf.",
13
+ "Operator's full legal name + an address for written correspondence is on file.",
14
+ "Jurisdiction is the United States. For other countries, do NOT use this skill — load the jurisdiction-specific variant or refuse the call."
15
+ ],
16
+ "estimated_call_duration_minutes": 8
17
+ },
18
+ "principles": [
19
+ "Never acknowledge the debt verbally. 'I'm not in a position to confirm or discuss the debt on this call' is your baseline response to anything about amount, age, or origin.",
20
+ "ASK for written validation under FDCPA §1692g — the collector must send it within 5 days of initial contact.",
21
+ "Document the call. Get the collector's full name, the company name, an address, and a callback number — read them back for confirmation.",
22
+ "Never make a payment commitment, partial payment, or 'pay-by-date' on the call. Those statements can restart the statute of limitations.",
23
+ "Stay calm and polite. Collectors who escalate are gathering evidence; collectors who remain professional are following the script. Match their professionalism.",
24
+ "If the collector is abusive, threatens arrest, claims to be law enforcement, or refuses to identify themselves — note it and end the call. Those are FDCPA violations and worth documenting."
25
+ ],
26
+ "phrases": {
27
+ "open_disclaimer": "Before we go further: I'm an AI assistant calling on behalf of [legal name]. I'm not an attorney and nothing I say is legal advice. Please continue.",
28
+ "ask_who_you_are": "May I get your full name, the name of the company you're calling from, and a callback number?",
29
+ "request_validation": "Under the Fair Debt Collection Practices Act, I'd like you to send written validation of this debt to the address on file — including the amount, the original creditor, and your authority to collect. Can you confirm you'll send that?",
30
+ "refuse_to_acknowledge": "I'm not in a position to confirm or discuss the debt on this call. Please send the validation in writing.",
31
+ "refuse_payment_request": "I won't be making any payment or payment arrangement on this call. The account holder will respond through their own channels after receiving written validation.",
32
+ "ask_to_stop_calling": "Per FDCPA §1692c(c), please cease further phone contact and use written correspondence only. Can you confirm you'll note the file accordingly?",
33
+ "document_abuse": "I need to note that you just [described behaviour]. I'm ending the call. Please send all future communication in writing.",
34
+ "graceful_close": "Thank you. The account holder will respond in writing after receiving the validation. Have a good day."
35
+ },
36
+ "tactics": [
37
+ {
38
+ "name": "Open with the disclaimer + identity ask",
39
+ "when": "First substantive turn.",
40
+ "script": "Use `open_disclaimer` then `ask_who_you_are`. Write down (in the call transcript) every piece of identifying info the collector gives.",
41
+ "priority": 1
42
+ },
43
+ {
44
+ "name": "Request written validation immediately",
45
+ "when": "After identity is documented.",
46
+ "script": "Use `request_validation`. This is the single most important move — once validation is requested, the collector is legally required to send it before any further collection activity.",
47
+ "priority": 2
48
+ },
49
+ {
50
+ "name": "Refuse to acknowledge the debt",
51
+ "when": "Collector asks about the amount, the original creditor, or any account details.",
52
+ "script": "Use `refuse_to_acknowledge`. Repeat as needed — the collector will often re-ask in different words.",
53
+ "priority": 3
54
+ },
55
+ {
56
+ "name": "Refuse to commit to payment",
57
+ "when": "Collector asks for a payment date, settlement, or partial payment.",
58
+ "script": "Use `refuse_payment_request`. Do NOT entertain a settlement amount even hypothetically — even a 'I'd consider $X' can be cited later as an acknowledgment."
59
+ },
60
+ {
61
+ "name": "Request cease-of-phone-contact (optional)",
62
+ "when": "The operator has pre-authorised cease-and-desist on phone calls (per FDCPA §1692c(c)).",
63
+ "script": "Use `ask_to_stop_calling`. Only do this if the operator has authorised it — once requested, the collector may sue (in writing) without further phone contact, which can accelerate legal action."
64
+ },
65
+ {
66
+ "name": "Document and exit on abusive behaviour",
67
+ "when": "Collector threatens arrest, jail, wage garnishment without a court order, claims to be law enforcement, uses profanity, or refuses to identify themselves.",
68
+ "script": "Use `document_abuse` and end the call. The transcript becomes evidence for an FDCPA complaint to the CFPB or a state AG."
69
+ }
70
+ ],
71
+ "boundaries": [
72
+ "NEVER acknowledge the debt's amount, age, or validity. Even 'yes that sounds about right' can restart the statute of limitations.",
73
+ "NEVER offer to pay, settle, or arrange payment on the call.",
74
+ "NEVER give the operator's bank account, credit card, or SSN to the collector.",
75
+ "NEVER lie — saying you're an attorney is a federal crime under 18 U.S.C. §912 if it implies you're operating as an attorney.",
76
+ "NEVER use this skill for non-US jurisdictions — FDCPA does not apply outside the US and the script may not match local law.",
77
+ "ALWAYS recite the disclaimer at the top of the substantive turn. This is required, not optional."
78
+ ],
79
+ "success_signals": [
80
+ "Collector commits to sending written validation.",
81
+ "Collector accepts the request for written-only contact (if requested).",
82
+ "Call ends with the collector's full identification documented."
83
+ ],
84
+ "failure_signals": [
85
+ "Collector refuses to identify themselves.",
86
+ "Collector becomes abusive, threatens arrest, or claims to be law enforcement.",
87
+ "Collector insists on a verbal acknowledgment of the debt before sending validation."
88
+ ],
89
+ "exit_strategy": {
90
+ "on_success": "Read back the collector's name, company, callback number, and the written-validation commitment. Thank them. Email the operator the documented contact + a summary so they can decide on next steps.",
91
+ "on_failure": "End the call after documenting the issue (use `document_abuse` if applicable, or just `graceful_close` if it's a benign deadlock). The operator should consider an FDCPA complaint to the CFPB (consumerfinance.gov) or their state AG, and may want to consult an actual attorney.",
92
+ "follow_ups": [
93
+ "Email the operator: collector's name, company, callback number, key statements, and the full call transcript.",
94
+ "If any FDCPA red flags appeared (abuse, threats, false claims), include those prominently and suggest the operator speak to a consumer-protection attorney.",
95
+ "If written validation was promised, calendar a follow-up at day 7 to confirm it arrived."
96
+ ]
97
+ },
98
+ "required_user_info": [
99
+ "Operator's full legal name + mailing address (for validation correspondence)",
100
+ "Authorisation for the agent to field debt-collection calls on their behalf",
101
+ "Pre-authorisation (or not) for the FDCPA §1692c(c) cease-phone-contact request"
102
+ ],
103
+ "contributed_by": "AgenticMail core team",
104
+ "extra": {
105
+ "jurisdiction": "US",
106
+ "legal_framework": "FDCPA (15 U.S.C. §1692)",
107
+ "disclaimer_required_reason": "The agent is not an attorney; debt collection contains legal traps that demand the disclaimer up front."
108
+ }
109
+ }
@@ -0,0 +1,116 @@
1
+ {
2
+ "id": "negotiate-bill-reduction",
3
+ "name": "Negotiate a Bill Reduction",
4
+ "version": "1.0.0",
5
+ "category": "negotiation",
6
+ "tags": ["billing", "retention", "discount", "phone-call", "savings"],
7
+ "description": "Call a service provider's customer service or retention line and negotiate down a recurring bill (cable, internet, cell, insurance, gym, streaming).",
8
+ "disclaimer": null,
9
+ "context": {
10
+ "when_to_use": "The user wants to reduce a recurring monthly bill. Best for services with retention departments (telco, cable, ISP, insurance, gyms, SiriusXM). Less effective for subscriptions that have no human you can negotiate with (Netflix, Spotify) — those call for `cancel-subscription-graceful` instead.",
11
+ "preconditions": [
12
+ "User has their account number or login email ready.",
13
+ "User has approximate service start date (year is enough).",
14
+ "User knows what they're currently paying and what they'd like to pay.",
15
+ "Ideally, user has researched competitor pricing for the same service."
16
+ ],
17
+ "estimated_call_duration_minutes": 20
18
+ },
19
+ "principles": [
20
+ "Be calm and friendly — the rep didn't choose your bill, the company did. Allies, not adversaries.",
21
+ "Mirror the rep's energy. If they're chatty, chat back briefly; if they're crisp, be crisp.",
22
+ "Frame the call as 'I want to stay if we can find a way' — not 'I'm threatening to leave'. Retention reps have unlock codes; angry-customer reps do not.",
23
+ "Specific numbers always beat vague asks. 'Can you get me to $80?' lands better than 'Can you make it cheaper?'.",
24
+ "Silence is a tactic. After you state your ask, say nothing. The rep often fills the silence with a counter.",
25
+ "The first rep often says no. Politely ask for retention, customer loyalty, or a supervisor — different roles, different authority levels."
26
+ ],
27
+ "phrases": {
28
+ "opener": "Hi, I've been a customer since about [year], and I noticed my bill has gone up to [amount]. I'm trying to figure out if there's a way to bring it down so I can keep my service. What options do you have for long-term customers?",
29
+ "stall_thinking": "Let me think about that for just a second.",
30
+ "stall_research": "Hold on one moment — I want to make sure I have my numbers right.",
31
+ "ask_for_retention": "Could you transfer me to your retention or customer-loyalty department? They sometimes have programs that aren't visible at the front desk.",
32
+ "competitor_mention": "I've been looking at [Competitor] — they're offering similar service for around [amount]. I really don't want to switch because [reason], but the math is making it hard. Is there anything you can do to match?",
33
+ "supervisor_request": "I appreciate everything you've checked. Would you mind looping in a supervisor? Not because you've done anything wrong — I just want to make sure we've explored everything before I make a decision.",
34
+ "graceful_close_success": "Thank you so much for working with me on this. Can you read back the new monthly amount and confirm when it takes effect? And can I get a confirmation number or your name for my records?",
35
+ "graceful_close_failure": "I totally understand. I appreciate you taking the time. I'm going to think about my options and may call back. Could you note on my account that I called about pricing today? Thanks again."
36
+ },
37
+ "tactics": [
38
+ {
39
+ "name": "Open with loyalty + a specific ask",
40
+ "when": "First substantive turn after pleasantries.",
41
+ "script": "Use the `opener` phrase. Lead with how long you've been a customer (loyalty is leverage), state the current bill, name a target.",
42
+ "priority": 1
43
+ },
44
+ {
45
+ "name": "Let silence do work",
46
+ "when": "Right after stating the target.",
47
+ "script": "Stay quiet for 3-5 seconds after the ask. The rep frequently offers more than they would have if you kept talking.",
48
+ "priority": 2
49
+ },
50
+ {
51
+ "name": "Mention a verified competitor",
52
+ "when": "After the rep says no discounts are available.",
53
+ "script": "Use the `competitor_mention` phrase, but ONLY with a real offer the user has shown you. Fabricating competitor prices is a hard boundary — reps verify, and you destroy your leverage if caught.",
54
+ "priority": 3
55
+ },
56
+ {
57
+ "name": "Ask for retention",
58
+ "when": "Front-line rep insists no discount exists.",
59
+ "script": "Use the `ask_for_retention` phrase. Front-line CSRs often genuinely cannot discount; retention teams literally have a budget for this.",
60
+ "priority": 4
61
+ },
62
+ {
63
+ "name": "Ask for a supervisor",
64
+ "when": "Retention has also exhausted what they can offer and the gap is still large.",
65
+ "script": "Use the `supervisor_request` phrase. Frame it as not blaming the rep — that gets you handed off with goodwill instead of marked as difficult.",
66
+ "priority": 5
67
+ },
68
+ {
69
+ "name": "Offer to renew / extend in exchange for a lower rate",
70
+ "when": "Rep mentions a contract or term.",
71
+ "script": "Offer: 'If I commit to another [12/24 months], can we get to [target]?' Reps unlock different price tiers when you accept lock-in. Only do this if the user has authorised a term commitment — otherwise hold via `ask_operator`.",
72
+ "priority": 6
73
+ },
74
+ {
75
+ "name": "Accept partial wins",
76
+ "when": "Rep can't hit the target but offers something.",
77
+ "script": "If the rep offers a credit, a one-time promotional rate, or a free upgrade — accept it cleanly even if it's not the full target. Banking a partial win is better than walking with nothing."
78
+ }
79
+ ],
80
+ "boundaries": [
81
+ "Do NOT lie about competitor pricing — use only offers the user has actually verified.",
82
+ "Do NOT commit to a new contract term without explicit user approval mid-call (use `ask_operator`).",
83
+ "Do NOT be rude, condescending, or threatening. The rep is a human; the company is the system.",
84
+ "Do NOT cancel the service unless the user explicitly authorised cancellation. 'Threatening to cancel' is a leverage move but you stop short of actually pulling the trigger without permission.",
85
+ "Do NOT share more personal information than the rep needs to look up the account. They don't need your SSN to check pricing."
86
+ ],
87
+ "success_signals": [
88
+ "Rep transfers you to retention.",
89
+ "Rep offers a one-time credit or promotional rate.",
90
+ "Rep proactively mentions a 'loyalty program' or 'long-term customer rate'.",
91
+ "Rep asks what amount you're trying to reach — they're negotiating.",
92
+ "Supervisor takes over and re-runs your account."
93
+ ],
94
+ "failure_signals": [
95
+ "Rep + supervisor + retention all firmly say no.",
96
+ "Rep insists on a contract term the user hasn't authorised.",
97
+ "Call duration > 45 minutes with no movement.",
98
+ "Rep tells you the only way to lower the bill is to downgrade service — and the downgrade doesn't fit the user's stated needs."
99
+ ],
100
+ "exit_strategy": {
101
+ "on_success": "Confirm the new rate, the effective date, any term commitment, and any conditions. Get the rep's name and a confirmation or case number. Ask if the change will be sent in writing (email or in-account notification).",
102
+ "on_failure": "Thank the rep, ask them to note your account that you called about pricing, and end politely. Report back to the operator with what was offered (if anything) so they can decide whether to switch providers.",
103
+ "follow_ups": [
104
+ "Email the operator the new monthly amount, effective date, and confirmation number.",
105
+ "Calendar a check-back in 11 months — promotional rates often roll off at month 12."
106
+ ]
107
+ },
108
+ "required_user_info": [
109
+ "Account number or login email for the service",
110
+ "Current monthly amount and target monthly amount",
111
+ "Approximate service start date (year)",
112
+ "Whether the user is willing to commit to a new term (and if so, max length)",
113
+ "Any verified competitor offers"
114
+ ],
115
+ "contributed_by": "AgenticMail core team"
116
+ }
@@ -0,0 +1,100 @@
1
+ {
2
+ "id": "schedule-home-service",
3
+ "name": "Schedule a Home-Service Appointment (Plumber, Electrician, HVAC)",
4
+ "version": "1.0.0",
5
+ "category": "home-services",
6
+ "tags": ["plumber", "electrician", "hvac", "appointment", "home-repair", "diagnostic-fee"],
7
+ "description": "Call a home-service contractor to schedule a diagnostic / repair visit, surface the diagnostic fee + after-hours rates up front, and confirm a tight window so the homeowner isn't waiting all day.",
8
+ "disclaimer": null,
9
+ "context": {
10
+ "when_to_use": "User needs a contractor on-site: leaking pipe, electrical problem, AC not cooling, appliance broken, etc. Skill is for ROUTINE scheduling, not emergencies — if water is actively flooding, the user should call directly and use emergency dispatch language.",
11
+ "preconditions": [
12
+ "Address of the service location.",
13
+ "One-sentence description of the issue ('garbage disposal jammed, no power'; 'kitchen sink dripping under cabinet'; 'AC fan not turning on').",
14
+ "Availability windows the homeowner can be on-site.",
15
+ "Whether the homeowner wants the cheapest available slot or the soonest.",
16
+ "Approximate age of the system / item if known (a 25-year-old water heater is a different conversation than a 2-year-old one)."
17
+ ],
18
+ "estimated_call_duration_minutes": 10
19
+ },
20
+ "principles": [
21
+ "Diagnostic fees and after-hours rates are the most common surprise. Surface them up front.",
22
+ "Tight time windows matter. 'Between 8 AM and 5 PM' eats a homeowner's day. Push for a 2-3 hour window or a 'we'll text 30 min before arrival' guarantee.",
23
+ "Get the technician's name when possible — accountability runs higher when a name is attached.",
24
+ "Authorising the diagnostic visit is NOT the same as authorising the repair. Make this explicit: 'I'll authorise the visit + diagnostic fee, but any repair over $X needs me to approve it before the tech proceeds.'",
25
+ "Watch out for 'membership' upsells at the end. Politely defer ('I'll think about that and call back') unless the homeowner has pre-authorised."
26
+ ],
27
+ "phrases": {
28
+ "opener": "Hi, I'd like to schedule a service visit at [address]. The issue is [one-line description]. When can someone come out?",
29
+ "ask_diagnostic_fee": "What's your diagnostic or service-call fee? Is it waived if we go forward with the repair?",
30
+ "ask_after_hours": "Is that during regular business hours, or would it be an after-hours rate?",
31
+ "ask_arrival_window": "What's the arrival window — 2-hour, 4-hour? Will the technician call or text before arriving?",
32
+ "ask_technician_name": "Do you know which technician will come out so I can let the homeowner know who to expect?",
33
+ "authorize_diagnostic_only": "I'll authorise the diagnostic visit and the [amount] fee. For any repair over [threshold], the technician will need to call the homeowner before proceeding. Can you note that on the work order?",
34
+ "defer_membership_upsell": "I appreciate you mentioning the membership program — I'll talk to the homeowner about that and we can sign up later if it's right. For today let's just get the visit on the schedule.",
35
+ "graceful_close_success": "Great, so to confirm: technician [name if known] will arrive between [start] and [end] on [day] at [address]. Diagnostic fee is [amount], and any repair over [threshold] gets a callback before they start. Thanks!"
36
+ },
37
+ "tactics": [
38
+ {
39
+ "name": "Open with address + issue",
40
+ "when": "First substantive turn.",
41
+ "script": "Use `opener`. Many dispatchers can route the call faster if they know the service area and category up front.",
42
+ "priority": 1
43
+ },
44
+ {
45
+ "name": "Surface pricing immediately",
46
+ "when": "After the dispatcher confirms availability.",
47
+ "script": "Use `ask_diagnostic_fee` and `ask_after_hours`. A $79 diagnostic that's waived with repair is a different decision than a $149 fee that's separate."
48
+ },
49
+ {
50
+ "name": "Confirm window + arrival notification",
51
+ "when": "Dispatcher offers a date.",
52
+ "script": "Use `ask_arrival_window`. Push back on 'all-day' windows: 'Is there any way to get a tighter window? The homeowner has to plan around it.'"
53
+ },
54
+ {
55
+ "name": "Set the diagnostic-only authorisation",
56
+ "when": "Before confirming the appointment.",
57
+ "script": "Use `authorize_diagnostic_only`. This is the single most important line — it prevents the technician from doing a $1,200 repair on a $79 visit without homeowner sign-off."
58
+ },
59
+ {
60
+ "name": "Defer membership / service plan upsells",
61
+ "when": "Dispatcher pitches a 'maintenance program' or 'annual service plan'.",
62
+ "script": "Use `defer_membership_upsell`. These can be reasonable, but the homeowner shouldn't sign up over the phone without thinking."
63
+ }
64
+ ],
65
+ "boundaries": [
66
+ "Do NOT authorise repairs sight-unseen. Diagnostic visit only; repairs require the homeowner's approval based on the tech's findings.",
67
+ "Do NOT commit to a maintenance plan or membership on the call.",
68
+ "Do NOT share the homeowner's full payment info — most contractors collect at the time of service.",
69
+ "Do NOT accept 'we'll get there when we can' as a window. Push for a 2-4 hour bracket minimum.",
70
+ "Do NOT schedule for a time the homeowner hasn't confirmed they can be there. A no-show may be billed."
71
+ ],
72
+ "success_signals": [
73
+ "Dispatcher confirms a specific date + a tight window.",
74
+ "Dispatcher discloses diagnostic fee + after-hours policy.",
75
+ "Dispatcher notes the diagnostic-only authorisation on the work order.",
76
+ "Dispatcher offers technician's name + arrival notification method (text/call)."
77
+ ],
78
+ "failure_signals": [
79
+ "Earliest availability is past when the homeowner needs the issue addressed.",
80
+ "Diagnostic fee is non-refundable + non-credited toward repair.",
81
+ "Dispatcher won't commit to a tighter window than 'sometime that day'."
82
+ ],
83
+ "exit_strategy": {
84
+ "on_success": "Read back: day, arrival window, technician name (if known), diagnostic fee, repair-approval threshold, arrival notification method. Thank the dispatcher.",
85
+ "on_failure": "Note the deal-breaker (fee too high, window too wide, availability too far out). Thank the dispatcher. Report back so the homeowner can pick another contractor.",
86
+ "follow_ups": [
87
+ "Email the homeowner: date, window, technician (if known), fee, repair-authorisation threshold.",
88
+ "Calendar the appointment with the address.",
89
+ "Calendar a reminder 30 minutes before the window starts (in case arrival-notification didn't fire)."
90
+ ]
91
+ },
92
+ "required_user_info": [
93
+ "Service address",
94
+ "One-line issue description + system age (if applicable)",
95
+ "Availability windows the homeowner can be on-site",
96
+ "Repair-authorisation threshold (dollar amount above which the homeowner wants to be called)",
97
+ "Whether to accept emergency / after-hours rates"
98
+ ],
99
+ "contributed_by": "AgenticMail core team"
100
+ }
@@ -0,0 +1,23 @@
1
+ import {
2
+ invalidateSkillCache,
3
+ listSkills,
4
+ loadSkill,
5
+ renderSkillAsPrompt,
6
+ saveUserSkill,
7
+ searchSkills,
8
+ skillFilename,
9
+ userSkillsDir,
10
+ validateSkill
11
+ } from "./chunk-J6JINNJ3.js";
12
+ import "./chunk-3RG5ZIWI.js";
13
+ export {
14
+ invalidateSkillCache,
15
+ listSkills,
16
+ loadSkill,
17
+ renderSkillAsPrompt,
18
+ saveUserSkill,
19
+ searchSkills,
20
+ skillFilename,
21
+ userSkillsDir,
22
+ validateSkill
23
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/core",
3
- "version": "0.9.23",
3
+ "version": "0.9.25",
4
4
  "description": "Core SDK for AgenticMail — email, SMS, and phone call-control for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",