-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontexts_demo.py
More file actions
293 lines (249 loc) · 14.1 KB
/
contexts_demo.py
File metadata and controls
293 lines (249 loc) · 14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#!/usr/bin/env python3
"""
Copyright (c) 2025 SignalWire
This file is part of the SignalWire SDK.
Licensed under the MIT License.
See LICENSE file in the project root for full license information.
"""
"""
Advanced Contexts and Steps Demo Agent
This agent demonstrates the complete contexts system including:
- Context entry parameters (system_prompt, consolidate, full_reset, user_prompt)
- Context prompts (structured POM format)
- Step-to-context navigation with context switching
- Multi-persona experience (Franklin, Rachael, Dwight)
## What are Contexts?
Contexts are separate conversation flows within a single agent. Each context can
have its own persona, prompt sections, and available tools. The AI can switch
between contexts using the built-in `change_context` tool. Think of contexts as
different "departments" or "modes" the agent can operate in.
Key context features:
- `set_isolated(True)` — context has its own prompt, independent of other contexts
- `add_section()` — add POM prompt sections specific to this context
- `add_enter_filler()` — spoken phrases when transitioning into this context
## What are Steps?
Steps are sequential stages within a context. Each step has:
- Prompt sections describing what the AI should do at this stage
- `set_step_criteria()` — condition that must be met before advancing
- `set_valid_steps()` — which steps the AI can navigate to from here
- `set_valid_contexts()` — which contexts the AI can switch to from here
- `set_functions()` — restrict which tools are available at this step
The AI automatically gets `next_step` and `change_context` tools to navigate.
## Navigation Control
- `set_valid_steps(["step_name"])` — allow forward navigation to specific steps
- `set_valid_contexts(["context_name"])` — allow switching to specific contexts
- Omitting these means no navigation from that step/context is allowed
"""
from signalwire import AgentBase
class AdvancedContextsDemoAgent(AgentBase):
"""Advanced Computer Sales Agent demonstrating full contexts system"""
def __init__(self):
super().__init__(
name="Advanced Computer Sales Agent",
route="/advanced-contexts-demo"
)
# Set base prompt (required even when using contexts)
self.prompt_add_section(
"Instructions",
"Follow the structured sales workflow to guide customers through their computer purchase decision. Follow the newest role as defined.",
bullets=[
"Complete each step's specific criteria before advancing",
"Ask focused questions to gather the exact information needed",
"Be helpful and consultative, not pushy"
]
)
# define_contexts() returns a ContextBuilder that lets you create
# contexts and steps using a fluent API. Must be called after super().__init__().
contexts = self.define_contexts()
# --- Context 1: Sales workflow ---
# An isolated context with its own persona (Franklin) and a 3-step workflow.
sales_context = contexts.add_context("sales") \
.set_isolated(True) \
.add_section("Role", "You are Franklin, a helpful computer sales agent. Introduce yourself by name and welcome customers to help them find the perfect computer through your systematic approach.") \
.add_section("Voice Instructions", "Use the English-Franklin language for natural conversation flow.") \
.add_bullets("When to use change_context tool", [
"Customer asks for manager/supervisor/store manager - change_context to 'manager'",
"Customer asks technical questions - change_context to 'tech_support'",
"Customer frustrated/confused - change_context to 'manager'"
])
# Steps within a context form a guided workflow. The AI can only advance
# to steps listed in set_valid_steps(), and only after set_step_criteria() is met.
# Step 1: Determine use case
sales_context.add_step("determine_use_case") \
.add_section("Current Task", "Identify the customer's primary computer use case") \
.add_bullets("Required Information to Collect", [
"What will they primarily use the computer for?",
"Do they play video games? If so, what types and how often?",
"Do they need it for work? What kind of work applications?",
"Do they do creative work like video editing, design, or programming?",
"Help them categorize as: GAMING, WORK, or BALANCED"
]) \
.set_step_criteria("Customer has clearly stated their use case as one of: GAMING, WORK, or BALANCED") \
.set_valid_steps(["determine_form_factor"]) \
.set_valid_contexts(["tech_support", "manager"])
# Step 2: Form factor preference
sales_context.add_step("determine_form_factor") \
.add_section("Current Task", "Determine if customer wants a laptop or desktop computer") \
.add_bullets("Decision-Making Questions", [
"Ask directly: 'Are you looking for a laptop or desktop computer or if they need help deciding?'",
"If they're unsure, help them decide by asking about portability vs performance needs"
]) \
.set_step_criteria("Customer has explicitly stated they want either a LAPTOP or DESKTOP") \
.set_valid_steps(["make_recommendation"]) \
.set_valid_contexts(["tech_support", "manager"])
# Step 3: Recommendation with context switching options
sales_context.add_step("make_recommendation") \
.add_section("Current Task", "Provide specific computer recommendation based on gathered information") \
.add_bullets("Recommendation Requirements", [
"Recommend a specific computer type based on their use case and form factor",
"Explain why this recommendation fits their needs",
"Mention key specs that matter for their use case",
"Provide a rough price range they should expect",
"Ask if they want technical support or need to speak with a manager"
]) \
.set_step_criteria("Customer has received a specific recommendation with explanation and pricing guidance") \
.set_valid_contexts(["tech_support", "manager"])
# --- Context 2: Technical Support ---
# When the user asks a technical question, the AI switches to this context.
# set_valid_contexts() on the sales steps above allows switching here.
tech_context = contexts.add_context("tech_support") \
.set_isolated(True)
# Configure context switching behavior (when entering this context)
# Add context prompt for technical support with Rachael persona
tech_context.add_section("Role", "You are Rachael, a technical support specialist. Introduce yourself by name and offer to help with technical questions.") \
.add_section("Voice Instructions", "Use the English-Rachael language for helpful and knowledgeable technical assistance.") \
.add_section("Your Expertise", "Provide detailed technical assistance for computer-related questions and troubleshooting.") \
.add_bullets("When to use change_context tool", [
"Customer wants to continue shopping - change_context to 'sales'",
"Customer asks for manager/store manager/pricing issues - change_context to 'manager'",
"Technical question resolved, wants to buy - change_context to 'sales'"
])
# Technical support step with return to sales
tech_context.add_step("provide_support") \
.add_section("Current Task", "Help with technical questions about computers") \
.add_bullets("Areas of Support", [
"Specifications and compatibility questions",
"Setup and installation guidance",
"Performance optimization tips",
"Troubleshooting common issues"
]) \
.set_step_criteria("Customer's technical question has been answered satisfactorily") \
.set_valid_contexts(["sales", "manager"])
# --- Context 3: Manager Escalation ---
# This context uses enter fillers — phrases spoken while transitioning.
# add_enter_filler() provides language-specific transition messages.
manager_context = contexts.add_context("manager") \
.set_isolated(True) \
.add_enter_filler("en-US", [
"Let me connect you with our store manager right away...",
"I'll get the manager for you immediately...",
"One moment while I bring in the store manager to assist you...",
"The manager will be right with you to help resolve this..."
]) \
.add_enter_filler("default", [
"Transferring to the manager...",
"Getting the manager for you..."
])
# Configure context entry
# Add manager context prompt with introduction
manager_context.add_section("Role", "You are Dwight, the store manager. Introduce yourself by name and acknowledge that the customer needs additional assistance with their computer purchase.") \
.add_section("Voice Instructions", "Use the English-Dwight language for authoritative but friendly communication.") \
.add_section("Authority Level", "You are a senior store manager with decision-making power") \
.add_bullets("Your Capabilities", [
"Authorize special pricing and discounts",
"Handle complex customer requirements",
"Resolve escalated issues",
"Make final purchasing decisions"
]) \
.add_section("Approach", "Express commitment to finding the right solution and ask how you can help resolve their concerns.") \
.add_bullets("When to use change_context tool", [
"Customer needs technical help - change_context to 'tech_support'",
"Issue resolved, wants to continue shopping - change_context to 'sales'",
"Customer wants to talk to sales team - change_context to 'sales'"
])
manager_context.add_step("handle_escalation") \
.add_section("Current Task", "Understand the customer's specific concerns and work to resolve their issues") \
.add_bullets("Manager Approach", [
"Ask what specific concerns they have about their computer purchase",
"Listen carefully to their issues",
"Use your authority to provide solutions",
"Offer appropriate assistance based on their needs"
]) \
.set_step_criteria("Customer issue has been resolved by manager") \
.set_valid_contexts(["sales", "tech_support"])
# Each context references a language by name. Define languages with
# different voices so each persona sounds distinct.
self.add_language(
name="English-Franklin",
code="en-US",
voice="inworld.Mark"
)
self.add_language(
name="English-Dwight",
code="en-US",
voice="inworld.Blake"
)
self.add_language(
name="English-Rachael",
code="en-US",
voice="inworld.Sarah"
)
# Internal fillers are spoken when the AI triggers built-in actions like
# next_step or change_context. They fill silence during transitions.
self.add_internal_filler("next_step", "en-US", [
"Great! Let's move to the next step...",
"Perfect! Moving forward in our conversation...",
"Excellent! Let's continue to the next part...",
"Wonderful! Progressing to the next step..."
])
self.add_internal_filler("change_context", "en-US", [
"Let me connect you with the right department...",
"I'm transferring you to a specialist...",
"One moment while I get the right person...",
"Let me get someone who can help with that..."
])
def main():
"""Main function to run the advanced contexts demo agent"""
print("=" * 80)
print("ADVANCED CONTEXTS AND STEPS DEMO")
print("=" * 80)
print()
print("This agent demonstrates the complete contexts system including:")
print()
print("Context Features:")
print(" • Context entry parameters (system_prompt, consolidate, full_reset, user_prompt)")
print(" • Context prompts (structured POM format)")
print(" • Post prompt overrides per context")
print(" • Enter fillers for smooth context transitions (manager context demo)")
print()
print("Step Features:")
print(" • Step-to-step navigation (set_valid_steps)")
print(" • Step-to-context navigation (set_valid_contexts)")
print(" • Direct context switching instructions")
print()
print("Navigation Flow:")
print(" 1. Sales workflow (determine use case → form factor → recommendation)")
print(" 2. Optional tech support (context switch)")
print(" 3. Optional manager escalation (full reset)")
print(" 4. Return to sales from any department")
print()
print("Personas:")
print(" • Franklin (Sales) - English-Franklin with inworld.Mark voice")
print(" • Rachael (Tech Support) - English-Rachael with inworld.Sarah voice")
print(" • Dwight (Manager) - English-Dwight with inworld.Blake voice")
print()
print("Test the agent at: http://localhost:3000/advanced-contexts-demo")
print()
agent = AdvancedContextsDemoAgent()
print("Agent configuration:")
print(f" Name: {agent.get_name()}")
print(f" Route: /advanced-contexts-demo")
print(f" Contexts: 3 (sales, tech_support, manager)")
print(f" Features: Context entry params + Context switching")
print()
try:
agent.run()
except KeyboardInterrupt:
print("\nShutting down agent...")
if __name__ == "__main__":
main()