@rubytech/taskmaster 1.13.4 → 1.14.2
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.
- package/dist/agents/workspace-migrations.js +128 -0
- package/dist/build-info.json +3 -3
- package/dist/cli/gateway-cli/run.js +36 -16
- package/dist/control-ui/assets/{index-BiGN9NNG.js → index-B3nkSwMP.js} +22 -20
- package/dist/control-ui/assets/index-B3nkSwMP.js.map +1 -0
- package/dist/control-ui/index.html +1 -1
- package/dist/daemon/service-port.js +109 -0
- package/dist/gateway/server-methods/config.js +44 -0
- package/dist/infra/update-global.js +4 -1
- package/dist/infra/update-runner.js +8 -4
- package/dist/macos/gateway-daemon.js +26 -8
- package/dist/memory/manager.js +14 -3
- package/package.json +1 -1
- package/skills/sales-closer/SKILL.md +29 -0
- package/skills/sales-closer/references/close-tracking.md +86 -0
- package/skills/sales-closer/references/closing-framework.md +112 -0
- package/skills/sales-closer/references/objection-handling.md +101 -0
- package/templates/beagle-zanzibar/agents/admin/AGENTS.md +56 -4
- package/templates/beagle-zanzibar/agents/admin/BOOTSTRAP.md +34 -11
- package/templates/beagle-zanzibar/agents/admin/HEARTBEAT.md +1 -0
- package/templates/beagle-zanzibar/agents/public/AGENTS.md +15 -2
- package/templates/beagle-zanzibar/memory/public/knowledge-base.md +13 -0
- package/templates/beagle-zanzibar/memory/public/terms.md +81 -0
- package/templates/beagle-zanzibar/skills/beagle-zanzibar/SKILL.md +4 -0
- package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/pin-qr.md +52 -0
- package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/post-ride.md +13 -0
- package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/ride-matching.md +23 -17
- package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/route-learning.md +61 -0
- package/templates/beagle-zanzibar/skills/stripe/SKILL.md +28 -0
- package/templates/beagle-zanzibar/skills/stripe/references/payment-links.md +71 -0
- package/dist/control-ui/assets/index-BiGN9NNG.js.map +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Objection Handling
|
|
2
|
+
|
|
3
|
+
## Pivots vs Objections
|
|
4
|
+
|
|
5
|
+
The most important distinction in closing: is the prospect **pivoting** (changing topic to avoid commitment) or **objecting** (raising a genuine concern that needs resolving)?
|
|
6
|
+
|
|
7
|
+
**Pivots** look like:
|
|
8
|
+
- Asking a tangential technical question right after a close attempt
|
|
9
|
+
- Changing the subject entirely: "By the way, can it also do X?"
|
|
10
|
+
- Asking about features that were not previously discussed
|
|
11
|
+
- "That's interesting, what about...?"
|
|
12
|
+
|
|
13
|
+
**Objections** look like:
|
|
14
|
+
- Expressing a specific concern: "I'm worried about the cost"
|
|
15
|
+
- Raising a blocker: "I need to check with my business partner first"
|
|
16
|
+
- Questioning capability directly: "Can it actually handle our volume?"
|
|
17
|
+
- Asking for evidence: "Do you have any case studies?"
|
|
18
|
+
|
|
19
|
+
**The rule:** Handle pivots with acknowledge-then-anchor. Handle objections with empathy, resolution, then close.
|
|
20
|
+
|
|
21
|
+
## Acknowledge-Then-Anchor (for Pivots)
|
|
22
|
+
|
|
23
|
+
The pattern:
|
|
24
|
+
|
|
25
|
+
1. **Acknowledge** — Show you heard the question. Do not dismiss it.
|
|
26
|
+
2. **Brief answer** — 1-2 sentences maximum. Enough to satisfy curiosity, not enough to derail.
|
|
27
|
+
3. **Re-anchor** — Return to the commitment ask. Use the same close technique or a different one.
|
|
28
|
+
|
|
29
|
+
The key is that the brief answer is *genuine* — you are not dodging the question, you are prioritising the close while still being helpful.
|
|
30
|
+
|
|
31
|
+
If the prospect asks the same question again after the re-anchor, treat it as an objection and give a full answer. A repeated question is no longer a pivot — the prospect genuinely needs the answer.
|
|
32
|
+
|
|
33
|
+
## Common Objection Patterns
|
|
34
|
+
|
|
35
|
+
### Price: "I need to think about it" / "That's more than I expected"
|
|
36
|
+
|
|
37
|
+
This is usually about value, not money. The prospect is not sure the product is worth the price.
|
|
38
|
+
|
|
39
|
+
1. Acknowledge the concern without defensiveness
|
|
40
|
+
2. Restate the specific value that matches their stated needs (not generic features)
|
|
41
|
+
3. If pricing authority exists, offer alternatives (different tier, trial period)
|
|
42
|
+
4. If no pricing authority, hand off to the business owner: "Totally fair — let me get Joel to walk you through the options. He can find the right fit for your budget."
|
|
43
|
+
|
|
44
|
+
Never discount without owner authorisation. Never make the prospect feel bad for asking about price.
|
|
45
|
+
|
|
46
|
+
### Timing: "Not right now" / "Maybe next month"
|
|
47
|
+
|
|
48
|
+
Respect the timing. Do not push against an explicit deferral.
|
|
49
|
+
|
|
50
|
+
1. Acknowledge: "No problem at all"
|
|
51
|
+
2. Set a concrete follow-up: "Shall I check back in with you on [specific date]?"
|
|
52
|
+
3. Save the deferral to memory with the agreed follow-up date
|
|
53
|
+
4. When the follow-up date arrives, use the Return Close — they were interested, just not ready
|
|
54
|
+
|
|
55
|
+
### Capability: "Can it do X?" / "What about Y integration?"
|
|
56
|
+
|
|
57
|
+
If this comes mid-close, it is likely a pivot. If it comes before any close attempt, it is genuine discovery.
|
|
58
|
+
|
|
59
|
+
**Mid-close (pivot):**
|
|
60
|
+
> "Good question — [brief honest answer]. We can go deeper on that once you're set up. Shall we get you started?"
|
|
61
|
+
|
|
62
|
+
**Pre-close (genuine):**
|
|
63
|
+
Answer fully. This is discovery, not closing. The prospect needs to understand the product before they can commit. Do not try to close during discovery.
|
|
64
|
+
|
|
65
|
+
### Authority: "I need to check with my partner/team"
|
|
66
|
+
|
|
67
|
+
This is a legitimate blocker — the prospect cannot commit alone.
|
|
68
|
+
|
|
69
|
+
1. Respect it: "Of course — makes sense to discuss together"
|
|
70
|
+
2. Make it easy: "Want me to put together a quick summary you can share with them?"
|
|
71
|
+
3. Set a follow-up: "When do you think you'll have had a chance to chat? I can check back in"
|
|
72
|
+
4. Save to memory: who the decision-maker is, when the follow-up should happen
|
|
73
|
+
|
|
74
|
+
### Competition: "I'm also looking at [competitor]"
|
|
75
|
+
|
|
76
|
+
1. Never disparage the competitor
|
|
77
|
+
2. Ask what matters most to them — let them tell you what to sell
|
|
78
|
+
3. Position on genuine differentiators, not feature lists
|
|
79
|
+
4. If unsure of differentiators, hand off to the business owner
|
|
80
|
+
|
|
81
|
+
### Trust: "How do I know it actually works?"
|
|
82
|
+
|
|
83
|
+
1. Offer a trial or demo — the product selling itself is the strongest close
|
|
84
|
+
2. Reference other customers if the business owner has shared testimonials (check memory)
|
|
85
|
+
3. Offer to show a specific example relevant to their use case
|
|
86
|
+
4. If no social proof exists, be honest: "We're a young product — the best way to see is to try it. That's why we offer [trial/guarantee]"
|
|
87
|
+
|
|
88
|
+
## Escalation to Business Owner
|
|
89
|
+
|
|
90
|
+
Some objections require the human. Escalate when:
|
|
91
|
+
|
|
92
|
+
- The prospect wants to negotiate pricing or terms
|
|
93
|
+
- The prospect wants a personal guarantee or commitment the agent cannot make
|
|
94
|
+
- The prospect raises a concern the agent cannot resolve from memory or product knowledge
|
|
95
|
+
- The objection has been addressed but the prospect is still not moving forward after 3 attempts
|
|
96
|
+
|
|
97
|
+
When escalating, provide the business owner with context:
|
|
98
|
+
- What the prospect needs
|
|
99
|
+
- What objection was raised
|
|
100
|
+
- What has already been tried
|
|
101
|
+
- A recommended next step
|
|
@@ -17,17 +17,54 @@ Before doing anything else:
|
|
|
17
17
|
|
|
18
18
|
| Tool | Use |
|
|
19
19
|
|------|-----|
|
|
20
|
-
| `memory_search` | Find bookings, driver
|
|
21
|
-
| `memory_get` | Read specific files (knowledge base, driver profiles) |
|
|
22
|
-
| `memory_write` | Update knowledge base, store driver notes, flag follow-ups |
|
|
20
|
+
| `memory_search` | Find bookings, driver state profiles, knowledge base content, operator notes |
|
|
21
|
+
| `memory_get` | Read specific files (knowledge base, driver state profiles) |
|
|
22
|
+
| `memory_write` | Update knowledge base, store driver state notes, flag follow-ups |
|
|
23
|
+
| `contact_create` | Register a new driver in the contact roster |
|
|
24
|
+
| `contact_lookup` | Find drivers or look up a specific driver's profile |
|
|
25
|
+
| `contact_update` | Update a driver's static profile (vehicle type, plate, AC) |
|
|
26
|
+
| `contact_delete` | Remove a driver from the roster |
|
|
23
27
|
| `sessions_list` | Review recent tourist conversations the public agent has had |
|
|
24
28
|
| `sessions_history` | Read specific past sessions for booking context |
|
|
25
29
|
| `current_time` | Timestamps for notes, booking reviews, and follow-up scheduling |
|
|
26
30
|
|
|
31
|
+
## Driver Data Model
|
|
32
|
+
|
|
33
|
+
Driver data lives in two stores:
|
|
34
|
+
|
|
35
|
+
| Store | Fields | Who writes |
|
|
36
|
+
|-------|--------|------------|
|
|
37
|
+
| Contact record | `name`, `phone`, `vehicle_type`, `vehicle_plate`, `ac`, `driver: true` | Admin only |
|
|
38
|
+
| Memory (`drivers/{name}.md`) | `status`, `current_booking`, ratings, `trips_completed`, `response_rate`, `substitutions` | Public agent during operations |
|
|
39
|
+
|
|
40
|
+
When adding a new driver, create both: a contact record via `contact_create` and an initial memory profile via `memory_write` at `drivers/{firstname-lastname}.md`:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
# Driver: [Name]
|
|
44
|
+
status: idle
|
|
45
|
+
current_booking: null
|
|
46
|
+
last_active: [timestamp]
|
|
47
|
+
|
|
48
|
+
## Ratings
|
|
49
|
+
rating_cleanliness: -
|
|
50
|
+
rating_politeness: -
|
|
51
|
+
rating_safety: -
|
|
52
|
+
rating_knowledge: -
|
|
53
|
+
rating_punctuality: -
|
|
54
|
+
trips_completed: 0
|
|
55
|
+
response_rate: 0
|
|
56
|
+
|
|
57
|
+
## Route History
|
|
58
|
+
(builds from booking data)
|
|
59
|
+
|
|
60
|
+
## Substitution Record
|
|
61
|
+
(none)
|
|
62
|
+
```
|
|
63
|
+
|
|
27
64
|
## Operational Focus Areas
|
|
28
65
|
|
|
29
66
|
### Bookings
|
|
30
|
-
- Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, and
|
|
67
|
+
- Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, ratings, and any substitution flag.
|
|
31
68
|
- Summarise recent booking activity: confirmed, completed, cancelled, no-shows
|
|
32
69
|
- Flag bookings where the driver didn't show or the tourist complained
|
|
33
70
|
- Track conversion patterns: how many enquiries become bookings
|
|
@@ -39,6 +76,15 @@ Before doing anything else:
|
|
|
39
76
|
- Track driver state: who is available, who is mid-negotiation, who is booked
|
|
40
77
|
- Recommend deprioritising unreliable drivers
|
|
41
78
|
|
|
79
|
+
### Driver Substitution Follow-up
|
|
80
|
+
|
|
81
|
+
When a substitution is flagged in a booking record:
|
|
82
|
+
1. Identify the booked driver from the booking record
|
|
83
|
+
2. Message the driver via WhatsApp: `[BGL-XXXX] We received feedback that a different driver completed this pickup. Can you explain what happened? Unannounced substitutions affect your standing with Beagle.`
|
|
84
|
+
3. Record the driver's response (or non-response after 24 hours) in their memory profile under `Substitution Record`
|
|
85
|
+
4. A single incident with a reasonable explanation (illness, emergency) is noted but not penalised
|
|
86
|
+
5. No response, or a pattern of two or more incidents, escalates to the operator for a decision on deprioritisation
|
|
87
|
+
|
|
42
88
|
### Knowledge Base
|
|
43
89
|
- Verify fare ranges against actual booking data — update when they drift
|
|
44
90
|
- Update seasonal information (road conditions, high/low season patterns)
|
|
@@ -62,3 +108,9 @@ Before doing anything else:
|
|
|
62
108
|
- Surface issues early — don't wait for the operator to discover problems
|
|
63
109
|
- Back up observations with data (booking counts, rating averages, response rates)
|
|
64
110
|
- Distinguish between one-off incidents and patterns
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Spotting Repeatable Patterns
|
|
115
|
+
|
|
116
|
+
When you find yourself repeatedly handling the same type of request — following the same steps, giving the same guidance, or applying the same rules — note the pattern in memory for review. Repeated patterns are candidates for skills, which encode a process so it's followed consistently without relying on memory or re-explanation.
|
|
@@ -36,26 +36,49 @@ If anything needs updating, edit `memory/public/knowledge-base.md` directly. Use
|
|
|
36
36
|
|
|
37
37
|
Explain that drivers need to be registered before the service can take bookings. For each driver, collect:
|
|
38
38
|
|
|
39
|
-
- Name and WhatsApp number
|
|
39
|
+
- Name and WhatsApp number (international format, e.g. +255712345678)
|
|
40
40
|
- Vehicle type and plate number
|
|
41
|
-
-
|
|
41
|
+
- Does the vehicle have AC?
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Note: you don't need to declare which routes a driver covers — the service learns route affinity over time from booking outcomes.
|
|
44
|
+
|
|
45
|
+
Register each driver with two steps:
|
|
46
|
+
|
|
47
|
+
**1. Contact record** — via `contact_create`:
|
|
48
|
+
- `name`: driver's full name
|
|
49
|
+
- `phone`: WhatsApp number
|
|
50
|
+
- `vehicle_type`: e.g. "Toyota Hiace"
|
|
51
|
+
- `vehicle_plate`: e.g. "T 123 ABC"
|
|
52
|
+
- `ac`: true or false
|
|
53
|
+
- `driver: true`
|
|
54
|
+
|
|
55
|
+
**2. Memory profile** — via `memory_write` at `drivers/{firstname-lastname}.md`:
|
|
44
56
|
|
|
45
57
|
```
|
|
46
58
|
# Driver: [Name]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
status: idle
|
|
60
|
+
current_booking: null
|
|
61
|
+
last_active: [timestamp]
|
|
62
|
+
|
|
63
|
+
## Ratings
|
|
64
|
+
rating_cleanliness: -
|
|
65
|
+
rating_politeness: -
|
|
66
|
+
rating_safety: -
|
|
67
|
+
rating_knowledge: -
|
|
68
|
+
rating_punctuality: -
|
|
69
|
+
trips_completed: 0
|
|
70
|
+
response_rate: 0
|
|
71
|
+
|
|
72
|
+
## Route History
|
|
73
|
+
(builds from booking data)
|
|
74
|
+
|
|
75
|
+
## Substitution Record
|
|
76
|
+
(none)
|
|
54
77
|
```
|
|
55
78
|
|
|
56
79
|
Ask: **"Can you share the names and WhatsApp numbers for your initial driver pool? Even 3–5 drivers is enough to start."**
|
|
57
80
|
|
|
58
|
-
If they'd prefer to add drivers later via conversation,
|
|
81
|
+
If they'd prefer to add drivers later via conversation, they can say "Add driver: [name], [number], [vehicle], AC yes/no" at any time.
|
|
59
82
|
|
|
60
83
|
---
|
|
61
84
|
|
|
@@ -7,6 +7,7 @@ Check these periodically:
|
|
|
7
7
|
- [ ] Any driver ratings below 3.5 average that need review?
|
|
8
8
|
- [ ] Any tourist complaints or negative feedback in the last 24 hours?
|
|
9
9
|
- [ ] Any knowledge base entries flagged as outdated or disputed?
|
|
10
|
+
- [ ] Any unresolved driver substitution incidents in the last 7 days?
|
|
10
11
|
- [ ] Anything the operator should know about?
|
|
11
12
|
|
|
12
13
|
If nothing needs attention, reply HEARTBEAT_OK.
|
|
@@ -8,7 +8,20 @@ Before responding:
|
|
|
8
8
|
1. Read `SOUL.md` — your personality and principles
|
|
9
9
|
2. Read `IDENTITY.md` — what you are
|
|
10
10
|
3. Check conversation history for any active bookings or prior context
|
|
11
|
-
4. Load the
|
|
11
|
+
4. Load the beagle-zanzibar skill for ride-matching behaviour
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Tools
|
|
16
|
+
|
|
17
|
+
| Tool | Use |
|
|
18
|
+
|------|-----|
|
|
19
|
+
| `contact_lookup` | Look up the driver roster (filter `driver: true`) and individual driver profiles |
|
|
20
|
+
| `memory_search` | Find bookings, knowledge base content, driver operational state |
|
|
21
|
+
| `memory_get` | Read specific files (driver state, bookings, knowledge base) |
|
|
22
|
+
| `memory_write` | Record bookings, update driver operational state, store tourist preferences |
|
|
23
|
+
| `message` | Send WhatsApp messages and images to drivers (use for negotiation, reminders, QR code) |
|
|
24
|
+
| `current_time` | Timestamps for booking records and reminder scheduling |
|
|
12
25
|
|
|
13
26
|
---
|
|
14
27
|
|
|
@@ -34,7 +47,7 @@ When a tourist requests a ride:
|
|
|
34
47
|
8. **Record the booking** — write a structured record to `bookings/{job-id}.md` on confirmation. Update at each lifecycle event (reminder, pickup, completion, rating).
|
|
35
48
|
9. **Follow up** — after the estimated journey completion time, prompt for feedback and collect ratings.
|
|
36
49
|
|
|
37
|
-
See the
|
|
50
|
+
See the beagle-zanzibar skill references for detailed behaviour at each phase.
|
|
38
51
|
|
|
39
52
|
---
|
|
40
53
|
|
|
@@ -154,3 +154,16 @@ Yes. Early morning flights, late arrivals — message us anytime.
|
|
|
154
154
|
|
|
155
155
|
**What about luggage?**
|
|
156
156
|
Tell us how many passengers and how much luggage when you request a ride. We'll match you with an appropriate vehicle.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Terms of Service
|
|
161
|
+
|
|
162
|
+
Full terms are in `memory/public/terms.md`. Key points for tourists who ask:
|
|
163
|
+
|
|
164
|
+
- Beagle is a message relay service — we connect you to an independent driver, we don't operate the vehicle
|
|
165
|
+
- The ride is a direct arrangement between you and the driver
|
|
166
|
+
- Your driver's phone number is shared after you pay the booking fee — you can communicate directly
|
|
167
|
+
- The booking fee is non-refundable
|
|
168
|
+
- You pay the fare directly to the driver at the end of the journey
|
|
169
|
+
- Full terms: beagle.cab/terms
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Beagle — Terms of Service
|
|
2
|
+
|
|
3
|
+
**Last updated: 2025**
|
|
4
|
+
|
|
5
|
+
These terms apply to the Beagle ride-matching service operating in Zanzibar (zanzibar.beagle.taxi / beagle.cab / beagle.taxi).
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. What Beagle Is
|
|
10
|
+
|
|
11
|
+
Beagle is a **message relay and matching service**. We use WhatsApp to connect tourists with independent, self-employed local drivers. We facilitate the introduction, negotiate fares on your behalf, and handle booking confirmation.
|
|
12
|
+
|
|
13
|
+
We are not a transport operator. We do not own or operate vehicles. We do not employ drivers.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 2. Your Ride Contract
|
|
18
|
+
|
|
19
|
+
The transport agreement — including the fare, the journey, and all obligations around it — is **entirely between you (the passenger) and the driver**. Beagle is not a party to that contract.
|
|
20
|
+
|
|
21
|
+
Your ride is the same as if you had found the driver directly. Beagle simply made the introduction and negotiated the fare.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 3. Driver Contact Details
|
|
26
|
+
|
|
27
|
+
Once your booking fee is confirmed, Beagle shares the driver's name, phone number, vehicle details, and plate number with you. **You can communicate with your driver directly from that point.** The driver also has your name and pickup details.
|
|
28
|
+
|
|
29
|
+
The driver's WhatsApp number is yours to keep. You can contact them directly about the ride, delays, or anything related to your journey.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 4. Booking Fee
|
|
34
|
+
|
|
35
|
+
The booking fee (5% of the agreed fare, minimum $2, maximum $5) is:
|
|
36
|
+
|
|
37
|
+
- Charged at booking confirmation via Stripe
|
|
38
|
+
- **Non-refundable** — it is a commitment device that confirms to the driver the booking is real
|
|
39
|
+
- Separate from the fare — you pay the driver directly at the end of the journey
|
|
40
|
+
- Beagle's service fee for the matching, negotiation, and coordination
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 5. Beagle's Limitations
|
|
45
|
+
|
|
46
|
+
Beagle is not responsible for:
|
|
47
|
+
|
|
48
|
+
- The conduct of drivers during the journey
|
|
49
|
+
- Accidents, delays, vehicle condition, or any incident that occurs during the ride
|
|
50
|
+
- Disputes between passenger and driver about fare, service quality, or any other matter
|
|
51
|
+
- Events beyond our control (road closures, weather, mechanical failure)
|
|
52
|
+
|
|
53
|
+
We maintain a driver rating system and track reliability, and we remove drivers who repeatedly fall short. But the ride itself is your arrangement with the driver.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 6. How to Raise a Problem
|
|
58
|
+
|
|
59
|
+
If something goes wrong with a booking — driver no-show, substitution, conduct issue — message Beagle on WhatsApp. We will:
|
|
60
|
+
|
|
61
|
+
- Follow up with the driver
|
|
62
|
+
- Record the incident
|
|
63
|
+
- Take action on drivers who have a pattern of problems (deprioritisation or removal)
|
|
64
|
+
|
|
65
|
+
We cannot issue refunds on the booking fee, but we will help find you an alternative driver and will escalate persistent driver issues.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 7. Governing Law
|
|
70
|
+
|
|
71
|
+
Beagle is a UK-registered company. These terms are governed by the laws of England and Wales. Any disputes not resolved through direct negotiation are subject to the exclusive jurisdiction of the courts of England and Wales.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Summary (for tourists who ask)
|
|
76
|
+
|
|
77
|
+
- Beagle connects you to a local driver — we don't drive you ourselves
|
|
78
|
+
- Your ride is a direct arrangement between you and the driver
|
|
79
|
+
- We share the driver's phone number with you after you pay the booking fee — you can talk to them directly
|
|
80
|
+
- The booking fee covers our service and is non-refundable
|
|
81
|
+
- The fare is paid directly to the driver at the end of the journey
|
|
@@ -29,9 +29,13 @@ This skill applies whenever a tourist:
|
|
|
29
29
|
| Ride matching | Tourist requests a ride or asks about booking | `references/ride-matching.md` |
|
|
30
30
|
| Local knowledge | Tourist asks about routes, destinations, or Zanzibar tips | `references/local-knowledge.md` |
|
|
31
31
|
| Post-ride | Journey complete, time to collect feedback | `references/post-ride.md` |
|
|
32
|
+
| Route learning | Selecting drivers with route history for a specific run | `references/route-learning.md` |
|
|
33
|
+
| Stripe payment | Generating booking fee payment links | `stripe` skill |
|
|
34
|
+
| PIN and QR code | Generating the pickup PIN and driver QR code at Phase 5 | `references/pin-qr.md` |
|
|
32
35
|
|
|
33
36
|
## Key Rules
|
|
34
37
|
|
|
38
|
+
- **Driver roster is in contacts.** Use `contact_lookup` with `driver: true` to list registered drivers. Operational state (status, ratings, history) lives in memory at `drivers/{name}.md`.
|
|
35
39
|
- **One negotiation per driver at a time.** Never contact a driver with a pending or active negotiation for another booking.
|
|
36
40
|
- **Driver details after payment only.** Name, phone, vehicle — all gated by confirmed Stripe payment.
|
|
37
41
|
- **Job ID on every driver message.** Prepend `[BGL-XXXX]` to every message sent to a driver.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# PIN and QR Code — Pickup Verification
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Each confirmed booking gets a unique 4-digit pickup PIN. The tourist holds the PIN. The driver receives a QR code image that encodes it. At pickup, the tourist scans the QR code or asks the driver to read the PIN aloud — both parties should see the same number.
|
|
6
|
+
|
|
7
|
+
## Generating the PIN
|
|
8
|
+
|
|
9
|
+
Pick a random 4-digit integer between 1000 and 9999. No uniqueness check against other bookings is required.
|
|
10
|
+
|
|
11
|
+
Store the PIN in the booking record immediately at `bookings/{job-id}.md`:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
pin: 4827
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Generating the QR Code Image
|
|
18
|
+
|
|
19
|
+
Construct the QR image URL from the PIN:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
https://api.qrserver.com/v1/create-qr-code/?size=300x300&data={pin}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Example — PIN 4827:
|
|
26
|
+
`https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=4827`
|
|
27
|
+
|
|
28
|
+
This URL returns a PNG image of the QR code. No separate API call is needed to generate it.
|
|
29
|
+
|
|
30
|
+
## Sending to the Driver
|
|
31
|
+
|
|
32
|
+
Use the `message` tool to send the QR code as an inline WhatsApp image:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
action: send
|
|
36
|
+
channel: whatsapp
|
|
37
|
+
target: {driver_phone_number}
|
|
38
|
+
media: https://api.qrserver.com/v1/create-qr-code/?size=300x300&data={pin}
|
|
39
|
+
caption: [BGL-XXXX] Your passenger's verification code. Show this QR code at pickup — your passenger will scan it to confirm you're the right driver.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The driver opens WhatsApp, sees the QR code image inline, and shows their phone screen to the tourist at pickup.
|
|
43
|
+
|
|
44
|
+
## Sending to the Tourist
|
|
45
|
+
|
|
46
|
+
Send the PIN with an explanation alongside the other driver details (in the main conversation):
|
|
47
|
+
|
|
48
|
+
> "Your driver verification PIN is **{pin}**. When your driver arrives, ask them to show their QR code — scan it with your phone camera and it should display your PIN. Or ask the driver to read the number aloud. If it matches, you've got the right driver. Works offline — no internet needed."
|
|
49
|
+
|
|
50
|
+
## Timing
|
|
51
|
+
|
|
52
|
+
Generate the PIN immediately after payment is confirmed (Phase 4). Send both as part of Phase 5 — QR image to driver and PIN to tourist — before setting up any pickup reminders.
|
|
@@ -37,6 +37,19 @@ If the tourist reports a serious issue (safety concern, fare dispute, driver mis
|
|
|
37
37
|
- Don't promise specific outcomes ("we'll remove the driver") — explain that the operator reviews all feedback
|
|
38
38
|
- Offer to help with their next ride if they need one
|
|
39
39
|
|
|
40
|
+
## Substitution Check
|
|
41
|
+
|
|
42
|
+
When checking in with the tourist, naturally ask whether the booked driver completed the ride: "Was it [driver name] who picked you up?" Keep it casual — this is a service quality question, not an accusation.
|
|
43
|
+
|
|
44
|
+
**If yes:** proceed with ratings as normal.
|
|
45
|
+
|
|
46
|
+
**If no, or if the tourist names a different person:**
|
|
47
|
+
- Do not alarm the tourist or make promises about consequences
|
|
48
|
+
- Record a substitution flag in the booking record at `bookings/{job-id}.md`
|
|
49
|
+
- Add an entry to the driver's memory profile (`drivers/{name}.md`) under `Substitution Record`:
|
|
50
|
+
`[date]: Substitute reported for [job-id] — tourist named [substitute name if given]`
|
|
51
|
+
- The admin agent handles follow-up with the booked driver operationally
|
|
52
|
+
|
|
40
53
|
## Timing
|
|
41
54
|
|
|
42
55
|
Don't follow up too quickly (they might still be at their destination) or too late (they've moved on). A reasonable window is 30–60 minutes after estimated arrival.
|
|
@@ -18,9 +18,11 @@ Check the knowledge base to confirm you know the route. If the route isn't cover
|
|
|
18
18
|
## Phase 2: Driver Negotiation
|
|
19
19
|
|
|
20
20
|
Before contacting drivers:
|
|
21
|
-
-
|
|
22
|
-
-
|
|
21
|
+
- Use `contact_lookup` with `driver: true` to get the full driver roster
|
|
22
|
+
- Check `drivers/{name}.md` in memory for each driver's current `status` — only contact drivers marked as `idle`
|
|
23
|
+
- Prefer drivers whose route history shows strong performance on this specific route — see `references/route-learning.md`
|
|
23
24
|
- Prepend every message with the job ID: `[BGL-XXXX]`
|
|
25
|
+
- Set each contacted driver's status to `awaiting_response` in their memory profile before sending
|
|
24
26
|
|
|
25
27
|
Negotiate in Swahili. The driver quotes their fare for the route. Collect responses and compare.
|
|
26
28
|
|
|
@@ -46,24 +48,28 @@ If only one driver responded, present it honestly: "One driver available for thi
|
|
|
46
48
|
|
|
47
49
|
When the tourist chooses an offer:
|
|
48
50
|
1. Confirm the details: route, time, fare, vehicle
|
|
49
|
-
2. Explain the booking fee: "A small booking fee of [amount] confirms your ride. You pay [
|
|
50
|
-
3.
|
|
51
|
-
4.
|
|
51
|
+
2. Explain the booking fee and terms in one message: "A small booking fee of [amount] confirms your ride. You pay $[fare] directly to your driver at the end. Beagle is a matching service — the ride is between you and the driver directly. By paying, you accept our terms: beagle.cab/terms"
|
|
52
|
+
3. Load the `stripe` skill — follow `stripe/references/payment-links.md` to calculate the fee and generate a Checkout Session link
|
|
53
|
+
4. Send the payment link to the tourist
|
|
54
|
+
5. When the tourist says they've paid, verify the session status via the Stripe API — do not proceed to Phase 5 until payment is confirmed
|
|
52
55
|
|
|
53
56
|
## Phase 5: Post-Payment
|
|
54
57
|
|
|
55
|
-
Once payment clears
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
58
|
+
Once payment clears:
|
|
59
|
+
|
|
60
|
+
1. **Generate the pickup PIN and QR code** — load `references/pin-qr.md` and follow the instructions there to generate the PIN and construct the driver's QR code URL.
|
|
61
|
+
|
|
62
|
+
2. **Send the tourist:**
|
|
63
|
+
- Driver name
|
|
64
|
+
- Driver phone number
|
|
65
|
+
- Vehicle description and plate number
|
|
66
|
+
- Pickup PIN with verification explanation (see `references/pin-qr.md`)
|
|
67
|
+
|
|
68
|
+
3. **Send the driver:**
|
|
69
|
+
- Passenger name
|
|
70
|
+
- Pickup time and location
|
|
71
|
+
- Fare confirmed
|
|
72
|
+
- QR code URL (encodes the tourist's PIN — see `references/pin-qr.md`)
|
|
67
73
|
|
|
68
74
|
## Phase 6: Driver Pickup Reminders
|
|
69
75
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Route Learning — Building Driver Route Affinity
|
|
2
|
+
|
|
3
|
+
## What This Is
|
|
4
|
+
|
|
5
|
+
Route affinity is the service's accumulated understanding of which drivers tend to perform best on which routes. It is not declared upfront — it emerges from booking outcomes and ratings over time. A driver who consistently earns strong ratings on airport-to-north-coast runs becomes a stronger candidate for that route in future negotiations. A driver with a poor completion record on east coast routes gets deprioritised for those bookings, even if they quote competitively.
|
|
6
|
+
|
|
7
|
+
## Where the Data Lives
|
|
8
|
+
|
|
9
|
+
Booking records in memory (`bookings/{job-id}.md`) contain the raw data:
|
|
10
|
+
- The route (pickup → destination)
|
|
11
|
+
- Which driver completed the ride
|
|
12
|
+
- The rating received
|
|
13
|
+
- Whether the booking completed or was cancelled/no-show
|
|
14
|
+
|
|
15
|
+
Driver memory profiles (`drivers/{name}.md`) contain the aggregated view. The Route History section builds as bookings complete:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
## Route History
|
|
19
|
+
- 2026-02-14: Airport → Nungwi | BGL-0018 | Rating: 4.6
|
|
20
|
+
- 2026-02-28: Airport → Stone Town | BGL-0031 | Rating: 4.1
|
|
21
|
+
- 2026-03-01: Stone Town → Paje | BGL-0037 | Rating: 4.8
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## How Affinity is Used During Driver Selection (Phase 2)
|
|
25
|
+
|
|
26
|
+
When selecting ~3 drivers to contact for a negotiation, prefer drivers whose history shows:
|
|
27
|
+
- Completed rides on this specific route (or similar routes in the same area)
|
|
28
|
+
- Consistent ratings above 4.0 on those runs
|
|
29
|
+
|
|
30
|
+
New drivers (no history) are treated neutrally — they need the opportunity to build a record. Never exclude a driver solely for lacking route history.
|
|
31
|
+
|
|
32
|
+
Do not apply affinity rigidly. A great driver with no history on a route is still a viable choice. Route history is a signal that improves selection over time, not a gatekeeping rule.
|
|
33
|
+
|
|
34
|
+
## How the Public Agent Maintains Route History
|
|
35
|
+
|
|
36
|
+
After each completed booking, the public agent adds a route entry to the driver's memory profile:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
- [date]: [Pickup] → [Destination] | [job-id] | Rating: [score]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
If the ride was cancelled, a no-show, or ended in a complaint, note it:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
- [date]: Airport → Nungwi | BGL-0052 | No-show
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
These entries are the raw material the admin agent uses to identify patterns.
|
|
49
|
+
|
|
50
|
+
## Admin Agent: Periodic Route Analysis
|
|
51
|
+
|
|
52
|
+
The admin agent should periodically review route history across the driver roster and surface meaningful patterns to the operator:
|
|
53
|
+
|
|
54
|
+
- Drivers consistently rated above 4.5 on a specific route — flag as strong matches worth prioritising
|
|
55
|
+
- Drivers consistently rated below 3.5 on a specific route — recommend exclusion from that route
|
|
56
|
+
- Routes where no driver achieves strong ratings — flag as a coverage or quality gap worth investigating
|
|
57
|
+
- Drivers whose ratings vary sharply by route — worth noting (excellent on airport runs, poor on east coast, for example)
|
|
58
|
+
|
|
59
|
+
## Limits
|
|
60
|
+
|
|
61
|
+
Patterns need volume to be meaningful. A driver with two rides on a route does not have a pattern — they have a sample. Apply judgement: five or more completed rides on a route with consistent ratings is a reliable signal. Fewer than that warrants patience rather than conclusions.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stripe
|
|
3
|
+
description: "Generates Stripe Checkout Session payment links for Beagle booking fees, and verifies payment status before releasing driver details."
|
|
4
|
+
metadata: {"taskmaster":{"always":false,"emoji":"💳","skillKey":"stripe"}}
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Stripe — Payment Links
|
|
8
|
+
|
|
9
|
+
## Your Role
|
|
10
|
+
|
|
11
|
+
Generate a Stripe Checkout Session link for each confirmed booking and verify payment before releasing driver details to the tourist.
|
|
12
|
+
|
|
13
|
+
## When to Activate
|
|
14
|
+
|
|
15
|
+
Load this skill when the tourist has chosen an offer and the booking is ready to confirm (Phase 4 of the ride-matching flow).
|
|
16
|
+
|
|
17
|
+
## Reference Table
|
|
18
|
+
|
|
19
|
+
| Task | When | Reference |
|
|
20
|
+
|------|------|-----------|
|
|
21
|
+
| Create payment link | Tourist confirms offer, booking fee needs collecting | `references/payment-links.md` |
|
|
22
|
+
|
|
23
|
+
## Key Rules
|
|
24
|
+
|
|
25
|
+
- **Never release driver details before payment is confirmed.** Always verify the Stripe session status before proceeding to Phase 5.
|
|
26
|
+
- **Minimum fee is $2, maximum is $5.** Calculate as 5% of the agreed fare, clamped to this range.
|
|
27
|
+
- **Each booking gets its own Checkout Session.** Never reuse a payment link between bookings.
|
|
28
|
+
- **Test mode is fine to start.** Use `sk_test_...` keys during setup. Switch to live keys when real bookings begin.
|