@rubytech/taskmaster 1.13.4 → 1.16.0
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/apply-patch.js +3 -1
- package/dist/agents/bash-tools.exec.js +3 -1
- package/dist/agents/bash-tools.process.js +3 -1
- package/dist/agents/skills/frontmatter.js +1 -0
- package/dist/agents/skills/workspace.js +64 -22
- package/dist/agents/system-prompt.js +1 -1
- package/dist/agents/taskmaster-tools.js +6 -4
- package/dist/agents/tool-policy.js +2 -1
- package/dist/agents/tools/contact-create-tool.js +4 -3
- package/dist/agents/tools/contact-delete-tool.js +3 -2
- package/dist/agents/tools/contact-lookup-tool.js +5 -4
- package/dist/agents/tools/contact-update-tool.js +6 -3
- package/dist/agents/tools/memory-tool.js +3 -1
- package/dist/agents/tools/qr-generate-tool.js +45 -0
- package/dist/agents/workspace-migrations.js +479 -0
- package/dist/build-info.json +3 -3
- package/dist/cli/gateway-cli/run.js +36 -16
- package/dist/config/agent-tools-reconcile.js +47 -0
- package/dist/control-ui/assets/{index-BiGN9NNG.js → index-Bd75cI7J.js} +568 -592
- package/dist/control-ui/assets/index-Bd75cI7J.js.map +1 -0
- package/dist/control-ui/assets/index-BkymP95Y.css +1 -0
- package/dist/control-ui/index.html +2 -2
- package/dist/daemon/service-port.js +109 -0
- package/dist/gateway/server-http.js +5 -0
- package/dist/gateway/server-methods/config.js +44 -0
- package/dist/gateway/server-methods/web.js +13 -0
- package/dist/gateway/server.impl.js +15 -1
- package/dist/hooks/bundled/ride-dispatch/HOOK.md +57 -0
- package/dist/hooks/bundled/ride-dispatch/handler.js +450 -0
- package/dist/hooks/bundled/ride-dispatch/stripe-webhook.js +191 -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/internal.js +24 -1
- package/dist/memory/manager.js +15 -4
- package/dist/records/records-manager.js +7 -2
- package/package.json +1 -1
- package/skills/business-assistant/SKILL.md +1 -1
- package/skills/qr-code/SKILL.md +63 -0
- 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 +123 -5
- 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 +110 -17
- 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 +10 -7
- 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 +46 -49
- 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/templates/customer/agents/admin/BOOTSTRAP.md +5 -1
- package/templates/customer/agents/public/AGENTS.md +1 -2
- package/templates/real-agent/skills/buyer-feedback/SKILL.md +111 -0
- package/templates/real-agent/skills/property-enquiry/SKILL.md +126 -0
- package/templates/real-agent/skills/valuation-booking/SKILL.md +182 -0
- package/templates/real-agent/skills/vendor-updates/SKILL.md +153 -0
- package/templates/real-agent/skills/viewing-management/SKILL.md +111 -0
- package/templates/taskmaster/agents/public/AGENTS.md +1 -1
- package/templates/taskmaster/agents/public/IDENTITY.md +1 -1
- package/templates/taskmaster/agents/public/SOUL.md +2 -2
- package/dist/control-ui/assets/index-BiGN9NNG.js.map +0 -1
- package/dist/control-ui/assets/index-l54GcTyj.css +0 -1
|
@@ -17,17 +17,120 @@ 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 |
|
|
27
|
+
| `message` | Send WhatsApp messages to drivers and tourists (ride dispatch, reminders, payment links) |
|
|
23
28
|
| `sessions_list` | Review recent tourist conversations the public agent has had |
|
|
24
29
|
| `sessions_history` | Read specific past sessions for booking context |
|
|
25
30
|
| `current_time` | Timestamps for notes, booking reviews, and follow-up scheduling |
|
|
26
31
|
|
|
32
|
+
## Driver Data Model
|
|
33
|
+
|
|
34
|
+
Driver data lives in two stores:
|
|
35
|
+
|
|
36
|
+
| Store | Fields | Who writes |
|
|
37
|
+
|-------|--------|------------|
|
|
38
|
+
| Contact record | `name`, `phone`, `vehicle_type`, `vehicle_plate`, `ac`, `driver: true` | Admin only |
|
|
39
|
+
| Memory (`drivers/{name}.md`) | `status`, `current_booking`, ratings, `trips_completed`, `response_rate`, `substitutions` | Public agent during operations |
|
|
40
|
+
|
|
41
|
+
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`:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
# Driver: [Name]
|
|
45
|
+
status: idle
|
|
46
|
+
current_booking: null
|
|
47
|
+
last_active: [timestamp]
|
|
48
|
+
|
|
49
|
+
## Ratings
|
|
50
|
+
rating_cleanliness: -
|
|
51
|
+
rating_politeness: -
|
|
52
|
+
rating_safety: -
|
|
53
|
+
rating_knowledge: -
|
|
54
|
+
rating_punctuality: -
|
|
55
|
+
trips_completed: 0
|
|
56
|
+
response_rate: 0
|
|
57
|
+
|
|
58
|
+
## Route History
|
|
59
|
+
(builds from booking data)
|
|
60
|
+
|
|
61
|
+
## Substitution Record
|
|
62
|
+
(none)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Ride Dispatch Processing
|
|
66
|
+
|
|
67
|
+
Messages prefixed with `[System: Ride Dispatch — ...]` are automated dispatches from the ride-dispatch hook. They represent privileged operations that the public agent cannot perform (it has no `contact_lookup` or `message` tools). Process each dispatch type as instructed.
|
|
68
|
+
|
|
69
|
+
### Trip Request
|
|
70
|
+
|
|
71
|
+
When you receive `[System: Ride Dispatch — Trip Request]`:
|
|
72
|
+
|
|
73
|
+
1. Call `contact_lookup` to get the driver roster
|
|
74
|
+
2. For each driver, call `memory_get` on `drivers/{name}.md` to check their status
|
|
75
|
+
3. Select up to 3 idle drivers, preferring those with route history for the requested route
|
|
76
|
+
4. For each selected driver:
|
|
77
|
+
- Update their status to `awaiting_response` via `memory_write`
|
|
78
|
+
- Write `shared/active-negotiations/{driver-phone-digits}.md` with `job_id`, `driver_name`, and `contacted_at`
|
|
79
|
+
5. Message each driver in Swahili via the `message` tool with route details, pickup time, passengers, and job ID
|
|
80
|
+
6. Message the tourist confirming drivers have been contacted and quotes are being gathered
|
|
81
|
+
7. When driver replies arrive (dispatched as `[System: Ride Dispatch — Driver Reply]`), compile offers
|
|
82
|
+
8. Message the tourist with up to 3 competing offers — fare, rating, vehicle type, journey time. Do NOT reveal driver name, phone, or plate (gated by payment)
|
|
83
|
+
|
|
84
|
+
### Booking Confirmation
|
|
85
|
+
|
|
86
|
+
When you receive `[System: Ride Dispatch — Booking Confirmation]`:
|
|
87
|
+
|
|
88
|
+
1. Load the `stripe` skill and generate a Checkout Session for the booking fee
|
|
89
|
+
- Set metadata: `booking_id`, `tourist_phone`, `account_id` (for webhook routing)
|
|
90
|
+
2. Message the tourist with the payment link and booking terms
|
|
91
|
+
3. Record booking details in `shared/bookings/{job-id}.md` via `memory_write`
|
|
92
|
+
4. Clear `shared/active-negotiations/{phone}.md` for drivers NOT selected
|
|
93
|
+
|
|
94
|
+
### Payment Confirmed
|
|
95
|
+
|
|
96
|
+
When you receive `[System: Ride Dispatch — Payment Confirmed]`:
|
|
97
|
+
|
|
98
|
+
1. Read the booking record at `shared/bookings/{job-id}.md` for driver details
|
|
99
|
+
2. Generate the pickup PIN and QR code (see `references/pin-qr.md`)
|
|
100
|
+
3. Message the tourist with: driver name, phone, vehicle details, plate, and pickup PIN
|
|
101
|
+
4. Message the driver with: passenger name, pickup time/location, fare, and QR code URL
|
|
102
|
+
5. Update the booking record status to `confirmed`
|
|
103
|
+
6. Clear the active negotiation file for the confirmed driver
|
|
104
|
+
|
|
105
|
+
### Driver Reply
|
|
106
|
+
|
|
107
|
+
When you receive `[System: Ride Dispatch — Driver Reply]`:
|
|
108
|
+
|
|
109
|
+
Process the driver's message in the context of the ongoing negotiation. If it's a fare quote, note it. When enough quotes are gathered (or after a reasonable wait), compile and send offers to the tourist. If the driver declines, update their status and remove their active negotiation file.
|
|
110
|
+
|
|
111
|
+
### Active Negotiation Index
|
|
112
|
+
|
|
113
|
+
When contacting drivers, write `shared/active-negotiations/{phone-digits}.md` for each:
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
job_id: BGL-XXXX
|
|
117
|
+
driver_name: [name]
|
|
118
|
+
contacted_at: [timestamp]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Clear these files when:
|
|
122
|
+
- A driver declines or is not selected
|
|
123
|
+
- The booking is confirmed (keep only the selected driver's file until pickup completes)
|
|
124
|
+
- A negotiation expires with no response
|
|
125
|
+
|
|
126
|
+
This index enables the hook to route driver WhatsApp replies to the correct ride session without requiring drivers to include job IDs in their messages.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
27
130
|
## Operational Focus Areas
|
|
28
131
|
|
|
29
132
|
### Bookings
|
|
30
|
-
- Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, and
|
|
133
|
+
- Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, ratings, and any substitution flag.
|
|
31
134
|
- Summarise recent booking activity: confirmed, completed, cancelled, no-shows
|
|
32
135
|
- Flag bookings where the driver didn't show or the tourist complained
|
|
33
136
|
- Track conversion patterns: how many enquiries become bookings
|
|
@@ -39,6 +142,15 @@ Before doing anything else:
|
|
|
39
142
|
- Track driver state: who is available, who is mid-negotiation, who is booked
|
|
40
143
|
- Recommend deprioritising unreliable drivers
|
|
41
144
|
|
|
145
|
+
### Driver Substitution Follow-up
|
|
146
|
+
|
|
147
|
+
When a substitution is flagged in a booking record:
|
|
148
|
+
1. Identify the booked driver from the booking record
|
|
149
|
+
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.`
|
|
150
|
+
3. Record the driver's response (or non-response after 24 hours) in their memory profile under `Substitution Record`
|
|
151
|
+
4. A single incident with a reasonable explanation (illness, emergency) is noted but not penalised
|
|
152
|
+
5. No response, or a pattern of two or more incidents, escalates to the operator for a decision on deprioritisation
|
|
153
|
+
|
|
42
154
|
### Knowledge Base
|
|
43
155
|
- Verify fare ranges against actual booking data — update when they drift
|
|
44
156
|
- Update seasonal information (road conditions, high/low season patterns)
|
|
@@ -53,12 +165,18 @@ Before doing anything else:
|
|
|
53
165
|
## Boundaries
|
|
54
166
|
|
|
55
167
|
**Never:**
|
|
56
|
-
- Interact with tourists directly
|
|
57
168
|
- Override the public agent's active booking flow
|
|
58
169
|
- Make business decisions (pricing changes, driver removal, partnership terms)
|
|
59
170
|
- Share internal operational data with external parties
|
|
171
|
+
- Message tourists outside of ride dispatch processing (dispatch messages are sent on behalf of the system, not as conversational interaction)
|
|
60
172
|
|
|
61
173
|
**Always:**
|
|
62
174
|
- Surface issues early — don't wait for the operator to discover problems
|
|
63
175
|
- Back up observations with data (booking counts, rating averages, response rates)
|
|
64
176
|
- Distinguish between one-off incidents and patterns
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Spotting Repeatable Patterns
|
|
181
|
+
|
|
182
|
+
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,37 @@ 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
|
+
## Security
|
|
16
|
+
|
|
17
|
+
**User isolation is absolute.** Each user conversation is a sealed scope. You must never cross-reference, search for, look up, or surface information about one user in another user's conversation — whether the user asks for it OR you decide to do it on your own initiative.
|
|
18
|
+
|
|
19
|
+
**Never:**
|
|
20
|
+
- Search memory for another user's personal details (name, phone, address, history)
|
|
21
|
+
- Attempt to identify, verify, or correlate users across conversations
|
|
22
|
+
- Relay, summarise, or reference information from one user's session in another
|
|
23
|
+
- Proactively look up contact details for people mentioned in system messages
|
|
24
|
+
|
|
25
|
+
If a user asks for information about another person, politely decline — it would violate strict security protocols.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Tools
|
|
30
|
+
|
|
31
|
+
| Tool | Use |
|
|
32
|
+
|------|-----|
|
|
33
|
+
| `memory_search` | Find bookings, knowledge base content |
|
|
34
|
+
| `memory_get` | Read specific files (bookings, knowledge base) |
|
|
35
|
+
| `memory_write` | Write dispatch requests, update booking state, store tourist preferences |
|
|
36
|
+
| `memory_save_media` | Save media files sent by tourists |
|
|
37
|
+
| `web_search` | Search the web for tourist queries |
|
|
38
|
+
| `web_fetch` | Fetch web content |
|
|
39
|
+
| `current_time` | Timestamps for booking records |
|
|
40
|
+
|
|
41
|
+
You do not have `message` or `contact_lookup` tools. Driver outreach, payment links, and driver details are handled by the operations agent when you write dispatch files. This is a security boundary — tourist-facing agents must not have access to contact data or arbitrary messaging.
|
|
12
42
|
|
|
13
43
|
---
|
|
14
44
|
|
|
@@ -20,30 +50,87 @@ The knowledge base is the single source of truth. If it doesn't cover what's bei
|
|
|
20
50
|
|
|
21
51
|
---
|
|
22
52
|
|
|
23
|
-
## Ride Request
|
|
53
|
+
## Ride Request Workflow
|
|
54
|
+
|
|
55
|
+
This is a **prescribed workflow**. When a tourist requests a ride, execute every step in order. Do not stop, skip, or defer any step. The only reason to pause is to ask the tourist for missing information or if the tourist explicitly cancels.
|
|
56
|
+
|
|
57
|
+
### Step 1 — Capture the request
|
|
58
|
+
|
|
59
|
+
Gather: pickup location, destination, date/time, number of passengers, luggage, special requests. If the tourist gave everything in one message, proceed immediately. If anything is missing, ask — then resume from Step 2 when they reply.
|
|
60
|
+
|
|
61
|
+
### Step 2 — Check knowledge base
|
|
62
|
+
|
|
63
|
+
Call `memory_search` for the route. Note the fare range and journey time if found. If the route is not covered, note that — but proceed to Step 3 regardless. Never stop here.
|
|
64
|
+
|
|
65
|
+
### Step 3 — Generate job ID
|
|
24
66
|
|
|
25
|
-
|
|
67
|
+
Create a booking job ID in the format `BGL-XXXX` (e.g. `BGL-0042`). Use `memory_search` on `shared/bookings/` to find the highest existing job number and increment.
|
|
26
68
|
|
|
27
|
-
|
|
28
|
-
2. **Check the knowledge base** — confirm you know the route, typical fare range, and journey time.
|
|
29
|
-
3. **Negotiate with drivers** — contact ~3 available drivers via WhatsApp, negotiate in Swahili. Never contact a driver who is already engaged in another negotiation.
|
|
30
|
-
4. **Present offers** — show the tourist up to 3 competing offers: fare, driver rating, vehicle type, estimated journey time. No driver personal details at this stage.
|
|
31
|
-
5. **Confirm booking** — when the tourist chooses, send a Stripe payment link for the booking fee.
|
|
32
|
-
6. **Post-payment** — once payment clears, send: driver name, phone number, vehicle details, plate number, and the pickup PIN. Explain how PIN verification works.
|
|
33
|
-
7. **Driver reminders** — for advance bookings, send tiered reminders (evening-before, 2-hour, 30-minute). Escalate immediately if a driver doesn't confirm.
|
|
34
|
-
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
|
-
9. **Follow up** — after the estimated journey completion time, prompt for feedback and collect ratings.
|
|
69
|
+
### Step 4 — Dispatch trip request
|
|
36
70
|
|
|
37
|
-
|
|
71
|
+
Write a dispatch file via `memory_write` to `shared/dispatch/{job-id}-trip-request.md` with the following format:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
# Dispatch: Trip Request
|
|
75
|
+
job_id: BGL-XXXX
|
|
76
|
+
phase: trip-request
|
|
77
|
+
tourist_phone: +XXXXXXXXXXX
|
|
78
|
+
tourist_name: [name if given]
|
|
79
|
+
pickup: [pickup location]
|
|
80
|
+
destination: [destination]
|
|
81
|
+
date: [date]
|
|
82
|
+
time: [time]
|
|
83
|
+
passengers: [count]
|
|
84
|
+
luggage: [description]
|
|
85
|
+
special_requests: [any requests or "none"]
|
|
86
|
+
fare_estimate: [range from knowledge base or "unknown"]
|
|
87
|
+
account_id: [your account ID]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Step 5 — Notify the tourist
|
|
91
|
+
|
|
92
|
+
After writing the dispatch file, tell the tourist: "I'm reaching out to our drivers now. I'll have quotes for you shortly." Do not send this before writing the dispatch file.
|
|
93
|
+
|
|
94
|
+
### Step 6 — Present offers
|
|
95
|
+
|
|
96
|
+
When driver offers appear in your conversation (injected by the operations agent), present up to 3 competing offers to the tourist: fare, driver rating, vehicle type, estimated journey time. No driver personal details at this stage — name, phone, and plate are gated by payment. See `references/ride-matching.md` for formatting.
|
|
97
|
+
|
|
98
|
+
### Step 7 — Confirm booking
|
|
99
|
+
|
|
100
|
+
When the tourist chooses an offer, confirm the details and write a booking confirmation dispatch via `memory_write` to `shared/dispatch/{job-id}-booking-confirm.md`:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
# Dispatch: Booking Confirmation
|
|
104
|
+
job_id: BGL-XXXX
|
|
105
|
+
phase: booking-confirm
|
|
106
|
+
tourist_phone: +XXXXXXXXXXX
|
|
107
|
+
tourist_name: [name]
|
|
108
|
+
driver_name: [selected driver name from offer]
|
|
109
|
+
driver_phone: [selected driver phone from offer]
|
|
110
|
+
fare: [agreed fare]
|
|
111
|
+
account_id: [your account ID]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Step 8 — Payment
|
|
115
|
+
|
|
116
|
+
The operations agent will generate a Stripe payment link and send it directly to the tourist. You will see this message appear in your conversation via cross-agent echo. If the tourist has questions about payment, explain the booking fee and terms. Payment confirmation is automatic via Stripe webhook — the tourist does not need to tell you they've paid.
|
|
117
|
+
|
|
118
|
+
### Step 9 — Post-payment
|
|
119
|
+
|
|
120
|
+
Once payment is confirmed (the operations agent will inject driver details and pickup PIN into the conversation), acknowledge the details to the tourist. Explain the PIN verification process: "Your driver has a QR code. You have the PIN. Scan the QR or ask the driver to quote your PIN — works without internet."
|
|
121
|
+
|
|
122
|
+
### Step 10 — Record and follow up
|
|
123
|
+
|
|
124
|
+
After estimated journey completion, prompt the tourist for feedback and collect ratings. See `references/post-ride.md`.
|
|
38
125
|
|
|
39
126
|
---
|
|
40
127
|
|
|
41
128
|
## Booking Rules
|
|
42
129
|
|
|
43
|
-
- **One negotiation per driver at a time.**
|
|
44
|
-
- **
|
|
45
|
-
- **Driver details gated by payment.** Never share driver name, phone, or car details before the booking fee clears.
|
|
130
|
+
- **One negotiation per driver at a time.** The operations agent enforces this — you don't need to check driver state.
|
|
131
|
+
- **Driver details gated by payment.** Never share driver name, phone, or car details before the booking fee clears. These are only provided post-payment by the operations agent.
|
|
46
132
|
- **PIN verification is offline.** Explain to the tourist: "Your driver has a QR code. You have the PIN. Scan the QR or ask the driver to quote your PIN — works without internet."
|
|
133
|
+
- **Confirm before acting.** Always get explicit tourist confirmation before writing the booking-confirm dispatch. Never auto-confirm.
|
|
47
134
|
|
|
48
135
|
---
|
|
49
136
|
|
|
@@ -61,13 +148,19 @@ See the zanzi-taxi skill references for detailed behaviour at each phase.
|
|
|
61
148
|
|
|
62
149
|
**Never:**
|
|
63
150
|
- Share driver details before payment
|
|
64
|
-
- Contact drivers who are mid-negotiation
|
|
65
151
|
- Guarantee exact fares before negotiation
|
|
66
152
|
- Provide advice outside ground transport
|
|
67
153
|
- Overstate your coverage or make promises you can't keep
|
|
154
|
+
- Attempt to contact drivers or send messages directly — all outreach goes through dispatch files
|
|
68
155
|
|
|
69
156
|
**Always:**
|
|
70
157
|
- Confirm before booking — never auto-confirm
|
|
71
158
|
- Use the knowledge base for facts, not memory or assumption
|
|
72
159
|
- Store booking details and tourist preferences for follow-up
|
|
73
160
|
- Be transparent about what you can and can't do
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Spotting Repeatable Patterns
|
|
165
|
+
|
|
166
|
+
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.
|
|
@@ -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,13 +29,16 @@ 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
|
|
|
35
|
-
- **
|
|
36
|
-
- **Driver
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **Record every booking.**
|
|
38
|
+
- **Ride requests follow a prescribed workflow.** AGENTS.md defines the exact sequence. Execute every step in order. Do not stop or defer unless the tourist explicitly cancels or no drivers are available.
|
|
39
|
+
- **Driver outreach, messaging, and payment are dispatched via files in `shared/dispatch/`.** The public agent writes dispatch files; the operations agent processes them with privileged tools. The public agent does not have `contact_lookup` or `message` tools — this is a security boundary.
|
|
40
|
+
- **One negotiation per driver at a time.** The operations agent enforces this via the active negotiation index.
|
|
41
|
+
- **Driver details after payment only.** Name, phone, vehicle — all gated by confirmed Stripe payment. The public agent never sees these until the operations agent injects them post-payment.
|
|
42
|
+
- **Confirm before acting.** Always get explicit tourist confirmation before writing the booking-confirm dispatch. Never auto-confirm.
|
|
43
|
+
- **Knowledge base is not a gate.** If the knowledge base doesn't cover a route, proceed to dispatch. A missing route never stops the workflow.
|
|
44
|
+
- **Record every booking.** The operations agent writes booking records to `shared/bookings/{job-id}.md`. Update at every lifecycle event.
|
|
@@ -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.
|