Skip to content

Commit bd11671

Browse files
committed
WIP new IA implementation
1 parent bea57fd commit bd11671

File tree

95 files changed

+5076
-719
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+5076
-719
lines changed

docs/colang-2/overview.rst

Lines changed: 0 additions & 113 deletions
This file was deleted.
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
# Action Parameters
2+
3+
This section describes the special parameters automatically provided to actions by the NeMo Guardrails toolkit.
4+
5+
## Special Parameters
6+
7+
When you include these parameters in your action's function signature, they are automatically populated:
8+
9+
| Parameter | Type | Description |
10+
|-----------|------|-------------|
11+
| `context` | `dict` | Context data available to the action |
12+
| `events` | `List[dict]` | History of events in the conversation |
13+
| `llm` | `BaseLLM` | Access to the LLM instance |
14+
| `config` | `RailsConfig` | The full configuration instance |
15+
16+
## The `context` Parameter
17+
18+
The `context` parameter provides access to conversation state and variables:
19+
20+
```python
21+
from typing import Optional
22+
from nemoguardrails.actions import action
23+
24+
@action(is_system_action=True)
25+
async def my_action(context: Optional[dict] = None):
26+
# Access context variables
27+
user_message = context.get("last_user_message")
28+
bot_message = context.get("bot_message")
29+
relevant_chunks = context.get("relevant_chunks")
30+
31+
return True
32+
```
33+
34+
### Common Context Variables
35+
36+
| Variable | Description |
37+
|----------|-------------|
38+
| `last_user_message` | The most recent user message |
39+
| `bot_message` | The current bot message (in output rails) |
40+
| `last_bot_message` | The previous bot message |
41+
| `relevant_chunks` | Retrieved knowledge base chunks |
42+
| `user_intent` | The canonical user intent |
43+
| `bot_intent` | The canonical bot intent |
44+
45+
### Accessing Custom Context
46+
47+
Custom context variables set in flows are also accessible:
48+
49+
```colang
50+
# In a Colang flow
51+
$user_preference = "dark_mode"
52+
execute check_preference
53+
```
54+
55+
```python
56+
@action()
57+
async def check_preference(context: Optional[dict] = None):
58+
preference = context.get("user_preference")
59+
return preference == "dark_mode"
60+
```
61+
62+
## The `events` Parameter
63+
64+
The `events` parameter provides the complete event history:
65+
66+
```python
67+
from typing import List, Optional
68+
from nemoguardrails.actions import action
69+
70+
@action()
71+
async def analyze_conversation(events: Optional[List[dict]] = None):
72+
# Count user messages
73+
user_messages = [
74+
e for e in events
75+
if e.get("type") == "UtteranceUserActionFinished"
76+
]
77+
78+
return {"message_count": len(user_messages)}
79+
```
80+
81+
### Event Types
82+
83+
| Event Type | Description |
84+
|------------|-------------|
85+
| `UtteranceUserActionFinished` | User sent a message |
86+
| `StartUtteranceBotAction` | Bot started responding |
87+
| `UtteranceBotActionFinished` | Bot finished responding |
88+
| `StartInternalSystemAction` | System action started |
89+
| `InternalSystemActionFinished` | System action completed |
90+
| `UserIntent` | User intent was determined |
91+
| `BotIntent` | Bot intent was determined |
92+
93+
### Event Structure Example
94+
95+
```python
96+
{
97+
"type": "UtteranceUserActionFinished",
98+
"uid": "abc123",
99+
"final_transcript": "Hello, how are you?",
100+
"action_uid": "action_001",
101+
"is_success": True
102+
}
103+
```
104+
105+
## The `llm` Parameter
106+
107+
The `llm` parameter provides direct access to the LLM instance:
108+
109+
```python
110+
from typing import Optional
111+
from langchain.llms.base import BaseLLM
112+
from nemoguardrails.actions import action
113+
114+
@action()
115+
async def custom_llm_call(
116+
prompt: str,
117+
llm: Optional[BaseLLM] = None
118+
):
119+
"""Make a custom LLM call."""
120+
if llm is None:
121+
return "LLM not available"
122+
123+
response = await llm.agenerate([prompt])
124+
return response.generations[0][0].text
125+
```
126+
127+
### Use Cases for LLM Access
128+
129+
- Custom prompt engineering
130+
- Multiple LLM calls within a single action
131+
- Specialized text processing
132+
133+
```python
134+
@action()
135+
async def summarize_and_validate(
136+
text: str,
137+
llm: Optional[BaseLLM] = None
138+
):
139+
"""Summarize text and validate the summary."""
140+
# First call: summarize
141+
summary_prompt = f"Summarize this text: {text}"
142+
summary = await llm.agenerate([summary_prompt])
143+
summary_text = summary.generations[0][0].text
144+
145+
# Second call: validate
146+
validation_prompt = f"Is this summary accurate? {summary_text}"
147+
validation = await llm.agenerate([validation_prompt])
148+
149+
return {
150+
"summary": summary_text,
151+
"validation": validation.generations[0][0].text
152+
}
153+
```
154+
155+
## The `config` Parameter
156+
157+
The `config` parameter provides access to the full configuration:
158+
159+
```python
160+
from typing import Optional
161+
from nemoguardrails import RailsConfig
162+
from nemoguardrails.actions import action
163+
164+
@action()
165+
async def check_config_setting(config: Optional[RailsConfig] = None):
166+
"""Access configuration settings."""
167+
# Access model configuration
168+
models = config.models
169+
main_model = next(
170+
(m for m in models if m.type == "main"),
171+
None
172+
)
173+
174+
# Access custom config data
175+
custom_data = config.custom_data
176+
177+
return {
178+
"model_engine": main_model.engine if main_model else None,
179+
"custom_data": custom_data
180+
}
181+
```
182+
183+
### Configuration Access Examples
184+
185+
```python
186+
@action()
187+
async def get_active_rails(config: Optional[RailsConfig] = None):
188+
"""Get list of active rails."""
189+
rails_config = config.rails
190+
191+
return {
192+
"input_rails": rails_config.input.flows if rails_config.input else [],
193+
"output_rails": rails_config.output.flows if rails_config.output else []
194+
}
195+
```
196+
197+
## Combining Multiple Parameters
198+
199+
You can use multiple special parameters together:
200+
201+
```python
202+
@action(is_system_action=True)
203+
async def advanced_check(
204+
context: Optional[dict] = None,
205+
events: Optional[List[dict]] = None,
206+
llm: Optional[BaseLLM] = None,
207+
config: Optional[RailsConfig] = None
208+
):
209+
"""Advanced action using multiple special parameters."""
210+
# Get current message from context
211+
message = context.get("last_user_message", "")
212+
213+
# Count previous interactions from events
214+
interaction_count = len([
215+
e for e in events
216+
if e.get("type") == "UtteranceUserActionFinished"
217+
])
218+
219+
# Check config for thresholds
220+
max_interactions = config.custom_data.get("max_interactions", 100)
221+
222+
if interaction_count > max_interactions:
223+
return False
224+
225+
# Use LLM for complex validation if needed
226+
if needs_llm_check(message):
227+
result = await llm.agenerate([f"Is this safe? {message}"])
228+
return "yes" in result.generations[0][0].text.lower()
229+
230+
return True
231+
```
232+
233+
## Parameter Type Annotations
234+
235+
Always use proper type annotations for special parameters:
236+
237+
```python
238+
from typing import Optional, List
239+
from langchain.llms.base import BaseLLM
240+
from nemoguardrails import RailsConfig
241+
from nemoguardrails.actions import action
242+
243+
@action()
244+
async def properly_typed_action(
245+
# Regular parameters
246+
query: str,
247+
limit: int = 10,
248+
# Special parameters with correct types
249+
context: Optional[dict] = None,
250+
events: Optional[List[dict]] = None,
251+
llm: Optional[BaseLLM] = None,
252+
config: Optional[RailsConfig] = None
253+
):
254+
"""Action with proper type annotations."""
255+
pass
256+
```
257+
258+
## Related Topics
259+
260+
- [Creating Custom Actions](creating-actions) - Create your own actions
261+
- [Registering Actions](registering-actions) - Ways to register actions

0 commit comments

Comments
 (0)