@directive-run/knowledge 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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -0
  3. package/ai/ai-adapters.md +250 -0
  4. package/ai/ai-agents-streaming.md +269 -0
  5. package/ai/ai-budget-resilience.md +235 -0
  6. package/ai/ai-communication.md +281 -0
  7. package/ai/ai-debug-observability.md +243 -0
  8. package/ai/ai-guardrails-memory.md +332 -0
  9. package/ai/ai-mcp-rag.md +288 -0
  10. package/ai/ai-multi-agent.md +274 -0
  11. package/ai/ai-orchestrator.md +227 -0
  12. package/ai/ai-security.md +293 -0
  13. package/ai/ai-tasks.md +261 -0
  14. package/ai/ai-testing-evals.md +378 -0
  15. package/api-skeleton.md +5 -0
  16. package/core/anti-patterns.md +382 -0
  17. package/core/constraints.md +263 -0
  18. package/core/core-patterns.md +228 -0
  19. package/core/error-boundaries.md +322 -0
  20. package/core/multi-module.md +315 -0
  21. package/core/naming.md +283 -0
  22. package/core/plugins.md +344 -0
  23. package/core/react-adapter.md +262 -0
  24. package/core/resolvers.md +357 -0
  25. package/core/schema-types.md +262 -0
  26. package/core/system-api.md +271 -0
  27. package/core/testing.md +257 -0
  28. package/core/time-travel.md +238 -0
  29. package/dist/index.cjs +111 -0
  30. package/dist/index.cjs.map +1 -0
  31. package/dist/index.d.cts +10 -0
  32. package/dist/index.d.ts +10 -0
  33. package/dist/index.js +102 -0
  34. package/dist/index.js.map +1 -0
  35. package/examples/ab-testing.ts +385 -0
  36. package/examples/ai-checkpoint.ts +509 -0
  37. package/examples/ai-guardrails.ts +319 -0
  38. package/examples/ai-orchestrator.ts +589 -0
  39. package/examples/async-chains.ts +287 -0
  40. package/examples/auth-flow.ts +371 -0
  41. package/examples/batch-resolver.ts +341 -0
  42. package/examples/checkers.ts +589 -0
  43. package/examples/contact-form.ts +176 -0
  44. package/examples/counter.ts +393 -0
  45. package/examples/dashboard-loader.ts +512 -0
  46. package/examples/debounce-constraints.ts +105 -0
  47. package/examples/dynamic-modules.ts +293 -0
  48. package/examples/error-boundaries.ts +430 -0
  49. package/examples/feature-flags.ts +220 -0
  50. package/examples/form-wizard.ts +347 -0
  51. package/examples/fraud-analysis.ts +663 -0
  52. package/examples/goal-heist.ts +341 -0
  53. package/examples/multi-module.ts +57 -0
  54. package/examples/newsletter.ts +241 -0
  55. package/examples/notifications.ts +210 -0
  56. package/examples/optimistic-updates.ts +317 -0
  57. package/examples/pagination.ts +260 -0
  58. package/examples/permissions.ts +337 -0
  59. package/examples/provider-routing.ts +403 -0
  60. package/examples/server.ts +316 -0
  61. package/examples/shopping-cart.ts +422 -0
  62. package/examples/sudoku.ts +630 -0
  63. package/examples/theme-locale.ts +204 -0
  64. package/examples/time-machine.ts +225 -0
  65. package/examples/topic-guard.ts +306 -0
  66. package/examples/url-sync.ts +333 -0
  67. package/examples/websocket.ts +404 -0
  68. package/package.json +65 -0
