@directive-run/knowledge 0.2.0 → 0.4.2
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.
- package/README.md +3 -3
- package/ai/ai-adapters.md +7 -7
- package/ai/ai-agents-streaming.md +8 -8
- package/ai/ai-budget-resilience.md +5 -5
- package/ai/ai-communication.md +1 -1
- package/ai/ai-guardrails-memory.md +7 -7
- package/ai/ai-mcp-rag.md +5 -5
- package/ai/ai-multi-agent.md +14 -14
- package/ai/ai-orchestrator.md +8 -8
- package/ai/ai-security.md +2 -2
- package/ai/ai-tasks.md +9 -9
- package/ai/ai-testing-evals.md +2 -2
- package/core/anti-patterns.md +39 -39
- package/core/constraints.md +15 -15
- package/core/core-patterns.md +9 -9
- package/core/error-boundaries.md +7 -7
- package/core/multi-module.md +16 -16
- package/core/naming.md +21 -21
- package/core/plugins.md +14 -14
- package/core/react-adapter.md +13 -13
- package/core/resolvers.md +14 -14
- package/core/schema-types.md +22 -22
- package/core/system-api.md +16 -16
- package/core/testing.md +5 -5
- package/core/time-travel.md +20 -20
- package/dist/index.cjs +6 -105
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -97
- package/dist/index.js.map +1 -1
- package/examples/ab-testing.ts +18 -90
- package/examples/ai-checkpoint.ts +68 -87
- package/examples/ai-guardrails.ts +20 -70
- package/examples/auth-flow.ts +2 -2
- package/examples/batch-resolver.ts +19 -59
- package/examples/contact-form.ts +220 -69
- package/examples/counter.ts +77 -95
- package/examples/dashboard-loader.ts +37 -55
- package/examples/debounce-constraints.ts +0 -2
- package/examples/dynamic-modules.ts +17 -20
- package/examples/error-boundaries.ts +30 -81
- package/examples/newsletter.ts +22 -49
- package/examples/notifications.ts +24 -23
- package/examples/optimistic-updates.ts +36 -41
- package/examples/pagination.ts +2 -2
- package/examples/permissions.ts +22 -32
- package/examples/provider-routing.ts +26 -83
- package/examples/shopping-cart.ts +8 -8
- package/examples/sudoku.ts +55 -62
- package/examples/theme-locale.ts +4 -7
- package/examples/time-machine.ts +12 -90
- package/examples/topic-guard.ts +30 -38
- package/examples/url-sync.ts +8 -8
- package/examples/websocket.ts +5 -5
- package/package.json +3 -3
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Example: ai-guardrails
|
|
2
|
-
// Source: examples/ai-guardrails/src/
|
|
3
|
-
//
|
|
2
|
+
// Source: examples/ai-guardrails/src/module.ts
|
|
3
|
+
// Pure module file — no DOM wiring
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* AI Safety Shield —
|
|
6
|
+
* AI Safety Shield — Directive Module
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Types, schema, module definition, timeline, analysis functions,
|
|
9
|
+
* and system creation for prompt injection & PII detection guardrails.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {
|
|
@@ -27,7 +27,7 @@ import { devtoolsPlugin, emitDevToolsEvent } from "@directive-run/core/plugins";
|
|
|
27
27
|
// Types
|
|
28
28
|
// ============================================================================
|
|
29
29
|
|
|
30
|
-
interface ChatMessage {
|
|
30
|
+
export interface ChatMessage {
|
|
31
31
|
id: string;
|
|
32
32
|
text: string;
|
|
33
33
|
blocked: boolean;
|
|
@@ -36,22 +36,22 @@ interface ChatMessage {
|
|
|
36
36
|
piiResult: PIIDetectionResult | null;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
interface TimelineEntry {
|
|
39
|
+
export interface TimelineEntry {
|
|
40
40
|
time: number;
|
|
41
41
|
event: string;
|
|
42
42
|
detail: string;
|
|
43
43
|
type: "pass" | "injection" | "pii" | "compliance" | "info";
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
type ComplianceMode = "standard" | "gdpr" | "hipaa";
|
|
46
|
+
export type ComplianceMode = "standard" | "gdpr" | "hipaa";
|
|
47
47
|
|
|
48
48
|
// ============================================================================
|
|
49
49
|
// Timeline
|
|
50
50
|
// ============================================================================
|
|
51
51
|
|
|
52
|
-
const timeline: TimelineEntry[] = [];
|
|
52
|
+
export const timeline: TimelineEntry[] = [];
|
|
53
53
|
|
|
54
|
-
function addTimeline(
|
|
54
|
+
export function addTimeline(
|
|
55
55
|
event: string,
|
|
56
56
|
detail: string,
|
|
57
57
|
type: TimelineEntry["type"],
|
|
@@ -66,9 +66,9 @@ function addTimeline(
|
|
|
66
66
|
// Schema
|
|
67
67
|
// ============================================================================
|
|
68
68
|
|
|
69
|
-
const schema = {
|
|
69
|
+
export const schema = {
|
|
70
70
|
facts: {
|
|
71
|
-
messages: t.
|
|
71
|
+
messages: t.array<ChatMessage>(),
|
|
72
72
|
complianceMode: t.string<ComplianceMode>(),
|
|
73
73
|
redactionEnabled: t.boolean(),
|
|
74
74
|
blockedCount: t.number(),
|
|
@@ -159,18 +159,17 @@ const guardrailModule = createModule("guardrails", {
|
|
|
159
159
|
// System
|
|
160
160
|
// ============================================================================
|
|
161
161
|
|
|
162
|
-
const system = createSystem({
|
|
162
|
+
export const system = createSystem({
|
|
163
163
|
module: guardrailModule,
|
|
164
164
|
debug: { runHistory: true },
|
|
165
165
|
plugins: [devtoolsPlugin({ name: "ai-guardrails" })],
|
|
166
166
|
});
|
|
167
|
-
system.start();
|
|
168
167
|
|
|
169
168
|
// ============================================================================
|
|
170
169
|
// Analysis Functions
|
|
171
170
|
// ============================================================================
|
|
172
171
|
|
|
173
|
-
function analyzeMessage(text: string): ChatMessage {
|
|
172
|
+
export function analyzeMessage(text: string): ChatMessage {
|
|
174
173
|
const id = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
175
174
|
let blocked = false;
|
|
176
175
|
|
|
@@ -181,6 +180,7 @@ function analyzeMessage(text: string): ChatMessage {
|
|
|
181
180
|
system.facts.injectionAttempts =
|
|
182
181
|
(system.facts.injectionAttempts as number) + 1;
|
|
183
182
|
for (const p of injectionResult.patterns) {
|
|
183
|
+
addTimeline("injection", `${p.name} (${p.severity})`, "injection");
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -200,6 +200,7 @@ function analyzeMessage(text: string): ChatMessage {
|
|
|
200
200
|
if (piiResult.detected) {
|
|
201
201
|
system.facts.piiDetections = (system.facts.piiDetections as number) + 1;
|
|
202
202
|
for (const item of piiResult.items) {
|
|
203
|
+
addTimeline("pii", `${item.type} found`, "pii");
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
206
|
|
|
@@ -228,12 +229,14 @@ function analyzeMessage(text: string): ChatMessage {
|
|
|
228
229
|
blocked = true;
|
|
229
230
|
system.facts.complianceBlocks =
|
|
230
231
|
(system.facts.complianceBlocks as number) + 1;
|
|
232
|
+
addTimeline("compliance", "HIPAA: PHI detected", "compliance");
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
if (mode === "gdpr" && hasContactInfo) {
|
|
234
236
|
blocked = true;
|
|
235
237
|
system.facts.complianceBlocks =
|
|
236
238
|
(system.facts.complianceBlocks as number) + 1;
|
|
239
|
+
addTimeline("compliance", "GDPR: personal data detected", "compliance");
|
|
237
240
|
}
|
|
238
241
|
}
|
|
239
242
|
|
|
@@ -250,8 +253,10 @@ function analyzeMessage(text: string): ChatMessage {
|
|
|
250
253
|
}
|
|
251
254
|
|
|
252
255
|
if (!blocked && !piiResult.detected) {
|
|
256
|
+
addTimeline("pass", "message passed all checks", "pass");
|
|
253
257
|
}
|
|
254
258
|
|
|
259
|
+
const redactedText = piiResult.redactedText ?? text;
|
|
255
260
|
|
|
256
261
|
return {
|
|
257
262
|
id,
|
|
@@ -262,58 +267,3 @@ function analyzeMessage(text: string): ChatMessage {
|
|
|
262
267
|
piiResult: piiResult.detected ? piiResult : null,
|
|
263
268
|
};
|
|
264
269
|
}
|
|
265
|
-
|
|
266
|
-
// ============================================================================
|
|
267
|
-
// DOM References
|
|
268
|
-
// ============================================================================
|
|
269
|
-
|
|
270
|
-
"gs-compliance",
|
|
271
|
-
"gs-redaction",
|
|
272
|
-
|
|
273
|
-
// Timeline
|
|
274
|
-
|
|
275
|
-
// Pre-built test buttons
|
|
276
|
-
|
|
277
|
-
// ============================================================================
|
|
278
|
-
// Render
|
|
279
|
-
// ============================================================================
|
|
280
|
-
|
|
281
|
-
function escapeHtml(text: string): string {
|
|
282
|
-
|
|
283
|
-
return div.innerHTML;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// ============================================================================
|
|
288
|
-
// Subscribe
|
|
289
|
-
// ============================================================================
|
|
290
|
-
|
|
291
|
-
const allKeys = [
|
|
292
|
-
...Object.keys(schema.facts),
|
|
293
|
-
...Object.keys(schema.derivations),
|
|
294
|
-
];
|
|
295
|
-
system.subscribe(allKeys, render);
|
|
296
|
-
|
|
297
|
-
// ============================================================================
|
|
298
|
-
// Controls
|
|
299
|
-
// ============================================================================
|
|
300
|
-
|
|
301
|
-
function sendMessage(text: string) {
|
|
302
|
-
if (!text.trim()) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const msg = analyzeMessage(text);
|
|
307
|
-
const messages = [...(system.facts.messages as ChatMessage[]), msg];
|
|
308
|
-
system.facts.messages = messages;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// Test buttons
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
// ============================================================================
|
|
316
|
-
// Initial Render
|
|
317
|
-
// ============================================================================
|
|
318
|
-
|
|
319
|
-
render();
|
package/examples/auth-flow.ts
CHANGED
|
@@ -54,7 +54,7 @@ export const authFlowSchema = {
|
|
|
54
54
|
refreshBuffer: t.number(),
|
|
55
55
|
loginFailRate: t.number(),
|
|
56
56
|
refreshFailRate: t.number(),
|
|
57
|
-
eventLog: t.
|
|
57
|
+
eventLog: t.array<EventLogEntry>(),
|
|
58
58
|
},
|
|
59
59
|
derivations: {
|
|
60
60
|
isAuthenticated: t.boolean(),
|
|
@@ -87,7 +87,7 @@ export const authFlowSchema = {
|
|
|
87
87
|
// ============================================================================
|
|
88
88
|
|
|
89
89
|
function addLogEntry(facts: any, event: string, detail: string): void {
|
|
90
|
-
const log = [...
|
|
90
|
+
const log = [...facts.eventLog];
|
|
91
91
|
log.push({ timestamp: Date.now(), event, detail });
|
|
92
92
|
facts.eventLog = log;
|
|
93
93
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
// Example: batch-resolver
|
|
2
|
-
// Source: examples/batch-resolver/src/
|
|
3
|
-
//
|
|
2
|
+
// Source: examples/batch-resolver/src/module.ts
|
|
3
|
+
// Pure module file — no DOM wiring
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Batch Data Loader —
|
|
6
|
+
* Batch Data Loader — Directive Module
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* catches type mismatches.
|
|
8
|
+
* Types, schema, mock data, module definition, timeline, and system creation
|
|
9
|
+
* for a batched user profile loader with schema validation.
|
|
11
10
|
*/
|
|
12
11
|
|
|
13
12
|
import {
|
|
@@ -22,14 +21,14 @@ import { devtoolsPlugin } from "@directive-run/core/plugins";
|
|
|
22
21
|
// Types
|
|
23
22
|
// ============================================================================
|
|
24
23
|
|
|
25
|
-
interface UserProfile {
|
|
24
|
+
export interface UserProfile {
|
|
26
25
|
id: number;
|
|
27
26
|
name: string;
|
|
28
27
|
email: string;
|
|
29
28
|
role: string;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
interface TimelineEntry {
|
|
31
|
+
export interface TimelineEntry {
|
|
33
32
|
time: number;
|
|
34
33
|
event: string;
|
|
35
34
|
detail: string;
|
|
@@ -67,9 +66,9 @@ const MOCK_USERS: Record<number, UserProfile> = {
|
|
|
67
66
|
// Timeline
|
|
68
67
|
// ============================================================================
|
|
69
68
|
|
|
70
|
-
const timeline: TimelineEntry[] = [];
|
|
69
|
+
export const timeline: TimelineEntry[] = [];
|
|
71
70
|
|
|
72
|
-
function addTimeline(
|
|
71
|
+
export function addTimeline(
|
|
73
72
|
event: string,
|
|
74
73
|
detail: string,
|
|
75
74
|
type: TimelineEntry["type"],
|
|
@@ -84,15 +83,15 @@ function addTimeline(
|
|
|
84
83
|
// Schema
|
|
85
84
|
// ============================================================================
|
|
86
85
|
|
|
87
|
-
const schema = {
|
|
86
|
+
export const schema = {
|
|
88
87
|
facts: {
|
|
89
|
-
users: t.
|
|
90
|
-
loadingIds: t.
|
|
88
|
+
users: t.array<UserProfile>(),
|
|
89
|
+
loadingIds: t.array<number>(),
|
|
91
90
|
batchCount: t.number(),
|
|
92
91
|
totalRequests: t.number(),
|
|
93
92
|
batchWindowMs: t.number(),
|
|
94
93
|
failItemId: t.number(),
|
|
95
|
-
validationErrors: t.
|
|
94
|
+
validationErrors: t.array<string>(),
|
|
96
95
|
},
|
|
97
96
|
derivations: {
|
|
98
97
|
userCount: t.number(),
|
|
@@ -182,6 +181,7 @@ const batchModule = createModule("batch-loader", {
|
|
|
182
181
|
...facts.validationErrors,
|
|
183
182
|
"schema: expected array for 'users', got string",
|
|
184
183
|
];
|
|
184
|
+
addTimeline(
|
|
185
185
|
"validation",
|
|
186
186
|
"schema error: expected array for 'users'",
|
|
187
187
|
"validation",
|
|
@@ -225,6 +225,7 @@ const batchModule = createModule("batch-loader", {
|
|
|
225
225
|
},
|
|
226
226
|
resolveBatchWithResults: async (requirements, context) => {
|
|
227
227
|
const ids = requirements.map((r) => r.userId);
|
|
228
|
+
addTimeline(
|
|
228
229
|
"batch",
|
|
229
230
|
`batch formed: ${ids.length} items [${ids.join(", ")}]`,
|
|
230
231
|
"batch",
|
|
@@ -239,6 +240,7 @@ const batchModule = createModule("batch-loader", {
|
|
|
239
240
|
const failId = context.facts.failItemId;
|
|
240
241
|
const results = ids.map((id) => {
|
|
241
242
|
if (id === failId) {
|
|
243
|
+
addTimeline("error", `user ${id}: simulated failure`, "error");
|
|
242
244
|
|
|
243
245
|
return {
|
|
244
246
|
success: false as const,
|
|
@@ -248,6 +250,7 @@ const batchModule = createModule("batch-loader", {
|
|
|
248
250
|
|
|
249
251
|
const user = MOCK_USERS[id];
|
|
250
252
|
if (!user) {
|
|
253
|
+
addTimeline("error", `user ${id}: not found`, "error");
|
|
251
254
|
|
|
252
255
|
return {
|
|
253
256
|
success: false as const,
|
|
@@ -275,6 +278,7 @@ const batchModule = createModule("batch-loader", {
|
|
|
275
278
|
);
|
|
276
279
|
|
|
277
280
|
const successCount = results.filter((r) => r.success).length;
|
|
281
|
+
addTimeline(
|
|
278
282
|
"success",
|
|
279
283
|
`batch resolved: ${successCount}/${ids.length} success`,
|
|
280
284
|
"success",
|
|
@@ -290,52 +294,8 @@ const batchModule = createModule("batch-loader", {
|
|
|
290
294
|
// System
|
|
291
295
|
// ============================================================================
|
|
292
296
|
|
|
293
|
-
const system = createSystem({
|
|
297
|
+
export const system = createSystem({
|
|
294
298
|
module: batchModule,
|
|
295
299
|
debug: { runHistory: true },
|
|
296
300
|
plugins: [devtoolsPlugin({ name: "batch-resolver" })],
|
|
297
301
|
});
|
|
298
|
-
system.start();
|
|
299
|
-
|
|
300
|
-
// ============================================================================
|
|
301
|
-
// DOM References
|
|
302
|
-
// ============================================================================
|
|
303
|
-
|
|
304
|
-
"bl-fail-item",
|
|
305
|
-
|
|
306
|
-
// ============================================================================
|
|
307
|
-
// Render
|
|
308
|
-
// ============================================================================
|
|
309
|
-
|
|
310
|
-
function escapeHtml(text: string): string {
|
|
311
|
-
|
|
312
|
-
return div.innerHTML;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
// ============================================================================
|
|
317
|
-
// Subscribe
|
|
318
|
-
// ============================================================================
|
|
319
|
-
|
|
320
|
-
const allKeys = [
|
|
321
|
-
...Object.keys(schema.facts),
|
|
322
|
-
...Object.keys(schema.derivations),
|
|
323
|
-
];
|
|
324
|
-
system.subscribe(allKeys, render);
|
|
325
|
-
|
|
326
|
-
// ============================================================================
|
|
327
|
-
// Controls
|
|
328
|
-
// ============================================================================
|
|
329
|
-
|
|
330
|
-
// Individual load buttons (1-5)
|
|
331
|
-
for (let i = 1; i <= 5; i++) {
|
|
332
|
-
system.events.loadUser({ id: i });
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
// ============================================================================
|
|
338
|
-
// Initial Render
|
|
339
|
-
// ============================================================================
|
|
340
|
-
|
|
341
|
-
render();
|