@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,227 @@
1
+ # AI Orchestrator (Single-Agent)
2
+
3
+ The `createAgentOrchestrator` configures a Directive-backed runtime for a single AI agent with constraints, resolvers, guardrails, memory, budgets, and hooks.
4
+
5
+ ## Decision Tree: "How do I set up an orchestrator?"
6
+
7
+ ```
8
+ Need to run an AI agent?
9
+ ├── Single agent → createAgentOrchestrator (this file)
10
+ ├── Multiple agents → createMultiAgentOrchestrator (see ai-multi-agent.md)
11
+
12
+ Setting up createAgentOrchestrator...
13
+ ├── Need schema? → factsSchema with t.*() builders (NOT TS types)
14
+ ├── Need guardrails? → guardrails: { input: [...], output: [...] }
15
+ ├── Need memory? → memory: createAgentMemory({ strategy, summarizer })
16
+ ├── Need budget control? → maxTokenBudget + budgetWarningThreshold
17
+ ├── Need streaming? → orchestrator.runStream(agent, prompt)
18
+ └── Need approval workflow? → hooks.onBeforeRun returns { approved: boolean }
19
+ ```
20
+
21
+ ## Basic Setup
22
+
23
+ ```typescript
24
+ import { createAgentOrchestrator, t } from "@directive-run/ai";
25
+ import { createAnthropicRunner } from "@directive-run/ai/anthropic";
26
+
27
+ const runner = createAnthropicRunner({
28
+ apiKey: process.env.ANTHROPIC_API_KEY,
29
+ });
30
+
31
+ const orchestrator = createAgentOrchestrator({
32
+ runner,
33
+ factsSchema: {
34
+ confidence: t.number(),
35
+ analysis: t.string(),
36
+ cache: t.array<string>(),
37
+ },
38
+ init: (facts) => {
39
+ facts.confidence = 0;
40
+ facts.analysis = "";
41
+ facts.cache = [];
42
+ },
43
+ constraints: {
44
+ lowConfidence: {
45
+ when: (facts) => facts.confidence < 0.5,
46
+ require: { type: "RE_ANALYZE" },
47
+ },
48
+ },
49
+ resolvers: {
50
+ reAnalyze: {
51
+ requirement: "RE_ANALYZE",
52
+ resolve: async (req, context) => {
53
+ context.facts.confidence = 0;
54
+ },
55
+ },
56
+ },
57
+ guardrails: {
58
+ input: [createPIIGuardrail({ redact: true })],
59
+ output: [createLengthGuardrail({ maxChars: 5000 })],
60
+ },
61
+ maxTokenBudget: 100000,
62
+ budgetWarningThreshold: 0.8,
63
+ memory: createAgentMemory({
64
+ strategy: createSlidingWindowStrategy({ maxMessages: 50 }),
65
+ summarizer: createKeyPointsSummarizer(),
66
+ }),
67
+ debug: true,
68
+ hooks: {
69
+ onStart: () => console.log("Orchestrator started"),
70
+ onBeforeRun: (agent, prompt) => ({ approved: true }),
71
+ onAfterRun: (agent, result) => console.log("Done", result.totalTokens),
72
+ onError: (error) => console.error(error),
73
+ onBudgetWarning: (usage) => console.warn("Budget:", usage),
74
+ },
75
+ });
76
+ ```
77
+
78
+ ## Running the Agent
79
+
80
+ ```typescript
81
+ const agent = {
82
+ name: "analyst",
83
+ instructions: "You are a data analyst.",
84
+ model: "claude-sonnet-4-5",
85
+ };
86
+
87
+ // Standard run
88
+ const result = await orchestrator.run(agent, "Analyze this dataset");
89
+ console.log(result.output);
90
+
91
+ // Streaming run
92
+ const stream = orchestrator.runStream(agent, "Summarize findings");
93
+ for await (const chunk of stream) {
94
+ if (chunk.type === "token") {
95
+ process.stdout.write(chunk.data);
96
+ }
97
+ }
98
+
99
+ // Wait for all constraints/resolvers to settle
100
+ await orchestrator.system.settle();
101
+ ```
102
+
103
+ ## OrchestratorState Fields
104
+
105
+ ```typescript
106
+ // Access via orchestrator.system.facts
107
+ orchestrator.system.facts.status; // "idle" | "running" | "paused" | "error"
108
+ orchestrator.system.facts.tokenUsage; // { inputTokens, outputTokens, total }
109
+ orchestrator.system.facts.runCount; // number of completed runs
110
+ orchestrator.system.facts.lastError; // Error | null
111
+ ```
112
+
113
+ ## Approval Workflow
114
+
115
+ ```typescript
116
+ const orchestrator = createAgentOrchestrator({
117
+ runner,
118
+ hooks: {
119
+ onBeforeRun: async (agent, prompt) => {
120
+ const decision = await reviewPrompt(prompt);
121
+
122
+ return { approved: decision.ok, reason: decision.reason };
123
+ },
124
+ },
125
+ });
126
+
127
+ // If not approved, run() throws ApprovalDeniedError
128
+ ```
129
+
130
+ ## Pause / Resume
131
+
132
+ ```typescript
133
+ orchestrator.pause();
134
+ // Agent work suspends; in-flight requests complete but new ones queue
135
+
136
+ orchestrator.resume();
137
+ // Queued work begins executing
138
+ ```
139
+
140
+ ## Checkpoints
141
+
142
+ ```typescript
143
+ // Save state
144
+ const checkpoint = orchestrator.checkpoint();
145
+ const serialized = JSON.stringify(checkpoint);
146
+
147
+ // Restore state
148
+ const restored = createAgentOrchestrator({
149
+ runner,
150
+ checkpoint: JSON.parse(serialized),
151
+ });
152
+ ```
153
+
154
+ ## Anti-Patterns
155
+
156
+ ### #21: TypeScript types instead of t.*() for factsSchema
157
+
158
+ ```typescript
159
+ // WRONG — TS types are erased at runtime, no schema validation
160
+ const orchestrator = createAgentOrchestrator({
161
+ runner,
162
+ factsSchema: {} as { confidence: number; analysis: string },
163
+ });
164
+
165
+ // CORRECT — use t.*() builders for runtime schema
166
+ const orchestrator = createAgentOrchestrator({
167
+ runner,
168
+ factsSchema: {
169
+ confidence: t.number(),
170
+ analysis: t.string(),
171
+ },
172
+ });
173
+ ```
174
+
175
+ ### #22: Mutating arrays/objects in place
176
+
177
+ ```typescript
178
+ // WRONG — proxy cannot detect in-place mutations
179
+ context.facts.cache.push("new-item");
180
+
181
+ // CORRECT — replace the entire value
182
+ context.facts.cache = [...context.facts.cache, "new-item"];
183
+ ```
184
+
185
+ ### #23: Returning data from resolve
186
+
187
+ ```typescript
188
+ // WRONG — resolvers return void, not data
189
+ resolve: async (req, context) => {
190
+ const result = await analyzeData(req.input);
191
+
192
+ return result; // Return value is ignored
193
+ },
194
+
195
+ // CORRECT — mutate context.facts to store results
196
+ resolve: async (req, context) => {
197
+ const result = await analyzeData(req.input);
198
+ context.facts.analysis = result;
199
+ },
200
+ ```
201
+
202
+ ### #24: Forgetting start() for multi-agent
203
+
204
+ ```typescript
205
+ // WRONG — multi-agent orchestrators require explicit start()
206
+ const orchestrator = createMultiAgentOrchestrator({ agents, runner });
207
+ const result = await orchestrator.runPattern("pipeline", "prompt");
208
+
209
+ // CORRECT — call start() before running patterns
210
+ const orchestrator = createMultiAgentOrchestrator({ agents, runner });
211
+ orchestrator.start();
212
+ const result = await orchestrator.runPattern("pipeline", "prompt");
213
+ ```
214
+
215
+ Note: Single-agent `createAgentOrchestrator` does NOT require `start()`. Only `createMultiAgentOrchestrator` does.
216
+
217
+ ## Quick Reference
218
+
219
+ | Method | Purpose |
220
+ |---|---|
221
+ | `orchestrator.run(agent, prompt)` | Run agent, return RunResult |
222
+ | `orchestrator.runStream(agent, prompt)` | Run agent, return AsyncIterable<StreamChunk> |
223
+ | `orchestrator.pause()` | Suspend new work |
224
+ | `orchestrator.resume()` | Resume suspended work |
225
+ | `orchestrator.checkpoint()` | Serialize current state |
226
+ | `orchestrator.system.settle()` | Wait for all resolvers |
227
+ | `orchestrator.system.facts` | Read orchestrator state |
@@ -0,0 +1,293 @@
1
+ # AI Security
2
+
3
+ PII detection/redaction, prompt injection defense, audit trails, GDPR/CCPA compliance, and security best practices for Directive AI applications.
4
+
5
+ ## Decision Tree: "What security do I need?"
6
+
7
+ ```
8
+ What are you protecting against?
9
+ ├── PII leakage in prompts/outputs → createPIIGuardrail()
10
+ ├── Prompt injection attacks → createPromptInjectionGuardrail()
11
+ ├── Audit/compliance requirements → createAuditTrailPlugin()
12
+ ├── GDPR/CCPA data handling → createCompliancePlugin()
13
+
14
+ Where do guardrails go?
15
+ ├── Before agent receives prompt → guardrails.input
16
+ ├── After agent produces output → guardrails.output
17
+ └── Both directions → guardrails.input + guardrails.output
18
+
19
+ Where do plugins go?
20
+ └── Always → plugins: [createAuditTrailPlugin(), ...]
21
+ (Plugins are Directive core plugins, not AI-specific)
22
+ ```
23
+
24
+ ## PII Detection and Redaction
25
+
26
+ Enhanced PII guardrail with built-in patterns and custom regex support:
27
+
28
+ ```typescript
29
+ import { createPIIGuardrail } from "@directive-run/ai";
30
+
31
+ const piiGuardrail = createPIIGuardrail({
32
+ // Redact PII instead of blocking (default: false = block)
33
+ redact: true,
34
+
35
+ // Replacement string (default: "[REDACTED]")
36
+ redactReplacement: "[REDACTED]",
37
+
38
+ // Additional custom patterns beyond built-ins
39
+ patterns: [
40
+ /\b\d{3}-\d{2}-\d{4}\b/, // SSN
41
+ /\b[A-Z]{2}\d{6,8}\b/, // Passport
42
+ /ACCT-\d{10}/, // Internal account IDs
43
+ ],
44
+ });
45
+ ```
46
+
47
+ Built-in patterns detect:
48
+ - Email addresses
49
+ - Phone numbers (US, international)
50
+ - Credit card numbers (Visa, MC, Amex, Discover)
51
+ - IP addresses (v4, v6)
52
+ - Dates of birth (common formats)
53
+
54
+ ### Using PII Guardrail
55
+
56
+ ```typescript
57
+ const orchestrator = createAgentOrchestrator({
58
+ runner,
59
+ guardrails: {
60
+ // Redact PII before the agent sees it
61
+ input: [piiGuardrail],
62
+
63
+ // Catch any PII the agent generates
64
+ output: [piiGuardrail],
65
+ },
66
+ });
67
+ ```
68
+
69
+ ## Prompt Injection Detection
70
+
71
+ Detect and block common prompt injection patterns:
72
+
73
+ ```typescript
74
+ import { createPromptInjectionGuardrail } from "@directive-run/ai";
75
+
76
+ const injectionGuardrail = createPromptInjectionGuardrail({
77
+ // Sensitivity: "low" | "medium" | "high" (default: "medium")
78
+ sensitivity: "high",
79
+
80
+ // Custom patterns to detect
81
+ additionalPatterns: [
82
+ /ignore previous instructions/i,
83
+ /you are now/i,
84
+ /system prompt/i,
85
+ ],
86
+
87
+ // Allow-list specific phrases that look like injections but are safe
88
+ allowlist: [
89
+ "you are now ready to proceed",
90
+ ],
91
+ });
92
+ ```
93
+
94
+ ### Sensitivity Levels
95
+
96
+ | Level | Detects | False Positives |
97
+ |---|---|---|
98
+ | `"low"` | Obvious injections (role overrides, ignore instructions) | Rare |
99
+ | `"medium"` | Common patterns + encoded attacks | Occasional |
100
+ | `"high"` | Aggressive detection + heuristic analysis | More frequent |
101
+
102
+ ### Applying Injection Defense
103
+
104
+ ```typescript
105
+ const orchestrator = createAgentOrchestrator({
106
+ runner,
107
+ guardrails: {
108
+ // Check user input for injection attempts
109
+ input: [injectionGuardrail],
110
+ },
111
+ });
112
+
113
+ // Handle blocked input
114
+ import { GuardrailError } from "@directive-run/ai";
115
+
116
+ try {
117
+ const result = await orchestrator.run(agent, userInput);
118
+ } catch (error) {
119
+ if (error instanceof GuardrailError) {
120
+ console.log(error.guardrailName); // "prompt-injection"
121
+ console.log(error.errorCode); // "GUARDRAIL_INPUT_BLOCKED"
122
+ console.log(error.reason); // "Prompt injection detected: role override"
123
+ }
124
+ }
125
+ ```
126
+
127
+ ## Audit Trail Plugin
128
+
129
+ Log all AI interactions for compliance and forensics:
130
+
131
+ ```typescript
132
+ import { createAuditTrailPlugin } from "@directive-run/core/plugins";
133
+
134
+ const auditPlugin = createAuditTrailPlugin({
135
+ // Where to store audit logs
136
+ storage: "file", // "file" | "console" | custom handler
137
+ filePath: "./audit.jsonl", // For file storage
138
+
139
+ // What to log
140
+ logInputs: true,
141
+ logOutputs: true,
142
+ logToolCalls: true,
143
+ logTokenUsage: true,
144
+
145
+ // Redact sensitive data in logs (recommended)
146
+ redactPII: true,
147
+
148
+ // Custom log handler (alternative to file/console)
149
+ onLog: async (entry) => {
150
+ await sendToSIEM(entry);
151
+ },
152
+ });
153
+ ```
154
+
155
+ ### Audit Log Entry Shape
156
+
157
+ ```typescript
158
+ interface AuditLogEntry {
159
+ timestamp: string;
160
+ eventType: "agent_run" | "tool_call" | "guardrail_check" | "error";
161
+ agentName: string;
162
+ input?: string; // Redacted if redactPII: true
163
+ output?: string; // Redacted if redactPII: true
164
+ toolCalls?: ToolCall[];
165
+ tokenUsage?: { inputTokens: number; outputTokens: number };
166
+ duration: number;
167
+ guardrails?: { name: string; passed: boolean; reason?: string }[];
168
+ error?: { message: string; code: string };
169
+ }
170
+ ```
171
+
172
+ ## GDPR/CCPA Compliance Plugin
173
+
174
+ Enforce data handling policies at the system level:
175
+
176
+ ```typescript
177
+ import { createCompliancePlugin } from "@directive-run/core/plugins";
178
+
179
+ const compliancePlugin = createCompliancePlugin({
180
+ // Data retention policy
181
+ retention: {
182
+ maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days in ms
183
+ autoDelete: true,
184
+ },
185
+
186
+ // Right to deletion
187
+ onDeletionRequest: async (userId) => {
188
+ await deleteUserData(userId);
189
+ await deleteConversationHistory(userId);
190
+ },
191
+
192
+ // Data export (right to portability)
193
+ onExportRequest: async (userId) => {
194
+ const data = await getUserData(userId);
195
+
196
+ return JSON.stringify(data);
197
+ },
198
+
199
+ // Consent tracking
200
+ requireConsent: true,
201
+ consentCategories: ["analytics", "personalization", "training"],
202
+ });
203
+ ```
204
+
205
+ ## Applying Security Plugins
206
+
207
+ Plugins go on the orchestrator (they are Directive core plugins):
208
+
209
+ ```typescript
210
+ import { createAgentOrchestrator } from "@directive-run/ai";
211
+
212
+ const orchestrator = createAgentOrchestrator({
213
+ runner,
214
+ guardrails: {
215
+ input: [piiGuardrail, injectionGuardrail],
216
+ output: [piiGuardrail],
217
+ },
218
+ plugins: [auditPlugin, compliancePlugin],
219
+ });
220
+ ```
221
+
222
+ ## Security Best Practices
223
+
224
+ ### Input Validation
225
+
226
+ ```typescript
227
+ // WRONG — passing raw user input to the agent
228
+ const result = await orchestrator.run(agent, userInput);
229
+
230
+ // CORRECT — validate and sanitize input first
231
+ const sanitized = sanitizeInput(userInput);
232
+ const result = await orchestrator.run(agent, sanitized);
233
+ ```
234
+
235
+ ### Token Budget Limits
236
+
237
+ ```typescript
238
+ // Always set a token budget to prevent runaway costs
239
+ const orchestrator = createAgentOrchestrator({
240
+ runner,
241
+ maxTokenBudget: 100000,
242
+ budgetWarningThreshold: 0.8,
243
+ });
244
+ ```
245
+
246
+ ### Tool Approval Workflows
247
+
248
+ ```typescript
249
+ import { createToolGuardrail } from "@directive-run/ai";
250
+
251
+ // Restrict which tools the agent can call
252
+ const toolGuardrail = createToolGuardrail({
253
+ allowedTools: ["search", "calculator", "readFile"],
254
+ // Tools not in this list are blocked
255
+ });
256
+
257
+ // For MCP tools, use toolConstraints
258
+ const mcp = createMCPAdapter({
259
+ servers: [...],
260
+ toolConstraints: {
261
+ "tools/write-file": { requireApproval: true },
262
+ "tools/delete": { requireApproval: true, maxAttempts: 1 },
263
+ },
264
+ });
265
+ ```
266
+
267
+ ### Output Sanitization
268
+
269
+ ```typescript
270
+ // Always validate agent output before using it
271
+ const orchestrator = createAgentOrchestrator({
272
+ runner,
273
+ guardrails: {
274
+ output: [
275
+ createOutputSchemaGuardrail({ schema: expectedSchema, retries: 2 }),
276
+ createContentFilterGuardrail({ patterns: [/eval\(/, /<script/i], action: "block" }),
277
+ createPIIGuardrail({ redact: true }),
278
+ ],
279
+ },
280
+ });
281
+ ```
282
+
283
+ ## Quick Reference
284
+
285
+ | API | Import Path | Purpose |
286
+ |---|---|---|
287
+ | `createPIIGuardrail` | `@directive-run/ai` | Detect/redact PII |
288
+ | `createPromptInjectionGuardrail` | `@directive-run/ai` | Block injection attacks |
289
+ | `createAuditTrailPlugin` | `@directive-run/core/plugins` | Log all AI interactions |
290
+ | `createCompliancePlugin` | `@directive-run/core/plugins` | GDPR/CCPA data policies |
291
+ | `createToolGuardrail` | `@directive-run/ai` | Restrict tool access |
292
+ | `createContentFilterGuardrail` | `@directive-run/ai` | Block unsafe content patterns |
293
+ | `GuardrailError` | `@directive-run/ai` | Catch guardrail failures |