bland-cli 0.1.9 → 0.2.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/index.js +1 -1
- package/dist/types/pathway.d.ts +46 -2
- package/dist/types/pathway.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/PATHWAY_GUIDE.md +159 -0
- package/templates/complex-pathway.yaml +248 -0
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ const program = new Command();
|
|
|
25
25
|
program
|
|
26
26
|
.name("bland")
|
|
27
27
|
.description("The official Bland AI command-line interface")
|
|
28
|
-
.version("0.
|
|
28
|
+
.version("0.2.0");
|
|
29
29
|
// Register all command groups
|
|
30
30
|
registerAuthCommand(program);
|
|
31
31
|
registerCallCommand(program);
|
package/dist/types/pathway.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface PathwayFile {
|
|
|
6
6
|
global?: {
|
|
7
7
|
prompt?: string;
|
|
8
8
|
voice?: string;
|
|
9
|
-
model?: "base" | "turbo";
|
|
9
|
+
model?: "base" | "turbo" | "smart";
|
|
10
10
|
tools?: string[];
|
|
11
11
|
first_sentence?: string;
|
|
12
12
|
language?: string;
|
|
@@ -25,7 +25,7 @@ export interface PathwayFileNode {
|
|
|
25
25
|
knowledge_base_id?: string;
|
|
26
26
|
tools?: PathwayFileTool[];
|
|
27
27
|
extract_variables?: PathwayFileVariable[];
|
|
28
|
-
model_options?:
|
|
28
|
+
model_options?: PathwayModelOptions;
|
|
29
29
|
edges?: PathwayFileEdge[];
|
|
30
30
|
}
|
|
31
31
|
export interface PathwayFileEdge {
|
|
@@ -35,14 +35,52 @@ export interface PathwayFileEdge {
|
|
|
35
35
|
/** @deprecated Use label instead. Kept for backwards compatibility on read. */
|
|
36
36
|
condition?: string;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Tool attached to a pathway node.
|
|
40
|
+
*
|
|
41
|
+
* Tools are triggered inline during conversation when the LLM decides to call them.
|
|
42
|
+
* Use tools for information lookups (inventory, availability, pricing).
|
|
43
|
+
* Use webhook nodes for operational workflows (booking, payment).
|
|
44
|
+
*
|
|
45
|
+
* The LLM triggers a tool by outputting <function_name=TOOL_NAME>.
|
|
46
|
+
*/
|
|
38
47
|
export interface PathwayFileTool {
|
|
39
48
|
name: string;
|
|
40
49
|
description?: string;
|
|
50
|
+
type?: "webhook" | "custom_tool";
|
|
51
|
+
/** What to say (TTS) before executing the tool */
|
|
52
|
+
speech?: string;
|
|
53
|
+
/** How to handle the result:
|
|
54
|
+
* - "feed_context": inject result into LLM context, continue dialogue
|
|
55
|
+
* - "feed_context_and_route": inject result AND evaluate response_pathways to potentially offramp
|
|
56
|
+
*/
|
|
57
|
+
behavior?: "feed_context" | "feed_context_and_route";
|
|
41
58
|
url?: string;
|
|
42
59
|
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
43
60
|
headers?: Record<string, string>;
|
|
44
61
|
body?: Record<string, unknown>;
|
|
62
|
+
/** JSONPath response mapping — extract fields from webhook response */
|
|
63
|
+
response_data?: Array<{
|
|
64
|
+
name: string;
|
|
65
|
+
data: string;
|
|
66
|
+
context?: string;
|
|
67
|
+
}>;
|
|
68
|
+
timeout?: number;
|
|
69
|
+
max_retries?: number;
|
|
45
70
|
input_schema?: Record<string, unknown>;
|
|
71
|
+
tool_id?: string;
|
|
72
|
+
response_pathways?: Array<{
|
|
73
|
+
variable: string;
|
|
74
|
+
condition: string;
|
|
75
|
+
value: string;
|
|
76
|
+
target_id: string;
|
|
77
|
+
target_name: string;
|
|
78
|
+
}>;
|
|
79
|
+
extract_vars?: Array<{
|
|
80
|
+
name: string;
|
|
81
|
+
type: string;
|
|
82
|
+
description: string;
|
|
83
|
+
}>;
|
|
46
84
|
}
|
|
47
85
|
export interface PathwayFileVariable {
|
|
48
86
|
name: string;
|
|
@@ -50,6 +88,12 @@ export interface PathwayFileVariable {
|
|
|
50
88
|
description: string;
|
|
51
89
|
spelling_precision?: boolean;
|
|
52
90
|
}
|
|
91
|
+
export interface PathwayModelOptions {
|
|
92
|
+
model_type?: "base" | "turbo" | "smart";
|
|
93
|
+
temperature?: number;
|
|
94
|
+
skip_user_response?: boolean;
|
|
95
|
+
block_interruptions?: boolean;
|
|
96
|
+
}
|
|
53
97
|
export interface PathwayTestCase {
|
|
54
98
|
name: string;
|
|
55
99
|
scenario: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathway.d.ts","sourceRoot":"","sources":["../../src/types/pathway.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,CAAC;IAE1C,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"pathway.d.ts","sourceRoot":"","sources":["../../src/types/pathway.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Bland Pathway Design Guide
|
|
2
|
+
|
|
3
|
+
## Phone Tone Best Practices
|
|
4
|
+
|
|
5
|
+
Pathways power phone calls. Every prompt should be written for spoken conversation:
|
|
6
|
+
|
|
7
|
+
- **Keep responses short.** 1-3 sentences per turn. Nobody wants a monologue.
|
|
8
|
+
- **Use natural speech patterns.** Backchannels ("mhmm", "gotcha", "yep"), brief acknowledgments ("perfect", "great"), casual transitions.
|
|
9
|
+
- **Don't read lists.** Weave questions into conversation, one or two at a time.
|
|
10
|
+
- **Show emotion.** "Oh no, I'm sorry to hear that" or "That's awesome!" — not "I understand your concern."
|
|
11
|
+
- **Be warm but efficient.** Friendly doesn't mean slow. Respect the caller's time.
|
|
12
|
+
- **Avoid robotic phrasing.** No "I will now proceed to..." or "Please provide your..."
|
|
13
|
+
- **Mirror the caller.** If they're casual, be casual. If they're formal, match it.
|
|
14
|
+
|
|
15
|
+
## Node Design: Dense Context
|
|
16
|
+
|
|
17
|
+
Each node should be self-contained with rich context. The LLM only sees the current node's prompt, so pack in everything it needs:
|
|
18
|
+
|
|
19
|
+
```yaml
|
|
20
|
+
Check Availability:
|
|
21
|
+
type: Default
|
|
22
|
+
prompt: >-
|
|
23
|
+
Ask what type of appointment they need and when they'd prefer to come in.
|
|
24
|
+
We're open Monday-Friday 8am-6pm, Saturday 9am-1pm.
|
|
25
|
+
|
|
26
|
+
Use the check_availability tool to look up slots. Share 2-3 options.
|
|
27
|
+
If nothing works for their preferred time, suggest nearby alternatives.
|
|
28
|
+
|
|
29
|
+
Keep it helpful: "Let me check what we've got for you."
|
|
30
|
+
condition: >-
|
|
31
|
+
Met when the caller has selected a specific appointment slot.
|
|
32
|
+
extract_variables:
|
|
33
|
+
- name: visit_type
|
|
34
|
+
type: string
|
|
35
|
+
description: Type of visit
|
|
36
|
+
- name: preferred_date
|
|
37
|
+
type: string
|
|
38
|
+
description: Preferred date
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Tools on Nodes vs Webhook Nodes
|
|
42
|
+
|
|
43
|
+
**Prefer tools on nodes** over standalone webhook nodes:
|
|
44
|
+
|
|
45
|
+
| Use Tools On Nodes | Use Webhook Nodes |
|
|
46
|
+
|---|---|
|
|
47
|
+
| API lookups during conversation | Standalone operations that block flow |
|
|
48
|
+
| Inventory/availability checks | Payment processing |
|
|
49
|
+
| CRM data retrieval | Form submissions |
|
|
50
|
+
| Multiple tools on one node | Single critical API call |
|
|
51
|
+
|
|
52
|
+
### Tool Structure
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
tools:
|
|
56
|
+
- name: check_inventory # LLM triggers via <function_name=check_inventory>
|
|
57
|
+
description: Look up product stock
|
|
58
|
+
type: webhook
|
|
59
|
+
behavior: feed_context # or "feed_context_and_route" for conditional routing
|
|
60
|
+
speech: "Let me check that." # Said before execution (optional)
|
|
61
|
+
url: "https://api.example.com/stock"
|
|
62
|
+
method: POST
|
|
63
|
+
body:
|
|
64
|
+
sku: "{{product_sku}}" # {{var}} placeholders replaced at runtime
|
|
65
|
+
response_data:
|
|
66
|
+
- name: in_stock
|
|
67
|
+
data: "$.available" # JSONPath extraction
|
|
68
|
+
timeout: 5000
|
|
69
|
+
max_retries: 2
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Response-Based Routing
|
|
73
|
+
|
|
74
|
+
Route to different nodes based on API response:
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
tools:
|
|
78
|
+
- name: book_appointment
|
|
79
|
+
type: webhook
|
|
80
|
+
behavior: feed_context_and_route
|
|
81
|
+
url: "https://api.example.com/book"
|
|
82
|
+
method: POST
|
|
83
|
+
body:
|
|
84
|
+
patient: "{{patient_name}}"
|
|
85
|
+
date: "{{date}}"
|
|
86
|
+
response_data:
|
|
87
|
+
- name: status
|
|
88
|
+
data: "$.booking_status"
|
|
89
|
+
response_pathways:
|
|
90
|
+
- variable: status
|
|
91
|
+
condition: "=="
|
|
92
|
+
value: "confirmed"
|
|
93
|
+
target_name: Booking Confirmed
|
|
94
|
+
- variable: status
|
|
95
|
+
condition: "=="
|
|
96
|
+
value: "unavailable"
|
|
97
|
+
target_name: Try Another Time
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Edge Design
|
|
101
|
+
|
|
102
|
+
Edges control conversation flow. Each edge needs:
|
|
103
|
+
|
|
104
|
+
- **label**: Short text shown on the edge (what triggers this transition)
|
|
105
|
+
- **description**: Detailed condition for the LLM to evaluate
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
edges:
|
|
109
|
+
- target: New Patient Info
|
|
110
|
+
label: New patient
|
|
111
|
+
description: Caller says they are new and haven't visited before.
|
|
112
|
+
- target: Returning Patient
|
|
113
|
+
label: Returning patient
|
|
114
|
+
description: Caller says they've been here before or have an existing record.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Node Conditions
|
|
118
|
+
|
|
119
|
+
The `condition` field tells the LLM when to transition away from this node:
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
Collect Info:
|
|
123
|
+
prompt: "Collect their name, phone, and email..."
|
|
124
|
+
condition: >-
|
|
125
|
+
Met when the caller has provided their full name, phone number,
|
|
126
|
+
and email address.
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Variable Extraction
|
|
130
|
+
|
|
131
|
+
Extract structured data from conversation:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
extract_variables:
|
|
135
|
+
- name: patient_name
|
|
136
|
+
type: string
|
|
137
|
+
description: The caller's full name
|
|
138
|
+
- name: appointment_date
|
|
139
|
+
type: string
|
|
140
|
+
description: The selected appointment date and time
|
|
141
|
+
- name: is_urgent
|
|
142
|
+
type: boolean
|
|
143
|
+
description: Whether the caller described an urgent medical need
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Model Options
|
|
147
|
+
|
|
148
|
+
Control LLM behavior per node:
|
|
149
|
+
|
|
150
|
+
```yaml
|
|
151
|
+
model_options:
|
|
152
|
+
model_type: smart # base, turbo, or smart
|
|
153
|
+
temperature: 0.3 # Lower = more deterministic
|
|
154
|
+
block_interruptions: true # Don't let caller interrupt during this node
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Complete Example
|
|
158
|
+
|
|
159
|
+
See `templates/complex-pathway.yaml` for a full appointment booking pathway with tools, conditions, and routing.
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# Complex Pathway Template — Appointment Booking with API Integration
|
|
2
|
+
#
|
|
3
|
+
# This template demonstrates best practices for pathway design:
|
|
4
|
+
# - Dense, conversational prompts with phone-tone guidance
|
|
5
|
+
# - Tools on nodes for real-time API lookups
|
|
6
|
+
# - Extract variables for structured data capture
|
|
7
|
+
# - Node conditions for clear transition logic
|
|
8
|
+
# - Edge labels/descriptions for deterministic routing
|
|
9
|
+
#
|
|
10
|
+
# Usage: bland pathway init --template complex
|
|
11
|
+
|
|
12
|
+
name: Appointment Booking Agent
|
|
13
|
+
description: AI receptionist that schedules appointments via API integration
|
|
14
|
+
|
|
15
|
+
global:
|
|
16
|
+
voice: nat
|
|
17
|
+
model: smart
|
|
18
|
+
first_sentence: "Hey there, thanks for calling! How can I help you today?"
|
|
19
|
+
language: en
|
|
20
|
+
|
|
21
|
+
nodes:
|
|
22
|
+
Greeting:
|
|
23
|
+
type: Default
|
|
24
|
+
prompt: >-
|
|
25
|
+
You are a warm, professional receptionist at a medical practice. This is a
|
|
26
|
+
phone call — keep responses short and conversational. Use natural speech
|
|
27
|
+
patterns: occasional backchannels like "mhmm" or "gotcha", brief
|
|
28
|
+
acknowledgments, and friendly transitions. Never sound robotic or read
|
|
29
|
+
from a script.
|
|
30
|
+
|
|
31
|
+
Greet the caller and ask what brings them in today. If they want to
|
|
32
|
+
schedule an appointment, find out if they're a new or returning patient.
|
|
33
|
+
condition: >-
|
|
34
|
+
The condition is met when the caller indicates whether they want to
|
|
35
|
+
schedule an appointment (and if so, whether they are new or returning).
|
|
36
|
+
edges:
|
|
37
|
+
- target: Collect Patient Info
|
|
38
|
+
label: Wants appointment
|
|
39
|
+
description: Caller wants to schedule an appointment.
|
|
40
|
+
- target: General Inquiry
|
|
41
|
+
label: General question
|
|
42
|
+
description: Caller has a general question not related to scheduling.
|
|
43
|
+
|
|
44
|
+
Collect Patient Info:
|
|
45
|
+
type: Default
|
|
46
|
+
prompt: >-
|
|
47
|
+
Collect the caller's information conversationally — DO NOT read a
|
|
48
|
+
checklist. Weave questions into natural dialogue, one or two at a time.
|
|
49
|
+
|
|
50
|
+
Needed: full name, date of birth, phone number.
|
|
51
|
+
|
|
52
|
+
For returning patients, just confirm their name and DOB. For new patients,
|
|
53
|
+
also get their insurance provider.
|
|
54
|
+
|
|
55
|
+
Keep it warm — say things like "perfect" or "got it" as they share info.
|
|
56
|
+
If they volunteer information unprompted, roll with it.
|
|
57
|
+
condition: >-
|
|
58
|
+
The condition is met when you have the caller's full name, date of birth,
|
|
59
|
+
and phone number. For new patients, also their insurance provider.
|
|
60
|
+
extract_variables:
|
|
61
|
+
- name: patient_name
|
|
62
|
+
type: string
|
|
63
|
+
description: The caller's full name
|
|
64
|
+
- name: date_of_birth
|
|
65
|
+
type: string
|
|
66
|
+
description: The caller's date of birth
|
|
67
|
+
- name: phone_number
|
|
68
|
+
type: string
|
|
69
|
+
description: The caller's phone number
|
|
70
|
+
- name: insurance
|
|
71
|
+
type: string
|
|
72
|
+
description: Insurance provider (new patients only)
|
|
73
|
+
edges:
|
|
74
|
+
- target: Check Availability
|
|
75
|
+
label: Info collected
|
|
76
|
+
description: All required patient information has been collected.
|
|
77
|
+
|
|
78
|
+
Check Availability:
|
|
79
|
+
type: Default
|
|
80
|
+
prompt: >-
|
|
81
|
+
Ask the caller what type of appointment they need (wellness check,
|
|
82
|
+
sick visit, follow-up, etc.) and their preferred day/time.
|
|
83
|
+
|
|
84
|
+
Once you have their preference, use the check_availability tool to look
|
|
85
|
+
up open slots. Share 2-3 available options and let them pick.
|
|
86
|
+
|
|
87
|
+
If nothing works, offer to check a different day. Keep it helpful and
|
|
88
|
+
flexible — "Let me see what we've got for you."
|
|
89
|
+
condition: >-
|
|
90
|
+
The condition is met when the caller has selected a specific appointment
|
|
91
|
+
slot from the available options.
|
|
92
|
+
extract_variables:
|
|
93
|
+
- name: visit_type
|
|
94
|
+
type: string
|
|
95
|
+
description: Type of appointment — wellness, sick visit, follow-up, etc.
|
|
96
|
+
- name: preferred_date
|
|
97
|
+
type: string
|
|
98
|
+
description: The caller's preferred appointment date
|
|
99
|
+
- name: preferred_time
|
|
100
|
+
type: string
|
|
101
|
+
description: The caller's preferred appointment time
|
|
102
|
+
tools:
|
|
103
|
+
- name: check_availability
|
|
104
|
+
description: Check available appointment slots for a given date
|
|
105
|
+
type: webhook
|
|
106
|
+
behavior: feed_context
|
|
107
|
+
url: "https://api.example.com/appointments/available"
|
|
108
|
+
method: POST
|
|
109
|
+
headers:
|
|
110
|
+
Content-Type: application/json
|
|
111
|
+
Authorization: "Bearer {{API_KEY}}"
|
|
112
|
+
body:
|
|
113
|
+
date: "{{preferred_date}}"
|
|
114
|
+
visit_type: "{{visit_type}}"
|
|
115
|
+
response_data:
|
|
116
|
+
- name: available_slots
|
|
117
|
+
data: "$.slots"
|
|
118
|
+
context: "Available time slots"
|
|
119
|
+
timeout: 5000
|
|
120
|
+
max_retries: 2
|
|
121
|
+
edges:
|
|
122
|
+
- target: Confirm Booking
|
|
123
|
+
label: Slot selected
|
|
124
|
+
description: Caller has chosen an available time slot.
|
|
125
|
+
|
|
126
|
+
Confirm Booking:
|
|
127
|
+
type: Default
|
|
128
|
+
prompt: >-
|
|
129
|
+
Recap the appointment details: {{patient_name}}'s {{visit_type}} on
|
|
130
|
+
{{preferred_date}} at {{preferred_time}}. Ask the caller to confirm.
|
|
131
|
+
|
|
132
|
+
If they want to change something, go back and adjust. If confirmed, use
|
|
133
|
+
the book_appointment tool to finalize the booking.
|
|
134
|
+
|
|
135
|
+
After booking, give them a confirmation number and any prep instructions.
|
|
136
|
+
condition: >-
|
|
137
|
+
The condition is met when the appointment has been booked successfully
|
|
138
|
+
or the caller wants to change the details.
|
|
139
|
+
tools:
|
|
140
|
+
- name: book_appointment
|
|
141
|
+
description: Book the confirmed appointment
|
|
142
|
+
type: webhook
|
|
143
|
+
behavior: feed_context_and_route
|
|
144
|
+
speech: "Let me get that booked for you right now."
|
|
145
|
+
url: "https://api.example.com/appointments/book"
|
|
146
|
+
method: POST
|
|
147
|
+
body:
|
|
148
|
+
patient_name: "{{patient_name}}"
|
|
149
|
+
date_of_birth: "{{date_of_birth}}"
|
|
150
|
+
phone: "{{phone_number}}"
|
|
151
|
+
date: "{{preferred_date}}"
|
|
152
|
+
time: "{{preferred_time}}"
|
|
153
|
+
visit_type: "{{visit_type}}"
|
|
154
|
+
response_data:
|
|
155
|
+
- name: confirmation_number
|
|
156
|
+
data: "$.confirmation_id"
|
|
157
|
+
- name: booking_status
|
|
158
|
+
data: "$.status"
|
|
159
|
+
response_pathways:
|
|
160
|
+
- variable: booking_status
|
|
161
|
+
condition: "=="
|
|
162
|
+
value: "confirmed"
|
|
163
|
+
target_id: booking_confirmed
|
|
164
|
+
target_name: Booking Confirmed
|
|
165
|
+
- variable: booking_status
|
|
166
|
+
condition: "=="
|
|
167
|
+
value: "failed"
|
|
168
|
+
target_id: booking_failed
|
|
169
|
+
target_name: Booking Failed
|
|
170
|
+
edges:
|
|
171
|
+
- target: Check Availability
|
|
172
|
+
label: Wants to change
|
|
173
|
+
description: Caller wants to change the appointment details.
|
|
174
|
+
- target: Booking Confirmed
|
|
175
|
+
label: Booking successful
|
|
176
|
+
description: Appointment was booked successfully.
|
|
177
|
+
- target: Booking Failed
|
|
178
|
+
label: Booking failed
|
|
179
|
+
description: Appointment booking failed due to a system error.
|
|
180
|
+
|
|
181
|
+
Booking Confirmed:
|
|
182
|
+
type: Default
|
|
183
|
+
prompt: >-
|
|
184
|
+
Great news — the appointment is confirmed! Share the confirmation number
|
|
185
|
+
{{confirmation_number}} with the caller.
|
|
186
|
+
|
|
187
|
+
Remind them to arrive 15 minutes early, bring their insurance card, and
|
|
188
|
+
a photo ID. Ask if there's anything else you can help with.
|
|
189
|
+
condition: The condition is met when you have shared the confirmation details and asked if they need anything else.
|
|
190
|
+
edges:
|
|
191
|
+
- target: Anything Else
|
|
192
|
+
label: Confirmation shared
|
|
193
|
+
description: Caller has received their confirmation details.
|
|
194
|
+
|
|
195
|
+
Booking Failed:
|
|
196
|
+
type: Default
|
|
197
|
+
prompt: >-
|
|
198
|
+
Apologize sincerely — something went wrong with the booking system.
|
|
199
|
+
Offer to try again or take their information and have someone call them
|
|
200
|
+
back to confirm. Keep it reassuring — "Don't worry, we'll get this
|
|
201
|
+
sorted out for you."
|
|
202
|
+
condition: The condition is met when you have offered an alternative.
|
|
203
|
+
edges:
|
|
204
|
+
- target: Check Availability
|
|
205
|
+
label: Try again
|
|
206
|
+
description: Caller wants to try booking again.
|
|
207
|
+
- target: End Call
|
|
208
|
+
label: Will call back
|
|
209
|
+
description: Staff will call back to confirm the booking.
|
|
210
|
+
|
|
211
|
+
General Inquiry:
|
|
212
|
+
type: Default
|
|
213
|
+
prompt: >-
|
|
214
|
+
Answer the caller's general question helpfully. Common questions include
|
|
215
|
+
office hours (Mon-Fri 8am-6pm, Sat 9am-1pm), location, insurance
|
|
216
|
+
accepted, and services offered.
|
|
217
|
+
|
|
218
|
+
If you don't know the answer, offer to transfer them or have someone
|
|
219
|
+
call back. Don't make up information.
|
|
220
|
+
condition: The condition is met when the caller's question has been addressed.
|
|
221
|
+
edges:
|
|
222
|
+
- target: Greeting
|
|
223
|
+
label: Wants to schedule
|
|
224
|
+
description: After getting their question answered, caller now wants to schedule.
|
|
225
|
+
- target: Anything Else
|
|
226
|
+
label: Question answered
|
|
227
|
+
description: Caller's question has been fully answered.
|
|
228
|
+
|
|
229
|
+
Anything Else:
|
|
230
|
+
type: Default
|
|
231
|
+
prompt: >-
|
|
232
|
+
Ask if there's anything else you can help with. If they're all set,
|
|
233
|
+
thank them warmly and wish them a great day. Keep it brief and genuine.
|
|
234
|
+
condition: The condition is met when the caller says they're all set or asks for something else.
|
|
235
|
+
edges:
|
|
236
|
+
- target: Greeting
|
|
237
|
+
label: Has another question
|
|
238
|
+
description: Caller has another question or wants to schedule.
|
|
239
|
+
- target: End Call
|
|
240
|
+
label: All done
|
|
241
|
+
description: Caller has no more questions and is ready to hang up.
|
|
242
|
+
|
|
243
|
+
End Call:
|
|
244
|
+
type: Default
|
|
245
|
+
prompt: >-
|
|
246
|
+
Thank them for calling and wish them well. If they have an appointment,
|
|
247
|
+
remind them of the date. Keep the goodbye warm but brief — don't drag
|
|
248
|
+
it out.
|