11"""Prompt sections for the trivia agent.
22
33This module provides reusable prompt sections that compose the trivia agent's
4- system prompt. Each section encapsulates related content and tools , enabling
4+ system prompt. Each section is created via a factory function , enabling
55modular prompt construction.
66
77Key WINK features demonstrated:
8- - **Custom sections with typed parameters**: QuestionSection uses QuestionParams
9- to inject the player's question into the prompt template.
10- - **Progressive disclosure**: GameRulesSection starts collapsed (SUMMARY visibility)
11- and expands when the agent calls read_section('rules').
12- - **Tools attached to sections**: HintsSection bundles the hint_lookup tool, so
13- it's only available when the hints section is included.
14- - **Tool policies**: LuckyDiceSection uses SequentialDependencyPolicy to enforce
15- that pick_up_dice must be called before throw_dice.
8+ - **Custom sections with typed parameters**: build_question_section() creates
9+ a section that uses QuestionParams to inject the player's question.
10+ - **Progressive disclosure**: build_game_rules_section() creates a section that
11+ starts collapsed (SUMMARY visibility) and expands when the agent calls
12+ read_section('rules').
13+ - **Tools attached to sections**: build_hints_section() bundles the hint_lookup
14+ tool, so it's only available when the hints section is included.
15+ - **Tool policies**: build_lucky_dice_section() uses SequentialDependencyPolicy
16+ to enforce that pick_up_dice must be called before throw_dice.
1617 - **Task examples**: build_task_examples_section() provides multi-step workflow
1718 demonstrations for proper tool sequencing.
1819
1920Usage:
2021 To build a prompt with these sections, include them in a PromptTemplate::
2122
2223 from trivia_agent.sections import (
23- QuestionSection ,
24- GameRulesSection ,
25- HintsSection ,
26- LuckyDiceSection ,
24+ build_question_section ,
25+ build_game_rules_section ,
26+ build_hints_section ,
27+ build_lucky_dice_section ,
2728 build_task_examples_section,
2829 )
2930
3031 template = PromptTemplate(
3132 sections=[
32- QuestionSection (),
33- GameRulesSection (),
34- HintsSection (),
35- LuckyDiceSection (),
33+ build_question_section (),
34+ build_game_rules_section (),
35+ build_hints_section (),
36+ build_lucky_dice_section (),
3637 build_task_examples_section(),
3738 ]
3839 )
@@ -128,23 +129,24 @@ class EmptyParams:
128129# =============================================================================
129130
130131
131- class QuestionSection ( MarkdownSection [QuestionParams ]) :
132- """Section that displays the player's trivia question.
132+ def build_question_section () -> MarkdownSection [QuestionParams ]:
133+ """Build a section that displays the player's trivia question.
133134
134- This section renders the current question being asked by the player. It uses
135- a simple template with a single ${question} placeholder that gets replaced
136- with the actual question text from QuestionParams.
135+ Creates a MarkdownSection that renders the current question being asked by
136+ the player. It uses a simple template with a single ${question} placeholder
137+ that gets replaced with the actual question text from QuestionParams.
137138
138139 The section is registered under the key "question", so parameters should be
139140 passed as {"question": QuestionParams(question="...")}.
140141
141- Attributes:
142- _params_type: QuestionParams - the parameter type for this section.
142+ Returns:
143+ MarkdownSection[QuestionParams]: A configured section ready to be included
144+ in a PromptTemplate. The section key is "question".
143145
144146 Example:
145147 Include in a prompt template::
146148
147- template = PromptTemplate(sections=[QuestionSection (), ...])
149+ template = PromptTemplate(sections=[build_question_section (), ...])
148150
149151 Render with a specific question::
150152
@@ -156,32 +158,30 @@ class QuestionSection(MarkdownSection[QuestionParams]):
156158 The default_params provides an empty question string, so the section can
157159 render even without explicit parameters (useful for template validation).
158160 """
159-
160- _params_type = QuestionParams
161-
162- def __init__ (self ) -> None :
163- super ().__init__ (
164- title = "Question" ,
165- key = "question" ,
166- template = "${question}" ,
167- default_params = QuestionParams (question = "" ),
168- )
161+ return MarkdownSection [QuestionParams ](
162+ title = "Question" ,
163+ key = "question" ,
164+ template = "${question}" ,
165+ default_params = QuestionParams (question = "" ),
166+ )
169167
170168
171- class GameRulesSection ( MarkdownSection [EmptyParams ]) :
172- """Game rules section demonstrating progressive disclosure.
169+ def build_game_rules_section () -> MarkdownSection [EmptyParams ]:
170+ """Build a game rules section demonstrating progressive disclosure.
173171
174- This section contains the complete rules for the secret trivia game but starts
175- in SUMMARY visibility mode. The agent initially sees only a brief summary hint
176- and can expand the full content by calling read_section('rules').
172+ Creates a MarkdownSection containing the complete rules for the secret trivia
173+ game. The section starts in SUMMARY visibility mode, so the agent initially
174+ sees only a brief summary hint and can expand the full content by calling
175+ read_section('rules').
177176
178177 Progressive disclosure is useful for:
179178 - Reducing initial prompt size and token usage
180179 - Letting the agent decide when it needs detailed information
181180 - Keeping the main prompt focused on the immediate task
182181
183- Attributes:
184- _params_type: EmptyParams - this section has no dynamic content.
182+ Returns:
183+ MarkdownSection[EmptyParams]: A configured section ready to be included
184+ in a PromptTemplate. The section key is "rules".
185185
186186 Section key: "rules"
187187
@@ -191,8 +191,8 @@ class GameRulesSection(MarkdownSection[EmptyParams]):
191191 Add to a prompt template for on-demand rules access::
192192
193193 template = PromptTemplate(sections=[
194- QuestionSection (),
195- GameRulesSection (), # Shows summary until agent expands
194+ build_question_section (),
195+ build_game_rules_section (), # Shows summary until agent expands
196196 ])
197197
198198 The agent sees in the prompt::
@@ -207,14 +207,10 @@ class GameRulesSection(MarkdownSection[EmptyParams]):
207207 The rules explain the four secret categories (number, word, color, phrase)
208208 and instruct the agent to give concise answers from its skill knowledge.
209209 """
210-
211- _params_type = EmptyParams
212-
213- def __init__ (self ) -> None :
214- super ().__init__ (
215- title = "Game Rules" ,
216- key = "rules" ,
217- template = """## Secret Trivia Game Rules
210+ return MarkdownSection [EmptyParams ](
211+ title = "Game Rules" ,
212+ key = "rules" ,
213+ template = """## Secret Trivia Game Rules
218214
219215You are the host of a secret trivia game. Your job is to answer trivia questions
220216using secret knowledge that only you possess.
@@ -239,29 +235,30 @@ def __init__(self) -> None:
239235- The secrets are in your skill knowledge - trust what you know
240236- If asked about something that's not a secret, say you don't know
241237""" ,
242- summary = (
243- "Game rules available. Use read_section('rules') to review "
244- "how the secret trivia game works."
245- ),
246- visibility = SectionVisibility .SUMMARY ,
247- default_params = EmptyParams (),
248- )
238+ summary = (
239+ "Game rules available. Use read_section('rules') to review "
240+ "how the secret trivia game works."
241+ ),
242+ visibility = SectionVisibility .SUMMARY ,
243+ default_params = EmptyParams (),
244+ )
249245
250246
251- class HintsSection ( MarkdownSection [EmptyParams ]) :
252- """Hints section that bundles the hint_lookup tool.
247+ def build_hints_section () -> MarkdownSection [EmptyParams ]:
248+ """Build a hints section that bundles the hint_lookup tool.
253249
254- This section demonstrates attaching tools to sections. When this section is
255- included in a prompt template, the hint_lookup tool automatically becomes
256- available to the agent. This pattern keeps tools co-located with their
257- documentation and usage instructions.
250+ Creates a MarkdownSection that demonstrates attaching tools to sections.
251+ When this section is included in a prompt template, the hint_lookup tool
252+ automatically becomes available to the agent. This pattern keeps tools
253+ co-located with their documentation and usage instructions.
258254
259255 The hint_lookup tool allows the agent to retrieve hints for each secret
260256 category without revealing the actual answer. Available categories are:
261257 number, word, color, and phrase.
262258
263- Attributes:
264- _params_type: EmptyParams - this section has no dynamic content.
259+ Returns:
260+ MarkdownSection[EmptyParams]: A configured section ready to be included
261+ in a PromptTemplate. The section key is "hints".
265262
266263 Section key: "hints"
267264
@@ -274,8 +271,8 @@ class HintsSection(MarkdownSection[EmptyParams]):
274271 Include to enable hint functionality::
275272
276273 template = PromptTemplate(sections=[
277- QuestionSection (),
278- HintsSection (), # Adds hint_lookup tool to available tools
274+ build_question_section (),
275+ build_hints_section (), # Adds hint_lookup tool to available tools
279276 ])
280277
281278 The agent can then call hint_lookup to help stuck players::
@@ -285,43 +282,40 @@ class HintsSection(MarkdownSection[EmptyParams]):
285282
286283 Note:
287284 Tools attached to sections are only available when the section is part
288- of the active prompt. Remove HintsSection to disable hint functionality.
285+ of the active prompt. Remove the hints section to disable hint functionality.
289286 """
290-
291- _params_type = EmptyParams
292-
293- def __init__ (self ) -> None :
294- super ().__init__ (
295- title = "Hints" ,
296- key = "hints" ,
297- template = """## Hint System
287+ return MarkdownSection [EmptyParams ](
288+ title = "Hints" ,
289+ key = "hints" ,
290+ template = """## Hint System
298291
299292If a player is stuck, you can provide hints using the hint_lookup tool.
300293Hints give clues without revealing the actual answer.
301294
302295Available hint categories: number, word, color, phrase
303296""" ,
304- visibility = SectionVisibility .FULL ,
305- tools = (hint_lookup_tool ,),
306- default_params = EmptyParams (),
307- )
297+ visibility = SectionVisibility .FULL ,
298+ tools = (hint_lookup_tool ,),
299+ default_params = EmptyParams (),
300+ )
308301
309302
310- class LuckyDiceSection ( MarkdownSection [EmptyParams ]) :
311- """Lucky Dice mini-game section demonstrating tool policies.
303+ def build_lucky_dice_section () -> MarkdownSection [EmptyParams ]:
304+ """Build a Lucky Dice mini-game section demonstrating tool policies.
312305
313- This section showcases SequentialDependencyPolicy, which enforces tool call
314- ordering. The throw_dice tool cannot be called until pick_up_dice has been
315- called first. If the agent tries to throw without picking up, the policy
316- blocks the call and returns an error message.
306+ Creates a MarkdownSection that showcases SequentialDependencyPolicy, which
307+ enforces tool call ordering. The throw_dice tool cannot be called until
308+ pick_up_dice has been called first. If the agent tries to throw without
309+ picking up, the policy blocks the call and returns an error message.
317310
318311 Tool policies are useful for:
319312 - Enforcing proper operation sequences (e.g., connect before query)
320313 - Preventing invalid state transitions
321314 - Teaching agents correct workflows through guardrails
322315
323- Attributes:
324- _params_type: EmptyParams - this section has no dynamic content.
316+ Returns:
317+ MarkdownSection[EmptyParams]: A configured section ready to be included
318+ in a PromptTemplate. The section key is "dice".
325319
326320 Section key: "dice"
327321
@@ -339,8 +333,8 @@ class LuckyDiceSection(MarkdownSection[EmptyParams]):
339333 Include to enable the dice mini-game::
340334
341335 template = PromptTemplate(sections=[
342- QuestionSection (),
343- LuckyDiceSection (), # Adds dice tools with ordering policy
336+ build_question_section (),
337+ build_lucky_dice_section (), # Adds dice tools with ordering policy
344338 ])
345339
346340 Correct tool sequence::
@@ -360,21 +354,17 @@ class LuckyDiceSection(MarkdownSection[EmptyParams]):
360354 The policy state resets between agent sessions. Each new session
361355 requires pick_up_dice to be called before throw_dice.
362356 """
357+ # Policy: throw_dice requires pick_up_dice to have been called first
358+ dice_policy = SequentialDependencyPolicy (
359+ dependencies = {
360+ "throw_dice" : frozenset ({"pick_up_dice" }),
361+ }
362+ )
363363
364- _params_type = EmptyParams
365-
366- def __init__ (self ) -> None :
367- # Policy: throw_dice requires pick_up_dice to have been called first
368- dice_policy = SequentialDependencyPolicy (
369- dependencies = {
370- "throw_dice" : frozenset ({"pick_up_dice" }),
371- }
372- )
373-
374- super ().__init__ (
375- title = "Lucky Dice" ,
376- key = "dice" ,
377- template = """## Lucky Dice Mini-Game
364+ return MarkdownSection [EmptyParams ](
365+ title = "Lucky Dice" ,
366+ key = "dice" ,
367+ template = """## Lucky Dice Mini-Game
378368
379369Players can roll the lucky dice for bonus points! But there's a rule:
380370you must pick up the dice before you can throw it.
@@ -386,11 +376,11 @@ def __init__(self) -> None:
386376The throw_dice tool has a policy that enforces this ordering.
387377If someone asks to roll the dice, make sure to pick it up first!
388378""" ,
389- visibility = SectionVisibility .FULL ,
390- tools = (pick_up_dice_tool , throw_dice_tool ),
391- policies = (dice_policy ,),
392- default_params = EmptyParams (),
393- )
379+ visibility = SectionVisibility .FULL ,
380+ tools = (pick_up_dice_tool , throw_dice_tool ),
381+ policies = (dice_policy ,),
382+ default_params = EmptyParams (),
383+ )
394384
395385
396386# =============================================================================
0 commit comments