@@ -0,0 +1,243 @@
1
+ # AI Debug and Observability
2
+
3
+ Debug timeline with 25+ event types, breakpoints, checkpoints, and OpenTelemetry integration for AI orchestrators.
4
+
5
+ ## Decision Tree: "How do I observe what's happening?"
6
+
7
+ ```
8
+ What do you need?
9
+ ├── Event stream of all AI activity → createDebugTimeline()
10
+ ├── Pause execution at specific points → breakpoints config
11
+ ├── Save/restore orchestrator state → checkpoint() / restore
12
+ ├── Export traces to observability platform → createOTLPExporter()
13
+
14
+ Which events to watch?
15
+ ├── Agent lifecycle → agent_start, agent_complete, agent_error, agent_retry
16
+ ├── Guardrails → guardrail_check
17
+ ├── Constraints/Resolvers → constraint_evaluate, resolver_start, resolver_complete
18
+ ├── Approval workflow → approval_request, approval_response
19
+ ├── Multi-agent patterns → pattern_start, pattern_complete, dag_node_update
20
+ ├── Composition patterns → race_start, race_winner, race_cancelled,
21
+ │ debate_round, reflection_iteration
22
+ ├── Handoffs → handoff_start, handoff_complete, reroute
23
+ ├── Tasks → task_start, task_complete, task_error, task_progress, goal_step
24
+ ├── Checkpoints → checkpoint_save, checkpoint_restore
25
+ └── Breakpoints → breakpoint_hit, breakpoint_resumed
26
+ ```
27
+
28
+ ## Debug Timeline
29
+
30
+ Subscribe to a real-time event stream of all orchestrator activity:
31
+
32
+ ```typescript
33
+ import { createDebugTimeline } from "@directive-run/ai";
34
+
35
+ const timeline = createDebugTimeline({
36
+ maxEvents: 2000, // Ring buffer size (oldest evicted first)
37
+ });
38
+
39
+ // Subscribe to all events
40
+ const unsubscribe = timeline.subscribe((event) => {
41
+ console.log(`[${event.timestamp}] ${event.type}`, event);
42
+ });
43
+
44
+ // Filter by event type
45
+ const agentEvents = timeline.subscribe(
46
+ (event) => {
47
+ console.log(`Agent: ${event.agentName} → ${event.type}`);
48
+ },
49
+ { filter: (event) => event.type.startsWith("agent_") },
50
+ );
51
+
52
+ // Query past events
53
+ const errors = timeline.query({ type: "agent_error" });
54
+ const recentAgentStarts = timeline.query({
55
+ type: "agent_start",
56
+ since: Date.now() - 60000,
57
+ });
58
+ ```
59
+
60
+ ## Event Types Reference
61
+
62
+ All 25+ event types emitted by the timeline:
63
+
64
+ ```typescript
65
+ // Agent lifecycle
66
+ type AgentEvents =
67
+ | { type: "agent_start"; agentName: string; prompt: string }
68
+ | { type: "agent_complete"; agentName: string; output: string; tokens: number; duration: number }
69
+ | { type: "agent_error"; agentName: string; error: Error }
70
+ | { type: "agent_retry"; agentName: string; attempt: number; maxRetries: number; error: Error };
71
+
72
+ // Guardrails
73
+ type GuardrailEvents =
74
+ | { type: "guardrail_check"; guardrailName: string; phase: "input" | "output"; passed: boolean; reason?: string };
75
+
76
+ // Constraints and resolvers
77
+ type ConstraintEvents =
78
+ | { type: "constraint_evaluate"; constraintId: string; result: boolean }
79
+ | { type: "resolver_start"; resolverType: string; requirementKey: string }
80
+ | { type: "resolver_complete"; resolverType: string; duration: number };
81
+
82
+ // Approval workflow
83
+ type ApprovalEvents =
84
+ | { type: "approval_request"; agentName: string; prompt: string }
85
+ | { type: "approval_response"; agentName: string; approved: boolean; reason?: string };
86
+
87
+ // Multi-agent patterns
88
+ type PatternEvents =
89
+ | { type: "pattern_start"; patternName: string; agents: string[] }
90
+ | { type: "pattern_complete"; patternName: string; duration: number }
91
+ | { type: "dag_node_update"; nodeId: string; status: "pending" | "running" | "complete" | "error" };
92
+
93
+ // Composition patterns
94
+ type CompositionEvents =
95
+ | { type: "race_start"; agents: string[] }
96
+ | { type: "race_winner"; agentName: string; duration: number }
97
+ | { type: "race_cancelled"; agentName: string; reason: string }
98
+ | { type: "debate_round"; round: number; agentName: string; position: string }
99
+ | { type: "reflection_iteration"; iteration: number; agentName: string };
100
+
101
+ // Handoffs and routing
102
+ type HandoffEvents =
103
+ | { type: "handoff_start"; from: string; to: string }
104
+ | { type: "handoff_complete"; from: string; to: string; duration: number }
105
+ | { type: "reroute"; from: string; to: string; reason: string };
106
+
107
+ // Checkpoints and breakpoints
108
+ type CheckpointEvents =
109
+ | { type: "checkpoint_save"; checkpointId: string }
110
+ | { type: "checkpoint_restore"; checkpointId: string }
111
+ | { type: "breakpoint_hit"; breakpointId: string; agentName: string }
112
+ | { type: "breakpoint_resumed"; breakpointId: string };
113
+
114
+ // Tasks
115
+ type TaskEvents =
116
+ | { type: "task_start"; taskId: string; label?: string }
117
+ | { type: "task_complete"; taskId: string; duration: number }
118
+ | { type: "task_error"; taskId: string; error: Error }
119
+ | { type: "task_progress"; taskId: string; percent: number; message?: string }
120
+ | { type: "goal_step"; iteration: number; goalMet: boolean };
121
+ ```
122
+
123
+ ## Attaching Timeline to Orchestrator
124
+
125
+ ```typescript
126
+ import { createAgentOrchestrator, createDebugTimeline } from "@directive-run/ai";
127
+
128
+ const timeline = createDebugTimeline({ maxEvents: 2000 });
129
+
130
+ const orchestrator = createAgentOrchestrator({
131
+ runner,
132
+ debug: {
133
+ timeline,
134
+ verbose: true, // Log all events to console
135
+ },
136
+ });
137
+ ```
138
+
139
+ ## Breakpoints
140
+
141
+ Pause execution at specific points for human inspection:
142
+
143
+ ```typescript
144
+ const orchestrator = createMultiAgentOrchestrator({
145
+ agents: { researcher, writer, editor },
146
+ runner,
147
+ debug: {
148
+ timeline,
149
+ breakpoints: [
150
+ {
151
+ id: "before-write",
152
+ // Pause before the writer agent runs
153
+ when: (event) => {
154
+ return event.type === "agent_start" && event.agentName === "writer";
155
+ },
156
+ onHit: async (event, resume) => {
157
+ console.log("Paused before writer. Review researcher output.");
158
+ console.log("Press enter to continue...");
159
+
160
+ await waitForInput();
161
+ resume();
162
+ },
163
+ },
164
+ {
165
+ id: "on-error",
166
+ when: (event) => {
167
+ return event.type === "agent_error";
168
+ },
169
+ onHit: async (event, resume) => {
170
+ console.error("Agent error:", event.error);
171
+ // Decide whether to continue or abort
172
+ resume();
173
+ },
174
+ },
175
+ ],
176
+ },
177
+ });
178
+ ```
179
+
180
+ ## Checkpoints
181
+
182
+ Save and restore full orchestrator state for debugging or recovery:
183
+
184
+ ```typescript
185
+ // Save checkpoint
186
+ const checkpoint = orchestrator.checkpoint();
187
+ const serialized = JSON.stringify(checkpoint);
188
+
189
+ // Store to disk, database, etc.
190
+ await fs.writeFile("checkpoint.json", serialized);
191
+
192
+ // Restore from checkpoint
193
+ const saved = JSON.parse(await fs.readFile("checkpoint.json", "utf-8"));
194
+ const restored = createMultiAgentOrchestrator({
195
+ agents,
196
+ runner,
197
+ checkpoint: saved,
198
+ });
199
+ restored.start();
200
+ ```
201
+
202
+ ## OpenTelemetry Integration
203
+
204
+ Export traces to any OpenTelemetry-compatible backend:
205
+
206
+ ```typescript
207
+ import { createOTLPExporter } from "@directive-run/ai";
208
+
209
+ const exporter = createOTLPExporter({
210
+ endpoint: "http://localhost:4318/v1/traces",
211
+ serviceName: "my-ai-app",
212
+ // Uses GenAI semantic conventions
213
+ // https://opentelemetry.io/docs/specs/semconv/gen-ai/
214
+ });
215
+
216
+ const orchestrator = createAgentOrchestrator({
217
+ runner,
218
+ debug: {
219
+ timeline,
220
+ exporter, // Automatically exports spans
221
+ },
222
+ });
223
+ ```
224
+
225
+ The exporter maps Directive events to GenAI semantic conventions:
226
+
227
+ | Directive Event | OTel Span | GenAI Attribute |
228
+ |---|---|---|
229
+ | `agent_start` → `agent_complete` | `gen_ai.chat` | `gen_ai.system`, `gen_ai.request.model` |
230
+ | `resolver_start` → `resolver_complete` | `gen_ai.tool` | `gen_ai.tool.name` |
231
+ | `guardrail_check` | `gen_ai.guardrail` | `gen_ai.guardrail.name`, `gen_ai.guardrail.passed` |
232
+ | `pattern_start` → `pattern_complete` | `gen_ai.orchestration` | `gen_ai.orchestration.pattern` |
233
+
234
+ ## Quick Reference
235
+
236
+ | API | Purpose | Key Options |
237
+ |---|---|---|
238
+ | `createDebugTimeline()` | Event stream for all activity | `maxEvents` |
239
+ | `timeline.subscribe()` | Listen to events in real time | callback, filter |
240
+ | `timeline.query()` | Search past events | type, since |
241
+ | `orchestrator.checkpoint()` | Serialize full state | returns JSON-safe object |
242
+ | `createOTLPExporter()` | Export traces to OTel backend | `endpoint`, `serviceName` |
243
+ | breakpoints config | Pause at specific events | `when`, `onHit`, `resume` |
@@ -0,0 +1,332 @@
1
+ # AI Guardrails and Memory
2
+
3
+ Built-in guardrails validate/transform input and output. Memory strategies manage conversation history with configurable summarization.
4
+
5
+ ## Decision Tree: "Which guardrail do I need?"
6
+
7
+ ```
8
+ What are you guarding against?
9
+ ├── PII in input/output → createPIIGuardrail()
10
+ ├── Harmful content → createModerationGuardrail()
11
+ ├── Rate limits → createRateLimitGuardrail()
12
+ ├── Unauthorized tool use → createToolGuardrail()
13
+ ├── Output format validation → createOutputSchemaGuardrail()
14
+ ├── Output type checking → createOutputTypeGuardrail()
15
+ ├── Response length → createLengthGuardrail()
16
+ └── Banned words/patterns → createContentFilterGuardrail()
17
+ ```
18
+
19
+ ## GuardrailResult Shape
20
+
21
+ Every guardrail returns this shape:
22
+
23
+ ```typescript
24
+ interface GuardrailResult {
25
+ // Did the input/output pass?
26
+ passed: boolean;
27
+
28
+ // Why it failed (when passed: false)
29
+ reason?: string;
30
+
31
+ // Modified data — guardrail can transform the input/output
32
+ transformed?: unknown;
33
+ }
34
+ ```
35
+
36
+ When `transformed` is set, the modified value replaces the original for downstream processing.
37
+
38
+ ## Built-In Guardrails
39
+
40
+ ### PII Detection and Redaction
41
+
42
+ ```typescript
43
+ import { createPIIGuardrail } from "@directive-run/ai";
44
+
45
+ const piiGuardrail = createPIIGuardrail({
46
+ // Additional regex patterns beyond defaults
47
+ patterns: [/CUSTOM-\d{8}/g],
48
+
49
+ // Redact instead of blocking (default: false)
50
+ redact: true,
51
+
52
+ // Replacement string (default: "[REDACTED]")
53
+ redactReplacement: "***",
54
+ });
55
+ ```
56
+
57
+ ### Content Moderation
58
+
59
+ ```typescript
60
+ import { createModerationGuardrail } from "@directive-run/ai";
61
+
62
+ const moderationGuardrail = createModerationGuardrail({
63
+ // Custom check function — return true if content is safe
64
+ checkFn: async (content) => {
65
+ const result = await moderationAPI.check(content);
66
+
67
+ return result.safe;
68
+ },
69
+
70
+ // Custom rejection message
71
+ message: "Content flagged by moderation",
72
+ });
73
+ ```
74
+
75
+ ### Rate Limiting
76
+
77
+ ```typescript
78
+ import { createRateLimitGuardrail } from "@directive-run/ai";
79
+
80
+ const rateLimitGuardrail = createRateLimitGuardrail({
81
+ maxTokensPerMinute: 50000,
82
+ maxRequestsPerMinute: 10,
83
+ });
84
+ ```
85
+
86
+ ### Tool Allowlist
87
+
88
+ ```typescript
89
+ import { createToolGuardrail } from "@directive-run/ai";
90
+
91
+ const toolGuardrail = createToolGuardrail({
92
+ allowedTools: ["search", "calculator", "readFile"],
93
+ // Any tool not in this list is blocked
94
+ });
95
+ ```
96
+
97
+ ### Output Schema Validation
98
+
99
+ ```typescript
100
+ import { createOutputSchemaGuardrail } from "@directive-run/ai";
101
+
102
+ const schemaGuardrail = createOutputSchemaGuardrail({
103
+ schema: {
104
+ type: "object",
105
+ properties: {
106
+ title: { type: "string" },
107
+ score: { type: "number", minimum: 0, maximum: 100 },
108
+ },
109
+ required: ["title", "score"],
110
+ },
111
+
112
+ // Retry with schema feedback if validation fails (default: 0)
113
+ retries: 2,
114
+ });
115
+ ```
116
+
117
+ ### Output Type Guard
118
+
119
+ ```typescript
120
+ import { createOutputTypeGuardrail } from "@directive-run/ai";
121
+
122
+ const typeGuardrail = createOutputTypeGuardrail({
123
+ type: "object", // "string" | "number" | "boolean" | "object" | "array"
124
+ });
125
+ ```
126
+
127
+ ### Length Constraints
128
+
129
+ ```typescript
130
+ import { createLengthGuardrail } from "@directive-run/ai";
131
+
132
+ const lengthGuardrail = createLengthGuardrail({
133
+ minChars: 100,
134
+ maxChars: 5000,
135
+ minTokens: 50,
136
+ maxTokens: 1000,
137
+ });
138
+ ```
139
+
140
+ ### Content Filter
141
+
142
+ ```typescript
143
+ import { createContentFilterGuardrail } from "@directive-run/ai";
144
+
145
+ const contentFilter = createContentFilterGuardrail({
146
+ patterns: [/badword/i, /sensitive-term/gi],
147
+
148
+ // "block" (default) or "redact"
149
+ action: "redact",
150
+
151
+ // Replacement for redact mode
152
+ replacement: "[FILTERED]",
153
+ });
154
+ ```
155
+
156
+ ## Applying Guardrails
157
+
158
+ ```typescript
159
+ const orchestrator = createAgentOrchestrator({
160
+ runner,
161
+ guardrails: {
162
+ // Run before the agent receives the prompt
163
+ input: [piiGuardrail, rateLimitGuardrail],
164
+
165
+ // Run after the agent produces output
166
+ output: [lengthGuardrail, schemaGuardrail, contentFilter],
167
+ },
168
+ });
169
+ ```
170
+
171
+ ## Anti-Pattern #25: Catching Error Instead of GuardrailError
172
+
173
+ ```typescript
174
+ // WRONG — loses guardrail-specific metadata
175
+ try {
176
+ const result = await orchestrator.run(agent, prompt);
177
+ } catch (error) {
178
+ if (error instanceof Error) {
179
+ console.log(error.message); // No guardrail context
180
+ }
181
+ }
182
+
183
+ // CORRECT — catch GuardrailError for full context
184
+ import { GuardrailError } from "@directive-run/ai";
185
+
186
+ try {
187
+ const result = await orchestrator.run(agent, prompt);
188
+ } catch (error) {
189
+ if (error instanceof GuardrailError) {
190
+ console.log(error.guardrailName); // "pii-detection"
191
+ console.log(error.errorCode); // "GUARDRAIL_INPUT_BLOCKED"
192
+ console.log(error.reason); // "PII detected in input"
193
+ }
194
+ }
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Memory Strategies
200
+
201
+ Memory strategies control how conversation history is managed when it grows too large.
202
+
203
+ ## Decision Tree: "Which memory strategy?"
204
+
205
+ ```
206
+ How should history be trimmed?
207
+ ├── Keep N most recent messages → createSlidingWindowStrategy()
208
+ ├── Keep within token budget → createTokenBasedStrategy()
209
+ └── Both constraints → createHybridStrategy()
210
+ ```
211
+
212
+ ### Sliding Window
213
+
214
+ ```typescript
215
+ import { createAgentMemory, createSlidingWindowStrategy } from "@directive-run/ai";
216
+
217
+ const memory = createAgentMemory({
218
+ strategy: createSlidingWindowStrategy({
219
+ maxMessages: 50,
220
+
221
+ // Always keep the N most recent (default: 5)
222
+ preserveRecentCount: 10,
223
+ }),
224
+ });
225
+ ```
226
+
227
+ ### Token-Based
228
+
229
+ ```typescript
230
+ import { createAgentMemory, createTokenBasedStrategy } from "@directive-run/ai";
231
+
232
+ const memory = createAgentMemory({
233
+ strategy: createTokenBasedStrategy({
234
+ maxTokens: 8000,
235
+ preserveRecentCount: 5,
236
+ }),
237
+ });
238
+ ```
239
+
240
+ ### Hybrid (Both Constraints)
241
+
242
+ ```typescript
243
+ import { createAgentMemory, createHybridStrategy } from "@directive-run/ai";
244
+
245
+ const memory = createAgentMemory({
246
+ strategy: createHybridStrategy({
247
+ maxMessages: 100,
248
+ maxTokens: 16000,
249
+ }),
250
+ });
251
+ ```
252
+
253
+ ## Summarizers
254
+
255
+ When messages are evicted, a summarizer condenses them:
256
+
257
+ ### Truncation (Default)
258
+
259
+ ```typescript
260
+ import { createTruncationSummarizer } from "@directive-run/ai";
261
+
262
+ // Simply drops old messages — no summary generated
263
+ const summarizer = createTruncationSummarizer();
264
+ ```
265
+
266
+ ### Key Points Extraction
267
+
268
+ ```typescript
269
+ import { createKeyPointsSummarizer } from "@directive-run/ai";
270
+
271
+ // Extracts bullet points from evicted messages (rule-based, no LLM)
272
+ const summarizer = createKeyPointsSummarizer();
273
+ ```
274
+
275
+ ### LLM-Based Summarization
276
+
277
+ ```typescript
278
+ import { createLLMSummarizer } from "@directive-run/ai";
279
+
280
+ // Uses the runner to summarize evicted messages via LLM
281
+ const summarizer = createLLMSummarizer(runner);
282
+ ```
283
+
284
+ ### Applying to Memory
285
+
286
+ ```typescript
287
+ const memory = createAgentMemory({
288
+ strategy: createSlidingWindowStrategy({ maxMessages: 50 }),
289
+ summarizer: createKeyPointsSummarizer(),
290
+ autoManage: true, // Automatically trim + summarize (default: true)
291
+ });
292
+
293
+ const orchestrator = createAgentOrchestrator({
294
+ runner,
295
+ memory,
296
+ });
297
+ ```
298
+
299
+ ## Anti-Pattern #31: Async Summarizer Without autoManage: false
300
+
301
+ ```typescript
302
+ // WRONG — LLM summarizer is async but autoManage runs synchronously
303
+ const memory = createAgentMemory({
304
+ strategy: createSlidingWindowStrategy({ maxMessages: 20 }),
305
+ summarizer: createLLMSummarizer(runner),
306
+ autoManage: true, // Will not await the summarizer properly
307
+ });
308
+
309
+ // CORRECT — disable autoManage, call memory.manage() manually
310
+ const memory = createAgentMemory({
311
+ strategy: createSlidingWindowStrategy({ maxMessages: 20 }),
312
+ summarizer: createLLMSummarizer(runner),
313
+ autoManage: false,
314
+ });
315
+
316
+ // After each run, manually manage memory
317
+ const result = await orchestrator.run(agent, prompt);
318
+ await memory.manage(); // Awaits the async summarizer
319
+ ```
320
+
321
+ ## Quick Reference
322
+
323
+ | Guardrail | Input/Output | Key Option |
324
+ |---|---|---|
325
+ | `createPIIGuardrail` | Both | `redact`, `patterns` |
326
+ | `createModerationGuardrail` | Both | `checkFn` |
327
+ | `createRateLimitGuardrail` | Input | `maxTokensPerMinute` |
328
+ | `createToolGuardrail` | Input | `allowedTools` |
329
+ | `createOutputSchemaGuardrail` | Output | `schema`, `retries` |
330
+ | `createOutputTypeGuardrail` | Output | `type` |
331
+ | `createLengthGuardrail` | Output | `minChars`, `maxChars` |
332
+ | `createContentFilterGuardrail` | Both | `patterns`, `action` |