@vurb/core 3.2.3 → 3.3.4
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 +677 -677
- package/dist/cli/constants.js +59 -59
- package/dist/cli/templates/config.js +26 -26
- package/dist/cli/templates/constants.d.ts +1 -1
- package/dist/cli/templates/constants.d.ts.map +1 -1
- package/dist/cli/templates/constants.js +1 -1
- package/dist/cli/templates/constants.js.map +1 -1
- package/dist/cli/templates/core.d.ts.map +1 -1
- package/dist/cli/templates/core.js +96 -169
- package/dist/cli/templates/core.js.map +1 -1
- package/dist/cli/templates/middleware.js +25 -25
- package/dist/cli/templates/readme.js +142 -142
- package/dist/cli/templates/testing.js +84 -84
- package/dist/cli/templates/tools.js +46 -46
- package/dist/cli/templates/vectors/database.js +69 -69
- package/dist/cli/templates/vectors/oauth.js +63 -63
- package/dist/cli/templates/vectors/openapi.js +97 -97
- package/dist/core/middleware/AuditTrail.d.ts +128 -0
- package/dist/core/middleware/AuditTrail.d.ts.map +1 -0
- package/dist/core/middleware/AuditTrail.js +94 -0
- package/dist/core/middleware/AuditTrail.js.map +1 -0
- package/dist/core/middleware/InputFirewall.d.ts +95 -0
- package/dist/core/middleware/InputFirewall.d.ts.map +1 -0
- package/dist/core/middleware/InputFirewall.js +104 -0
- package/dist/core/middleware/InputFirewall.js.map +1 -0
- package/dist/core/middleware/RateLimiter.d.ts +151 -0
- package/dist/core/middleware/RateLimiter.d.ts.map +1 -0
- package/dist/core/middleware/RateLimiter.js +121 -0
- package/dist/core/middleware/RateLimiter.js.map +1 -0
- package/dist/core/middleware/index.d.ts +6 -0
- package/dist/core/middleware/index.d.ts.map +1 -1
- package/dist/core/middleware/index.js +4 -0
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/index.d.ts +28 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/introspection/SemanticProbe.js +49 -49
- package/dist/observability/TelemetryEvent.d.ts +61 -1
- package/dist/observability/TelemetryEvent.d.ts.map +1 -1
- package/dist/presenter/JudgeChain.d.ts +129 -0
- package/dist/presenter/JudgeChain.d.ts.map +1 -0
- package/dist/presenter/JudgeChain.js +215 -0
- package/dist/presenter/JudgeChain.js.map +1 -0
- package/dist/presenter/PostProcessor.d.ts.map +1 -1
- package/dist/presenter/PostProcessor.js +11 -66
- package/dist/presenter/PostProcessor.js.map +1 -1
- package/dist/presenter/Presenter.d.ts +175 -37
- package/dist/presenter/Presenter.d.ts.map +1 -1
- package/dist/presenter/Presenter.js +265 -154
- package/dist/presenter/Presenter.js.map +1 -1
- package/dist/presenter/PresenterPipeline.d.ts +147 -0
- package/dist/presenter/PresenterPipeline.d.ts.map +1 -0
- package/dist/presenter/PresenterPipeline.js +271 -0
- package/dist/presenter/PresenterPipeline.js.map +1 -0
- package/dist/presenter/PromptFirewall.d.ts +160 -0
- package/dist/presenter/PromptFirewall.d.ts.map +1 -0
- package/dist/presenter/PromptFirewall.js +228 -0
- package/dist/presenter/PromptFirewall.js.map +1 -0
- package/dist/presenter/ResponseBuilder.d.ts +13 -0
- package/dist/presenter/ResponseBuilder.d.ts.map +1 -1
- package/dist/presenter/ResponseBuilder.js +28 -1
- package/dist/presenter/ResponseBuilder.js.map +1 -1
- package/dist/presenter/TelemetryCollector.d.ts +48 -0
- package/dist/presenter/TelemetryCollector.d.ts.map +1 -0
- package/dist/presenter/TelemetryCollector.js +93 -0
- package/dist/presenter/TelemetryCollector.js.map +1 -0
- package/dist/presenter/definePresenter.d.ts +112 -0
- package/dist/presenter/definePresenter.d.ts.map +1 -1
- package/dist/presenter/definePresenter.js +110 -0
- package/dist/presenter/definePresenter.js.map +1 -1
- package/dist/presenter/index.d.ts +6 -2
- package/dist/presenter/index.d.ts.map +1 -1
- package/dist/presenter/index.js +5 -1
- package/dist/presenter/index.js.map +1 -1
- package/dist/presenter/ui.d.ts +31 -8
- package/dist/presenter/ui.d.ts.map +1 -1
- package/dist/presenter/ui.js +16 -16
- package/dist/presenter/ui.js.map +1 -1
- package/dist/prompt/FluentPromptBuilder.d.ts.map +1 -1
- package/dist/resource/ResourceBuilder.d.ts +129 -0
- package/dist/resource/ResourceBuilder.d.ts.map +1 -0
- package/dist/resource/ResourceBuilder.js +93 -0
- package/dist/resource/ResourceBuilder.js.map +1 -0
- package/dist/resource/ResourceRegistry.d.ts +147 -0
- package/dist/resource/ResourceRegistry.d.ts.map +1 -0
- package/dist/resource/ResourceRegistry.js +234 -0
- package/dist/resource/ResourceRegistry.js.map +1 -0
- package/dist/resource/SubscriptionManager.d.ts +67 -0
- package/dist/resource/SubscriptionManager.d.ts.map +1 -0
- package/dist/resource/SubscriptionManager.js +86 -0
- package/dist/resource/SubscriptionManager.js.map +1 -0
- package/dist/resource/index.d.ts +13 -0
- package/dist/resource/index.d.ts.map +1 -0
- package/dist/resource/index.js +13 -0
- package/dist/resource/index.js.map +1 -0
- package/dist/server/ServerAttachment.d.ts +26 -0
- package/dist/server/ServerAttachment.d.ts.map +1 -1
- package/dist/server/ServerAttachment.js +70 -2
- package/dist/server/ServerAttachment.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/startServer.d.ts +22 -1
- package/dist/server/startServer.d.ts.map +1 -1
- package/dist/server/startServer.js +98 -5
- package/dist/server/startServer.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// ── Factory ──────────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* Create a compiled JudgeChain from configuration.
|
|
4
|
+
*
|
|
5
|
+
* @param config - Chain configuration (adapters, strategy, timeouts)
|
|
6
|
+
* @returns A compiled {@link JudgeChain} ready for evaluation
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { createJudgeChain } from '@vurb/core';
|
|
11
|
+
*
|
|
12
|
+
* const chain = createJudgeChain({
|
|
13
|
+
* adapters: [
|
|
14
|
+
* { name: 'gpt-4o-mini', evaluate: (p) => openai.chat(p) },
|
|
15
|
+
* { name: 'claude-haiku', evaluate: (p) => claude.message(p) },
|
|
16
|
+
* ],
|
|
17
|
+
* strategy: 'fallback',
|
|
18
|
+
* timeoutMs: 3000,
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const result = await chain.evaluate('Is this safe?');
|
|
22
|
+
* if (!result.passed) { // blocked }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function createJudgeChain(config) {
|
|
26
|
+
if (config.adapters.length === 0) {
|
|
27
|
+
throw new Error('[vurb] JudgeChain requires at least one adapter.');
|
|
28
|
+
}
|
|
29
|
+
const resolved = {
|
|
30
|
+
adapters: config.adapters,
|
|
31
|
+
strategy: config.strategy ?? 'fallback',
|
|
32
|
+
timeoutMs: config.timeoutMs ?? 5000,
|
|
33
|
+
failOpen: config.failOpen ?? false,
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
config: resolved,
|
|
37
|
+
evaluate: (prompt) => executeChain(resolved, prompt),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// ── Execution ────────────────────────────────────────────
|
|
41
|
+
/**
|
|
42
|
+
* Execute a single adapter with timeout guard.
|
|
43
|
+
*
|
|
44
|
+
* Uses `Promise.race` pattern. On timeout, rejects with a descriptive error.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
async function executeAdapter(adapter, prompt, timeoutMs, parseFn) {
|
|
49
|
+
const start = Date.now();
|
|
50
|
+
let timer;
|
|
51
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
52
|
+
timer = setTimeout(() => reject(new Error(`Judge "${adapter.name}" timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
53
|
+
});
|
|
54
|
+
try {
|
|
55
|
+
const rawResponse = await Promise.race([
|
|
56
|
+
adapter.evaluate(prompt),
|
|
57
|
+
timeoutPromise,
|
|
58
|
+
]);
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
const passed = parseFn(rawResponse);
|
|
61
|
+
return {
|
|
62
|
+
adapterName: adapter.name,
|
|
63
|
+
passed,
|
|
64
|
+
rawResponse,
|
|
65
|
+
durationMs: Date.now() - start,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
clearTimeout(timer);
|
|
70
|
+
return {
|
|
71
|
+
adapterName: adapter.name,
|
|
72
|
+
passed: false,
|
|
73
|
+
rawResponse: `ERROR: ${err instanceof Error ? err.message : String(err)}`,
|
|
74
|
+
durationMs: Date.now() - start,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Execute the full chain with the configured strategy.
|
|
80
|
+
*
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
async function executeChain(config, prompt) {
|
|
84
|
+
const start = Date.now();
|
|
85
|
+
const parseFn = parseJudgePass;
|
|
86
|
+
if (config.strategy === 'fallback') {
|
|
87
|
+
return executeFallback(config, prompt, parseFn, start);
|
|
88
|
+
}
|
|
89
|
+
return executeConsensus(config, prompt, parseFn, start);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Fallback strategy: try adapters sequentially until one succeeds.
|
|
93
|
+
*
|
|
94
|
+
* @internal
|
|
95
|
+
*/
|
|
96
|
+
async function executeFallback(config, prompt, parseFn, start) {
|
|
97
|
+
const results = [];
|
|
98
|
+
for (const adapter of config.adapters) {
|
|
99
|
+
const result = await executeAdapter(adapter, prompt, config.timeoutMs, parseFn);
|
|
100
|
+
results.push(result);
|
|
101
|
+
// If we got a real response (not an error), use it
|
|
102
|
+
if (!result.rawResponse.startsWith('ERROR:')) {
|
|
103
|
+
return {
|
|
104
|
+
passed: result.passed,
|
|
105
|
+
results,
|
|
106
|
+
totalDurationMs: Date.now() - start,
|
|
107
|
+
fallbackTriggered: false,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Otherwise, try next adapter
|
|
111
|
+
}
|
|
112
|
+
// All adapters failed — apply failOpen/failClosed
|
|
113
|
+
return {
|
|
114
|
+
passed: config.failOpen,
|
|
115
|
+
results,
|
|
116
|
+
totalDurationMs: Date.now() - start,
|
|
117
|
+
fallbackTriggered: true,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Consensus strategy: ALL adapters must agree.
|
|
122
|
+
*
|
|
123
|
+
* Runs all adapters in parallel. If any fails with an error,
|
|
124
|
+
* the result depends on `failOpen`. If any returns `passed: false`,
|
|
125
|
+
* the content is blocked regardless of `failOpen`.
|
|
126
|
+
*
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
async function executeConsensus(config, prompt, parseFn, start) {
|
|
130
|
+
const settled = await Promise.allSettled(config.adapters.map(adapter => executeAdapter(adapter, prompt, config.timeoutMs, parseFn)));
|
|
131
|
+
const results = [];
|
|
132
|
+
let anyError = false;
|
|
133
|
+
let anyRejected = false;
|
|
134
|
+
for (const outcome of settled) {
|
|
135
|
+
if (outcome.status === 'fulfilled') {
|
|
136
|
+
results.push(outcome.value);
|
|
137
|
+
if (outcome.value.rawResponse.startsWith('ERROR:')) {
|
|
138
|
+
anyError = true;
|
|
139
|
+
}
|
|
140
|
+
else if (!outcome.value.passed) {
|
|
141
|
+
anyRejected = true;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
anyError = true;
|
|
146
|
+
results.push({
|
|
147
|
+
adapterName: 'unknown',
|
|
148
|
+
passed: false,
|
|
149
|
+
rawResponse: `ERROR: ${String(outcome.reason)}`,
|
|
150
|
+
durationMs: Date.now() - start,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// If any judge explicitly rejected → always blocked
|
|
155
|
+
if (anyRejected) {
|
|
156
|
+
return {
|
|
157
|
+
passed: false,
|
|
158
|
+
results,
|
|
159
|
+
totalDurationMs: Date.now() - start,
|
|
160
|
+
fallbackTriggered: false,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
// If all judges errored → apply failOpen/failClosed
|
|
164
|
+
if (anyError) {
|
|
165
|
+
return {
|
|
166
|
+
passed: config.failOpen,
|
|
167
|
+
results,
|
|
168
|
+
totalDurationMs: Date.now() - start,
|
|
169
|
+
fallbackTriggered: true,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
// All judges passed
|
|
173
|
+
return {
|
|
174
|
+
passed: true,
|
|
175
|
+
results,
|
|
176
|
+
totalDurationMs: Date.now() - start,
|
|
177
|
+
fallbackTriggered: false,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// ── Response Parsing ─────────────────────────────────────
|
|
181
|
+
/**
|
|
182
|
+
* Parse a judge's raw response to determine pass/fail.
|
|
183
|
+
*
|
|
184
|
+
* Expects a JSON response with a `"safe"` boolean field.
|
|
185
|
+
* Falls back to text matching for non-JSON responses.
|
|
186
|
+
*
|
|
187
|
+
* @internal
|
|
188
|
+
*/
|
|
189
|
+
function parseJudgePass(raw) {
|
|
190
|
+
try {
|
|
191
|
+
const jsonMatch = raw.match(/\{[\s\S]*\}/);
|
|
192
|
+
if (jsonMatch) {
|
|
193
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
194
|
+
// Support multiple field names
|
|
195
|
+
if (typeof parsed.safe === 'boolean')
|
|
196
|
+
return parsed.safe;
|
|
197
|
+
if (typeof parsed.passed === 'boolean')
|
|
198
|
+
return parsed.passed;
|
|
199
|
+
if (typeof parsed.allowed === 'boolean')
|
|
200
|
+
return parsed.allowed;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// Fall through to text matching
|
|
205
|
+
}
|
|
206
|
+
// Text-based fallback — conservative (default: fail-closed)
|
|
207
|
+
const lower = raw.toLowerCase();
|
|
208
|
+
if (lower.includes('"safe": true') || lower.includes('"safe":true'))
|
|
209
|
+
return true;
|
|
210
|
+
if (lower.includes('"safe": false') || lower.includes('"safe":false'))
|
|
211
|
+
return false;
|
|
212
|
+
// Unparseable → treated as error (passthrough depends on failOpen)
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=JudgeChain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JudgeChain.js","sourceRoot":"","sources":["../../src/presenter/JudgeChain.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostProcessor.d.ts","sourceRoot":"","sources":["../../src/presenter/PostProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,YAAY,EAA8B,MAAM,qBAAqB,CAAC;AAEpF,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"PostProcessor.d.ts","sourceRoot":"","sources":["../../src/presenter/PostProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,YAAY,EAA8B,MAAM,qBAAqB,CAAC;AAEpF,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAKxE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,EACzC,GAAG,CAAC,EAAE,OAAO,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,EACvB,SAAS,CAAC,EAAE,oBAAoB,GACjC,YAAY,CA0Cd;AAID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAgBpE"}
|
|
@@ -12,7 +12,7 @@ import { success as successResponse } from '../core/response.js';
|
|
|
12
12
|
import { isResponseBuilder } from './ResponseBuilder.js';
|
|
13
13
|
import {} from './Presenter.js';
|
|
14
14
|
import {} from '../observability/TelemetryEvent.js';
|
|
15
|
-
|
|
15
|
+
import { emitPresenterTelemetry } from './TelemetryCollector.js';
|
|
16
16
|
/**
|
|
17
17
|
* Post-process a handler's return value through the MVA priority hierarchy.
|
|
18
18
|
*
|
|
@@ -42,77 +42,22 @@ export function postProcessResult(result, presenter, ctx, selectFields, telemetr
|
|
|
42
42
|
}
|
|
43
43
|
// Priority 3: Raw data + Presenter → pipe through MVA
|
|
44
44
|
if (presenter) {
|
|
45
|
-
//
|
|
46
|
-
const rawJson = telemetry ? JSON.stringify(result) :
|
|
47
|
-
const rawBytes = rawJson ? _encoder.encode(rawJson).byteLength : 0;
|
|
45
|
+
// Pre-serialize for telemetry (skip if no sink)
|
|
46
|
+
const rawJson = telemetry ? JSON.stringify(result) : '';
|
|
48
47
|
const rawRows = Array.isArray(result) ? result.length : 1;
|
|
49
48
|
const response = presenter.make(result, ctx, selectFields).build();
|
|
50
|
-
//
|
|
49
|
+
// Delegate all telemetry emission to TelemetryCollector
|
|
51
50
|
if (telemetry) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
for (const c of response.content) {
|
|
55
|
-
if ('text' in c && typeof c.text === 'string') {
|
|
56
|
-
wireBytes += _encoder.encode(c.text).byteLength;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Compute wire rows — agentLimit may have truncated
|
|
60
|
-
const agentLimitMax = presenter.getAgentLimitMax();
|
|
61
|
-
const wireRows = (agentLimitMax !== undefined && rawRows > agentLimitMax)
|
|
62
|
-
? agentLimitMax
|
|
63
|
-
: rawRows;
|
|
64
|
-
telemetry.sink({
|
|
65
|
-
type: 'presenter.slice',
|
|
51
|
+
emitPresenterTelemetry({
|
|
52
|
+
sink: telemetry.sink,
|
|
66
53
|
tool: telemetry.tool,
|
|
67
54
|
action: telemetry.action,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
...(selectFields && selectFields.length > 0 ? {
|
|
74
|
-
selectFields,
|
|
75
|
-
totalFields: presenter.getSchemaKeys().length || undefined,
|
|
76
|
-
} : {}),
|
|
77
|
-
...(agentLimitMax !== undefined && rawRows > agentLimitMax ? {
|
|
78
|
-
guardrailFrom: rawRows,
|
|
79
|
-
guardrailTo: agentLimitMax,
|
|
80
|
-
guardrailHint: 'Results truncated by agentLimit. Use pagination or filters.',
|
|
81
|
-
} : {}),
|
|
82
|
-
timestamp: Date.now(),
|
|
55
|
+
response,
|
|
56
|
+
presenter,
|
|
57
|
+
rawJson,
|
|
58
|
+
rawRows,
|
|
59
|
+
selectFields,
|
|
83
60
|
});
|
|
84
|
-
// Extract rules from the built response text content
|
|
85
|
-
// Rules are embedded as <domain_rules> XML blocks by the ResponseBuilder
|
|
86
|
-
const rulesFromResponse = [];
|
|
87
|
-
for (const c of response.content) {
|
|
88
|
-
if ('text' in c && typeof c.text === 'string') {
|
|
89
|
-
const match = c.text.match(/<domain_rules>\n([\s\S]*?)\n<\/domain_rules>/);
|
|
90
|
-
if (match) {
|
|
91
|
-
rulesFromResponse.push(...match[1].split('\n').filter(Boolean).map(r => r.replace(/^- /, '')));
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
if (rulesFromResponse.length > 0) {
|
|
96
|
-
telemetry.sink({
|
|
97
|
-
type: 'presenter.rules',
|
|
98
|
-
tool: telemetry.tool,
|
|
99
|
-
action: telemetry.action,
|
|
100
|
-
rules: rulesFromResponse,
|
|
101
|
-
timestamp: Date.now(),
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
// Emit DLP redaction event if the Presenter has redact paths
|
|
105
|
-
const redactPaths = presenter.getRedactPaths();
|
|
106
|
-
if (redactPaths.length > 0) {
|
|
107
|
-
telemetry.sink({
|
|
108
|
-
type: 'dlp.redact',
|
|
109
|
-
tool: telemetry.tool,
|
|
110
|
-
action: telemetry.action,
|
|
111
|
-
fieldsRedacted: redactPaths.length,
|
|
112
|
-
paths: [...redactPaths],
|
|
113
|
-
timestamp: Date.now(),
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
61
|
}
|
|
117
62
|
return response;
|
|
118
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostProcessor.js","sourceRoot":"","sources":["../../src/presenter/PostProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAqB,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAwB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAkB,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAsB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"PostProcessor.js","sourceRoot":"","sources":["../../src/presenter/PostProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAqB,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAwB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAkB,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAsB,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAejE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,iBAAiB,CAC7B,MAAe,EACf,SAAyC,EACzC,GAAa,EACb,YAAuB,EACvB,SAAgC;IAEhC,yDAAyD;IACzD,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,4DAA4D;IAC5D,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,OAAQ,MAA0B,CAAC,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,sDAAsD;IACtD,IAAI,SAAS,EAAE,CAAC;QACZ,gDAAgD;QAChD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE1D,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,KAAK,EAAE,CAAC;QAEnE,wDAAwD;QACxD,IAAI,SAAS,EAAE,CAAC;YACZ,sBAAsB,CAAC;gBACnB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,QAAQ;gBACR,SAAS;gBACT,OAAO;gBACP,OAAO;gBACP,YAAY;aACf,CAAC,CAAC;QACP,CAAC;QAED,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,sEAAsE;IACtE,OAAO,eAAe,CAClB,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ;QACpD,CAAC,CAAE,MAA0B;QAC7B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CACvB,CAAC;AACN,CAAC;AAED,4DAA4D;AAE5D;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IACzC,IACI,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC;QACrB,CAAC,KAAK,CAAC,OAAO,CAAE,KAA8B,CAAC,OAAO,CAAC,EACzD,CAAC;QACC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,OAAO,GAAI,KAAgC,CAAC,OAAO,CAAC;IAC1D,sDAAsD;IACtD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,mDAAmD;IACnD,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAwC,CAAC;IAChE,OAAO,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC;AAC9D,CAAC"}
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
import { z, ZodType, type ZodRawShape } from 'zod';
|
|
56
56
|
import { ResponseBuilder } from './ResponseBuilder.js';
|
|
57
57
|
import { type UiBlock } from './ui.js';
|
|
58
|
+
import { type PresenterSnapshot, type CollectionRulesFn, type ItemUiBlocksFn, type CollectionUiBlocksFn, type SuggestActionsFn, type CollectionSuggestActionsFn } from './PresenterPipeline.js';
|
|
59
|
+
import { type PromptFirewallConfig } from './PromptFirewall.js';
|
|
58
60
|
/**
|
|
59
61
|
* Check if a value is a {@link Presenter} instance.
|
|
60
62
|
*
|
|
@@ -72,12 +74,15 @@ export interface ActionSuggestion {
|
|
|
72
74
|
/** Human-readable reason for the suggestion */
|
|
73
75
|
readonly reason: string;
|
|
74
76
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
export type { RulesConfig, CollectionRulesFn, ItemUiBlocksFn, CollectionUiBlocksFn, SuggestActionsFn, CollectionSuggestActionsFn, AgentLimitConfig, EmbedEntry, } from './PresenterPipeline.js';
|
|
78
|
+
/** Async UI blocks callback (single item) */
|
|
79
|
+
type AsyncItemUiBlocksFn<T> = (item: T, ctx?: unknown) => Promise<(UiBlock | null)[]>;
|
|
80
|
+
/** Async UI blocks callback (collection) */
|
|
81
|
+
type AsyncCollectionUiBlocksFn<T> = (items: T[], ctx?: unknown) => Promise<(UiBlock | null)[]>;
|
|
82
|
+
/** Async rules callback */
|
|
83
|
+
type AsyncRulesFn<T> = (data: T, ctx?: unknown) => Promise<(string | null)[]>;
|
|
84
|
+
/** Async suggest actions callback */
|
|
85
|
+
type AsyncSuggestActionsFn<T> = (data: T, ctx?: unknown) => Promise<(ActionSuggestion | null)[]>;
|
|
81
86
|
/**
|
|
82
87
|
* Domain-level Presenter — the "View" in MVA (Model-View-Agent).
|
|
83
88
|
*
|
|
@@ -103,13 +108,20 @@ export declare class Presenter<T> {
|
|
|
103
108
|
private _itemUiBlocks?;
|
|
104
109
|
private _collectionUiBlocks?;
|
|
105
110
|
private _suggestActions?;
|
|
111
|
+
private _collectionSuggestActions?;
|
|
106
112
|
private _agentLimit?;
|
|
107
113
|
private _embeds;
|
|
108
114
|
private _sealed;
|
|
115
|
+
private _collectionRules;
|
|
109
116
|
private _compiledStringify;
|
|
110
117
|
private _compiledRedactor;
|
|
111
118
|
private _redactConfig;
|
|
112
119
|
private _redactPaths;
|
|
120
|
+
private _asyncItemUiBlocks?;
|
|
121
|
+
private _asyncCollectionUiBlocks?;
|
|
122
|
+
private _asyncRules?;
|
|
123
|
+
private _asyncSuggestActions?;
|
|
124
|
+
private _promptFirewall?;
|
|
113
125
|
/** @internal Use {@link createPresenter} factory instead */
|
|
114
126
|
constructor(name: string);
|
|
115
127
|
/**
|
|
@@ -270,6 +282,32 @@ export declare class Presenter<T> {
|
|
|
270
282
|
* ```
|
|
271
283
|
*/
|
|
272
284
|
suggestActions(fn: SuggestActionsFn<T>): this;
|
|
285
|
+
/**
|
|
286
|
+
* Define HATEOAS-style action suggestions for **collections**.
|
|
287
|
+
*
|
|
288
|
+
* Unlike `.suggestActions()`, this callback receives the **entire array**
|
|
289
|
+
* of validated items, enabling aggregate-level suggestions like batch
|
|
290
|
+
* operations, bulk approvals, or summary insights.
|
|
291
|
+
*
|
|
292
|
+
* When both `.suggestActions()` and `.collectionSuggestActions()` are set,
|
|
293
|
+
* only collectionSuggestActions is used for arrays.
|
|
294
|
+
*
|
|
295
|
+
* @param fn - `(items[], ctx?) => (ActionSuggestion | null)[]`
|
|
296
|
+
* @returns `this` for chaining
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```typescript
|
|
300
|
+
* .collectionSuggestActions((invoices) => [
|
|
301
|
+
* invoices.some(i => i.status === 'overdue')
|
|
302
|
+
* ? { tool: 'billing.batch_remind', reason: 'Send batch reminders' }
|
|
303
|
+
* : null,
|
|
304
|
+
* invoices.length > 100
|
|
305
|
+
* ? { tool: 'billing.export', reason: 'Export results for offline review' }
|
|
306
|
+
* : null,
|
|
307
|
+
* ])
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
collectionSuggestActions(fn: CollectionSuggestActionsFn<T>): this;
|
|
273
311
|
/**
|
|
274
312
|
* Alias for `.suggestActions()` — fluent shorthand.
|
|
275
313
|
*
|
|
@@ -292,6 +330,13 @@ export declare class Presenter<T> {
|
|
|
292
330
|
* ```
|
|
293
331
|
*/
|
|
294
332
|
suggest(fn: SuggestActionsFn<T>): this;
|
|
333
|
+
/**
|
|
334
|
+
* Alias for `.collectionSuggestActions()` — fluent shorthand.
|
|
335
|
+
*
|
|
336
|
+
* @param fn - `(items[], ctx?) => (ActionSuggestion | null)[]`
|
|
337
|
+
* @returns `this` for chaining
|
|
338
|
+
*/
|
|
339
|
+
collectionSuggest(fn: CollectionSuggestActionsFn<T>): this;
|
|
295
340
|
/**
|
|
296
341
|
* Alias for `.systemRules()` — fluent shorthand.
|
|
297
342
|
*
|
|
@@ -307,6 +352,29 @@ export declare class Presenter<T> {
|
|
|
307
352
|
* ```
|
|
308
353
|
*/
|
|
309
354
|
rules(rules: readonly string[] | ((data: T, ctx?: unknown) => (string | null)[])): this;
|
|
355
|
+
/**
|
|
356
|
+
* Set collection-level system rules.
|
|
357
|
+
*
|
|
358
|
+
* Unlike `.systemRules()`, these rules are evaluated with the **entire
|
|
359
|
+
* array** of validated items. Use for aggregate context (totals, counts,
|
|
360
|
+
* mixed-status warnings) that cannot be derived from a single item.
|
|
361
|
+
*
|
|
362
|
+
* Both per-item and collection rules are merged in the response.
|
|
363
|
+
*
|
|
364
|
+
* @param rules - Static rules array, or dynamic `(items[], ctx?) => (string | null)[]`
|
|
365
|
+
* @returns `this` for chaining
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```typescript
|
|
369
|
+
* .collectionRules((invoices, ctx) => [
|
|
370
|
+
* `Total: ${invoices.length} invoices found.`,
|
|
371
|
+
* invoices.some(i => i.status === 'overdue')
|
|
372
|
+
* ? '⚠️ Some invoices are OVERDUE. Highlight them.'
|
|
373
|
+
* : null,
|
|
374
|
+
* ])
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
collectionRules(rules: CollectionRulesFn<T>): this;
|
|
310
378
|
/**
|
|
311
379
|
* Alias for `.uiBlocks()` — fluent shorthand.
|
|
312
380
|
*
|
|
@@ -473,6 +541,69 @@ export declare class Presenter<T> {
|
|
|
473
541
|
* @returns Static rule strings, or empty array if rules are contextual
|
|
474
542
|
*/
|
|
475
543
|
getStaticRuleStrings(): readonly string[];
|
|
544
|
+
/**
|
|
545
|
+
* Register an **async** UI block callback for single items.
|
|
546
|
+
*
|
|
547
|
+
* Use when UI generation requires I/O (database, API, file system).
|
|
548
|
+
* Must be consumed via `makeAsync()` — `make()` ignores async callbacks.
|
|
549
|
+
*
|
|
550
|
+
* @param fn - Async function receiving validated data + optional context
|
|
551
|
+
* @returns `this` for chaining
|
|
552
|
+
*
|
|
553
|
+
* @example
|
|
554
|
+
* ```typescript
|
|
555
|
+
* createPresenter('Invoice')
|
|
556
|
+
* .asyncUiBlocks(async (inv, ctx) => {
|
|
557
|
+
* const history = await ctx.db.payments.history(inv.id);
|
|
558
|
+
* return [ui.echarts(buildTimeline(history))];
|
|
559
|
+
* });
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
562
|
+
asyncUiBlocks(fn: AsyncItemUiBlocksFn<T>): this;
|
|
563
|
+
/**
|
|
564
|
+
* Register an **async** UI block callback for collections.
|
|
565
|
+
*
|
|
566
|
+
* @param fn - Async function receiving the full validated array + optional context
|
|
567
|
+
* @returns `this` for chaining
|
|
568
|
+
*/
|
|
569
|
+
asyncCollectionUiBlocks(fn: AsyncCollectionUiBlocksFn<T>): this;
|
|
570
|
+
/**
|
|
571
|
+
* Register **async** system rules generation.
|
|
572
|
+
*
|
|
573
|
+
* @param fn - Async function receiving validated data + optional context
|
|
574
|
+
* @returns `this` for chaining
|
|
575
|
+
*/
|
|
576
|
+
asyncRules(fn: AsyncRulesFn<T>): this;
|
|
577
|
+
/**
|
|
578
|
+
* Register **async** action suggestions generation.
|
|
579
|
+
*
|
|
580
|
+
* @param fn - Async function receiving validated data + optional context
|
|
581
|
+
* @returns `this` for chaining
|
|
582
|
+
*/
|
|
583
|
+
asyncSuggestActions(fn: AsyncSuggestActionsFn<T>): this;
|
|
584
|
+
/**
|
|
585
|
+
* Enable LLM-as-Judge evaluation of dynamic system rules.
|
|
586
|
+
*
|
|
587
|
+
* The PromptFirewall evaluates all resolved rules (sync + async)
|
|
588
|
+
* through a judge chain before they reach the LLM. This prevents
|
|
589
|
+
* prompt injection via tainted data interpolated in `.systemRules()`.
|
|
590
|
+
*
|
|
591
|
+
* **Important:** Presenters with a firewall MUST use `makeAsync()`.
|
|
592
|
+
* Calling `make()` will throw an error.
|
|
593
|
+
*
|
|
594
|
+
* @param config - Firewall configuration (adapter or chain)
|
|
595
|
+
* @returns `this` for chaining
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* ```typescript
|
|
599
|
+
* createPresenter('Invoice')
|
|
600
|
+
* .systemRules((inv) => [`Status: ${inv.description}`])
|
|
601
|
+
* .promptFirewall({
|
|
602
|
+
* adapter: { name: 'gpt-4o-mini', evaluate: (p) => openai.chat(p) },
|
|
603
|
+
* });
|
|
604
|
+
* ```
|
|
605
|
+
*/
|
|
606
|
+
promptFirewall(config: PromptFirewallConfig): this;
|
|
476
607
|
/**
|
|
477
608
|
* Compose a {@link ResponseBuilder} from raw data.
|
|
478
609
|
*
|
|
@@ -511,42 +642,50 @@ export declare class Presenter<T> {
|
|
|
511
642
|
*/
|
|
512
643
|
make(data: T | T[], ctx?: unknown, selectFields?: string[]): ResponseBuilder;
|
|
513
644
|
/**
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
*
|
|
521
|
-
* For arrays, each item is validated independently.
|
|
522
|
-
* @internal
|
|
523
|
-
*/
|
|
524
|
-
private _validate;
|
|
525
|
-
/**
|
|
526
|
-
* Generate and attach UI blocks to the response builder.
|
|
527
|
-
* Auto-detects single vs collection. Filters `null` blocks.
|
|
528
|
-
* @internal
|
|
529
|
-
*/
|
|
530
|
-
private _attachUiBlocks;
|
|
531
|
-
/**
|
|
532
|
-
* Resolve and attach domain rules to the response builder.
|
|
533
|
-
* Supports both static arrays and dynamic context-aware functions.
|
|
534
|
-
* Filters `null` rules automatically.
|
|
535
|
-
* @internal
|
|
645
|
+
* Check if this Presenter has any async callbacks configured.
|
|
646
|
+
*
|
|
647
|
+
* Used by the pipeline to decide between sync `make()` and async
|
|
648
|
+
* `makeAsync()`. When no async callbacks are set, `makeAsync()` is
|
|
649
|
+
* equivalent to `Promise.resolve(make())`, so the sync path is preferred.
|
|
650
|
+
*
|
|
651
|
+
* @returns `true` if any async callback is configured
|
|
536
652
|
*/
|
|
537
|
-
|
|
653
|
+
hasAsyncCallbacks(): boolean;
|
|
538
654
|
/**
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
655
|
+
* Async version of `make()` — enriches the response with async callbacks.
|
|
656
|
+
*
|
|
657
|
+
* Runs all sync steps first (via `make()`), then awaits async callbacks
|
|
658
|
+
* and appends their results to the builder. The sync `make()` method
|
|
659
|
+
* remains unchanged (zero breaking changes).
|
|
660
|
+
*
|
|
661
|
+
* @param data - Raw data from the handler (object or array)
|
|
662
|
+
* @param ctx - Optional request context
|
|
663
|
+
* @param selectFields - Optional top-level field names for context window optimization
|
|
664
|
+
* @returns A Promise resolving to a {@link ResponseBuilder}
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* ```typescript
|
|
668
|
+
* const presenter = createPresenter('Invoice')
|
|
669
|
+
* .schema(invoiceSchema)
|
|
670
|
+
* .asyncUiBlocks(async (inv, ctx) => {
|
|
671
|
+
* const history = await ctx.db.payments.history(inv.id);
|
|
672
|
+
* return [ui.echarts(buildTimeline(history))];
|
|
673
|
+
* });
|
|
674
|
+
*
|
|
675
|
+
* // In handler:
|
|
676
|
+
* const builder = await presenter.makeAsync(data, ctx);
|
|
677
|
+
* return builder.build();
|
|
678
|
+
* ```
|
|
542
679
|
*/
|
|
543
|
-
|
|
680
|
+
makeAsync(data: T | T[], ctx?: unknown, selectFields?: string[]): Promise<ResponseBuilder>;
|
|
544
681
|
/**
|
|
545
|
-
*
|
|
546
|
-
*
|
|
682
|
+
* Create a read-only snapshot of the Presenter's configuration
|
|
683
|
+
* for use by the decomposed pipeline steps.
|
|
684
|
+
*
|
|
685
|
+
* @returns A {@link PresenterSnapshot} capturing the current config
|
|
547
686
|
* @internal
|
|
548
687
|
*/
|
|
549
|
-
|
|
688
|
+
_toSnapshot(): PresenterSnapshot<T>;
|
|
550
689
|
}
|
|
551
690
|
/**
|
|
552
691
|
* Create a new domain-level Presenter.
|
|
@@ -571,5 +710,4 @@ export declare class Presenter<T> {
|
|
|
571
710
|
* @see {@link Presenter} for the full API
|
|
572
711
|
*/
|
|
573
712
|
export declare function createPresenter(name: string): Presenter<unknown>;
|
|
574
|
-
export {};
|
|
575
713
|
//# sourceMappingURL=Presenter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Presenter.d.ts","sourceRoot":"","sources":["../../src/presenter/Presenter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,WAAW,EAAY,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Presenter.d.ts","sourceRoot":"","sources":["../../src/presenter/Presenter.ts"],"names":[],"mappings":"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"}
|