@framers/agentos 0.1.56 → 0.1.57
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 +67 -16
- package/dist/api/types/AgentOSResponse.d.ts +7 -0
- package/dist/api/types/AgentOSResponse.d.ts.map +1 -1
- package/dist/core/guardrails/IGuardrailService.d.ts +39 -0
- package/dist/core/guardrails/IGuardrailService.d.ts.map +1 -1
- package/dist/core/guardrails/ParallelGuardrailDispatcher.d.ts +92 -0
- package/dist/core/guardrails/ParallelGuardrailDispatcher.d.ts.map +1 -0
- package/dist/core/guardrails/ParallelGuardrailDispatcher.js +463 -0
- package/dist/core/guardrails/ParallelGuardrailDispatcher.js.map +1 -0
- package/dist/core/guardrails/guardrailDispatcher.d.ts +59 -1
- package/dist/core/guardrails/guardrailDispatcher.d.ts.map +1 -1
- package/dist/core/guardrails/guardrailDispatcher.js +49 -154
- package/dist/core/guardrails/guardrailDispatcher.js.map +1 -1
- package/dist/core/guardrails/index.d.ts +1 -0
- package/dist/core/guardrails/index.d.ts.map +1 -1
- package/dist/core/guardrails/index.js +2 -0
- package/dist/core/guardrails/index.js.map +1 -1
- package/dist/core/utils/index.d.ts +13 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/index.js +13 -0
- package/dist/core/utils/index.js.map +1 -0
- package/dist/core/utils/text-utils.d.ts +164 -0
- package/dist/core/utils/text-utils.d.ts.map +1 -0
- package/dist/core/utils/text-utils.js +254 -0
- package/dist/core/utils/text-utils.js.map +1 -0
- package/dist/extensions/index.d.ts +0 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +0 -2
- package/dist/extensions/index.js.map +1 -1
- package/package.json +1 -6
- package/dist/extensions/packs/pii-redaction/EntityMerger.d.ts +0 -127
- package/dist/extensions/packs/pii-redaction/EntityMerger.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/EntityMerger.js +0 -263
- package/dist/extensions/packs/pii-redaction/EntityMerger.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.d.ts +0 -199
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.js +0 -456
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.d.ts +0 -121
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.js +0 -271
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/RedactionEngine.d.ts +0 -61
- package/dist/extensions/packs/pii-redaction/RedactionEngine.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/RedactionEngine.js +0 -207
- package/dist/extensions/packs/pii-redaction/RedactionEngine.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/index.d.ts +0 -90
- package/dist/extensions/packs/pii-redaction/index.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/index.js +0 -195
- package/dist/extensions/packs/pii-redaction/index.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.d.ts +0 -151
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.js +0 -14
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.d.ts +0 -177
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.js +0 -420
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.d.ts +0 -145
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.js +0 -299
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.d.ts +0 -102
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.js +0 -228
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.d.ts +0 -103
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.js +0 -275
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.d.ts +0 -118
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.js +0 -152
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.d.ts +0 -98
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.js +0 -153
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.js.map +0 -1
- package/dist/extensions/packs/pii-redaction/types.d.ts +0 -332
- package/dist/extensions/packs/pii-redaction/types.d.ts.map +0 -1
- package/dist/extensions/packs/pii-redaction/types.js +0 -83
- package/dist/extensions/packs/pii-redaction/types.js.map +0 -1
|
@@ -31,12 +31,29 @@
|
|
|
31
31
|
*/
|
|
32
32
|
import { uuidv4 } from '../../utils/uuid.js';
|
|
33
33
|
import { AgentOSResponseChunkType, } from '../../api/types/AgentOSResponse.js';
|
|
34
|
-
import {
|
|
34
|
+
import { ParallelGuardrailDispatcher } from './ParallelGuardrailDispatcher.js';
|
|
35
|
+
/**
|
|
36
|
+
* Normalize a service input (single, array, or undefined) into a flat array.
|
|
37
|
+
*
|
|
38
|
+
* Filters out falsy entries so callers never need null-checks.
|
|
39
|
+
*
|
|
40
|
+
* @param service - Single guardrail, array of guardrails, or undefined
|
|
41
|
+
* @returns Non-empty array of valid guardrail services
|
|
42
|
+
*/
|
|
43
|
+
export function normalizeServices(service) {
|
|
44
|
+
return Array.isArray(service)
|
|
45
|
+
? service.filter(Boolean)
|
|
46
|
+
: service
|
|
47
|
+
? [service]
|
|
48
|
+
: [];
|
|
49
|
+
}
|
|
35
50
|
/**
|
|
36
51
|
* Type guard to check if a guardrail service implements evaluateOutput.
|
|
37
|
-
*
|
|
52
|
+
*
|
|
53
|
+
* @param svc - The guardrail service to inspect
|
|
54
|
+
* @returns `true` when `svc.evaluateOutput` is a callable function
|
|
38
55
|
*/
|
|
39
|
-
function hasEvaluateOutput(svc) {
|
|
56
|
+
export function hasEvaluateOutput(svc) {
|
|
40
57
|
return typeof svc.evaluateOutput === 'function';
|
|
41
58
|
}
|
|
42
59
|
/**
|
|
@@ -70,48 +87,9 @@ function hasEvaluateOutput(svc) {
|
|
|
70
87
|
* ```
|
|
71
88
|
*/
|
|
72
89
|
export async function evaluateInputGuardrails(service, input, context) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
? [service]
|
|
77
|
-
: [];
|
|
78
|
-
if (services.length === 0) {
|
|
79
|
-
return { sanitizedInput: input, evaluations: [] };
|
|
80
|
-
}
|
|
81
|
-
let sanitizedInput = input;
|
|
82
|
-
const evaluations = [];
|
|
83
|
-
for (const currentService of services) {
|
|
84
|
-
if (!currentService?.evaluateInput) {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
let evaluation = null;
|
|
88
|
-
try {
|
|
89
|
-
evaluation = await currentService.evaluateInput({ context, input: sanitizedInput });
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
console.warn('[AgentOS][Guardrails] evaluateInput failed.', error);
|
|
93
|
-
continue;
|
|
94
|
-
}
|
|
95
|
-
if (!evaluation) {
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
evaluations.push(evaluation);
|
|
99
|
-
if (evaluation.action === GuardrailAction.SANITIZE && evaluation.modifiedText !== undefined) {
|
|
100
|
-
sanitizedInput = {
|
|
101
|
-
...sanitizedInput,
|
|
102
|
-
textInput: evaluation.modifiedText,
|
|
103
|
-
};
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
if (evaluation.action === GuardrailAction.BLOCK) {
|
|
107
|
-
return { sanitizedInput, evaluation, evaluations };
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return {
|
|
111
|
-
sanitizedInput,
|
|
112
|
-
evaluation: evaluations.at(-1) ?? null,
|
|
113
|
-
evaluations,
|
|
114
|
-
};
|
|
90
|
+
// Delegate to the two-phase parallel dispatcher.
|
|
91
|
+
// normalizeServices handles single / array / undefined normalization.
|
|
92
|
+
return ParallelGuardrailDispatcher.evaluateInput(normalizeServices(service), input, context);
|
|
115
93
|
}
|
|
116
94
|
/**
|
|
117
95
|
* Create a stream that emits a single error chunk for blocked content.
|
|
@@ -195,115 +173,21 @@ export async function* createGuardrailBlockedStream(context, evaluation, options
|
|
|
195
173
|
* ```
|
|
196
174
|
*/
|
|
197
175
|
export async function* wrapOutputGuardrails(service, context, stream, options) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
? [service]
|
|
202
|
-
: [];
|
|
203
|
-
// Separate guardrails by evaluation mode
|
|
204
|
-
const streamingGuardrails = services.filter((svc) => svc.config?.evaluateStreamingChunks === true && hasEvaluateOutput(svc));
|
|
205
|
-
const _finalOnlyGuardrails = services.filter((svc) => svc.config?.evaluateStreamingChunks !== true && typeof svc.evaluateOutput === 'function');
|
|
206
|
-
const guardrailEnabled = services.some((svc) => typeof svc.evaluateOutput === 'function');
|
|
207
|
-
const serializedInputEvaluations = (options.inputEvaluations ?? []).map(serializeEvaluation);
|
|
208
|
-
let inputMetadataApplied = serializedInputEvaluations.length === 0;
|
|
209
|
-
// Track streaming evaluations for rate limiting
|
|
210
|
-
const streamingEvaluationCounts = new Map();
|
|
211
|
-
for await (const chunk of stream) {
|
|
212
|
-
let currentChunk = chunk;
|
|
213
|
-
if (!inputMetadataApplied && serializedInputEvaluations.length > 0) {
|
|
214
|
-
currentChunk = withGuardrailMetadata(currentChunk, { input: serializedInputEvaluations });
|
|
215
|
-
inputMetadataApplied = true;
|
|
216
|
-
}
|
|
217
|
-
// Evaluate streaming chunks (TEXT_DELTA) if guardrails are configured for it
|
|
218
|
-
if (streamingGuardrails.length > 0 &&
|
|
219
|
-
chunk.type === AgentOSResponseChunkType.TEXT_DELTA &&
|
|
220
|
-
!chunk.isFinal) {
|
|
221
|
-
const outputEvaluations = [];
|
|
222
|
-
let workingChunk = currentChunk;
|
|
223
|
-
for (const svc of streamingGuardrails) {
|
|
224
|
-
const svcId = svc.id || 'unknown';
|
|
225
|
-
const currentCount = streamingEvaluationCounts.get(svcId) || 0;
|
|
226
|
-
const maxEvals = svc.config?.maxStreamingEvaluations;
|
|
227
|
-
// Skip if rate limit reached
|
|
228
|
-
if (maxEvals !== undefined && currentCount >= maxEvals) {
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
let evaluation = null;
|
|
232
|
-
try {
|
|
233
|
-
const evalRes = await svc.evaluateOutput({ context, chunk: workingChunk });
|
|
234
|
-
streamingEvaluationCounts.set(svcId, currentCount + 1);
|
|
235
|
-
evaluation = evalRes ?? null;
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
console.warn('[AgentOS][Guardrails] evaluateOutput (streaming) failed.', error);
|
|
239
|
-
}
|
|
240
|
-
if (!evaluation) {
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
outputEvaluations.push(evaluation);
|
|
244
|
-
if (evaluation.action === GuardrailAction.BLOCK) {
|
|
245
|
-
yield* createGuardrailBlockedStream(context, evaluation, options);
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
// For TEXT_DELTA chunks, sanitize modifies the textDelta field
|
|
249
|
-
if (evaluation.action === GuardrailAction.SANITIZE && evaluation.modifiedText !== undefined) {
|
|
250
|
-
workingChunk = {
|
|
251
|
-
...workingChunk,
|
|
252
|
-
textDelta: evaluation.modifiedText,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
if (outputEvaluations.length > 0) {
|
|
257
|
-
workingChunk = withGuardrailMetadata(workingChunk, {
|
|
258
|
-
output: outputEvaluations.map(serializeEvaluation),
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
currentChunk = workingChunk;
|
|
262
|
-
}
|
|
263
|
-
// Evaluate final chunks (all guardrails)
|
|
264
|
-
if (guardrailEnabled && chunk.isFinal) {
|
|
265
|
-
const outputEvaluations = [];
|
|
266
|
-
let workingChunk = currentChunk;
|
|
267
|
-
for (const svc of services) {
|
|
268
|
-
if (!svc?.evaluateOutput) {
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
let evaluation = null;
|
|
272
|
-
try {
|
|
273
|
-
evaluation = await svc.evaluateOutput({ context, chunk: workingChunk });
|
|
274
|
-
}
|
|
275
|
-
catch (error) {
|
|
276
|
-
console.warn('[AgentOS][Guardrails] evaluateOutput (final) failed.', error);
|
|
277
|
-
}
|
|
278
|
-
if (!evaluation) {
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
outputEvaluations.push(evaluation);
|
|
282
|
-
if (evaluation.action === GuardrailAction.BLOCK) {
|
|
283
|
-
yield* createGuardrailBlockedStream(context, evaluation, options);
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
if (evaluation.action === GuardrailAction.SANITIZE &&
|
|
287
|
-
workingChunk.type === AgentOSResponseChunkType.FINAL_RESPONSE) {
|
|
288
|
-
workingChunk = {
|
|
289
|
-
...workingChunk,
|
|
290
|
-
finalResponseText: evaluation.modifiedText !== undefined
|
|
291
|
-
? evaluation.modifiedText
|
|
292
|
-
: workingChunk.finalResponseText,
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
if (outputEvaluations.length > 0) {
|
|
297
|
-
workingChunk = withGuardrailMetadata(workingChunk, {
|
|
298
|
-
output: outputEvaluations.map(serializeEvaluation),
|
|
299
|
-
});
|
|
300
|
-
}
|
|
301
|
-
currentChunk = workingChunk;
|
|
302
|
-
}
|
|
303
|
-
yield currentChunk;
|
|
304
|
-
}
|
|
176
|
+
// Delegate to the two-phase parallel dispatcher.
|
|
177
|
+
// normalizeServices handles single / array / undefined normalization.
|
|
178
|
+
yield* ParallelGuardrailDispatcher.wrapOutput(normalizeServices(service), context, stream, options);
|
|
305
179
|
}
|
|
306
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Convert a full {@link GuardrailEvaluationResult} into the compact
|
|
182
|
+
* {@link GuardrailMetadataEntry} shape that gets embedded in chunk metadata.
|
|
183
|
+
*
|
|
184
|
+
* Strips heavy fields (`details`, `modifiedText`) that are not needed
|
|
185
|
+
* for downstream telemetry / observability.
|
|
186
|
+
*
|
|
187
|
+
* @param evaluation - The evaluation to serialize
|
|
188
|
+
* @returns A lightweight metadata entry suitable for chunk embedding
|
|
189
|
+
*/
|
|
190
|
+
export function serializeEvaluation(evaluation) {
|
|
307
191
|
return {
|
|
308
192
|
action: evaluation.action,
|
|
309
193
|
reason: evaluation.reason,
|
|
@@ -311,7 +195,18 @@ function serializeEvaluation(evaluation) {
|
|
|
311
195
|
metadata: evaluation.metadata,
|
|
312
196
|
};
|
|
313
197
|
}
|
|
314
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Attach guardrail evaluation metadata to a response chunk.
|
|
200
|
+
*
|
|
201
|
+
* Merges new input/output evaluation entries into any existing
|
|
202
|
+
* `metadata.guardrail` structure on the chunk. The result is a
|
|
203
|
+
* shallow-cloned chunk — the original is never mutated.
|
|
204
|
+
*
|
|
205
|
+
* @param chunk - The response chunk to annotate
|
|
206
|
+
* @param entry - Input and/or output metadata entries to merge
|
|
207
|
+
* @returns A new chunk with guardrail metadata merged in
|
|
208
|
+
*/
|
|
209
|
+
export function withGuardrailMetadata(chunk, entry) {
|
|
315
210
|
const existingMetadata = chunk.metadata ?? {};
|
|
316
211
|
const existingGuardrail = existingMetadata.guardrail ?? {};
|
|
317
212
|
const existingInput = Array.isArray(existingGuardrail.input)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guardrailDispatcher.js","sourceRoot":"","sources":["../../../src/core/guardrails/guardrailDispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,OAAO,EAEL,wBAAwB,
|
|
1
|
+
{"version":3,"file":"guardrailDispatcher.js","sourceRoot":"","sources":["../../../src/core/guardrails/guardrailDispatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
*/
|
|
48
48
|
export { GuardrailAction, type GuardrailConfig, type GuardrailContext, type GuardrailEvaluationResult, type GuardrailInputPayload, type GuardrailOutputPayload, type IGuardrailService, } from './IGuardrailService';
|
|
49
49
|
export { createGuardrailBlockedStream, evaluateInputGuardrails, type GuardrailInputOutcome, type GuardrailOutputOptions, wrapOutputGuardrails, } from './guardrailDispatcher';
|
|
50
|
+
export { ParallelGuardrailDispatcher } from './ParallelGuardrailDispatcher';
|
|
50
51
|
export { type CrossAgentOutputPayload, type ICrossAgentGuardrailService, isCrossAgentGuardrail, shouldObserveAgent, } from './ICrossAgentGuardrailService';
|
|
51
52
|
export { type CrossAgentEvaluationResult, type CrossAgentGuardrailContext, evaluateCrossAgentGuardrails, filterCrossAgentGuardrails, wrapWithCrossAgentGuardrails, } from './crossAgentGuardrailDispatcher';
|
|
52
53
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/guardrails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EACL,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/guardrails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EACL,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAG5E,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAC"}
|
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
export { GuardrailAction, } from './IGuardrailService.js';
|
|
50
50
|
// Guardrail dispatcher functions
|
|
51
51
|
export { createGuardrailBlockedStream, evaluateInputGuardrails, wrapOutputGuardrails, } from './guardrailDispatcher.js';
|
|
52
|
+
// Two-phase parallel guardrail dispatcher
|
|
53
|
+
export { ParallelGuardrailDispatcher } from './ParallelGuardrailDispatcher.js';
|
|
52
54
|
// Cross-agent guardrail interface and types
|
|
53
55
|
export { isCrossAgentGuardrail, shouldObserveAgent, } from './ICrossAgentGuardrailService.js';
|
|
54
56
|
// Cross-agent guardrail dispatcher
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/guardrails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,qCAAqC;AACrC,OAAO,EACL,eAAe,GAOhB,MAAM,qBAAqB,CAAC;AAE7B,iCAAiC;AACjC,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EAGvB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,4CAA4C;AAC5C,OAAO,EAGL,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAEvC,mCAAmC;AACnC,OAAO,EAGL,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/guardrails/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,qCAAqC;AACrC,OAAO,EACL,eAAe,GAOhB,MAAM,qBAAqB,CAAC;AAE7B,iCAAiC;AACjC,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,EAGvB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAE/B,0CAA0C;AAC1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAE5E,4CAA4C;AAC5C,OAAO,EAGL,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AAEvC,mCAAmC;AACnC,OAAO,EAGL,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for the `core/utils` module.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all public utilities so consumers can import from the directory
|
|
5
|
+
* root:
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { clamp, tokenize, estimateTokens } from '../core/utils';
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* @module agentos/core/utils
|
|
11
|
+
*/
|
|
12
|
+
export * from './text-utils';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for the `core/utils` module.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all public utilities so consumers can import from the directory
|
|
5
|
+
* root:
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { clamp, tokenize, estimateTokens } from '../core/utils';
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* @module agentos/core/utils
|
|
11
|
+
*/
|
|
12
|
+
export * from './text-utils.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared text utility functions used across AgentOS modules.
|
|
3
|
+
*
|
|
4
|
+
* These utilities cover common text-processing operations: numeric clamping,
|
|
5
|
+
* safe JSON parsing (including markdown code-fence stripping), tokenisation,
|
|
6
|
+
* text normalisation, and a lightweight token-count estimator used wherever
|
|
7
|
+
* the exact subword count is not critical.
|
|
8
|
+
*
|
|
9
|
+
* All functions are pure (no side-effects) and operate synchronously so they
|
|
10
|
+
* can be called from any context — including hot paths and web workers.
|
|
11
|
+
*
|
|
12
|
+
* @module agentos/core/utils/text-utils
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Clamps a numeric `value` to the closed interval [`min`, `max`].
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* clamp(5, 0, 10); // → 5
|
|
20
|
+
* clamp(-3, 0, 10); // → 0
|
|
21
|
+
* clamp(15, 0, 10); // → 10
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param value - The number to clamp.
|
|
25
|
+
* @param min - The inclusive lower bound.
|
|
26
|
+
* @param max - The inclusive upper bound.
|
|
27
|
+
* @returns The clamped value, guaranteed to satisfy `min <= result <= max`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function clamp(value: number, min: number, max: number): number;
|
|
30
|
+
/**
|
|
31
|
+
* Safely parses a JSON string, stripping markdown code fences if present.
|
|
32
|
+
*
|
|
33
|
+
* LLMs frequently wrap JSON in triple-backtick blocks (e.g. ` ```json … ``` `
|
|
34
|
+
* or ` ``` … ``` `). This function strips those fences before attempting
|
|
35
|
+
* `JSON.parse`, so callers do not need to pre-process LLM output.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Plain JSON
|
|
40
|
+
* parseJsonResponse<{ ok: boolean }>('{"ok":true}'); // → { ok: true }
|
|
41
|
+
*
|
|
42
|
+
* // Markdown-fenced JSON
|
|
43
|
+
* parseJsonResponse('```json\n{"ok":true}\n```'); // → { ok: true }
|
|
44
|
+
*
|
|
45
|
+
* // Invalid input
|
|
46
|
+
* parseJsonResponse('not json'); // → null
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @typeParam T - Expected shape of the parsed value.
|
|
50
|
+
* @param response - Raw string that may contain JSON, optionally wrapped in
|
|
51
|
+
* markdown code fences.
|
|
52
|
+
* @returns The parsed value cast to `T`, or `null` if parsing fails for any
|
|
53
|
+
* reason (syntax error, empty input, etc.).
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseJsonResponse<T = unknown>(response: string): T | null;
|
|
56
|
+
/**
|
|
57
|
+
* Splits text into lowercase word tokens, stripping punctuation.
|
|
58
|
+
*
|
|
59
|
+
* This is an intentionally simple, dependency-free tokeniser suited for tasks
|
|
60
|
+
* like keyword matching, vocabulary analysis, and lightweight NLP pipelines.
|
|
61
|
+
* It is *not* a subword tokeniser and does not respect language-specific rules.
|
|
62
|
+
*
|
|
63
|
+
* Steps performed:
|
|
64
|
+
* 1. Convert to lowercase.
|
|
65
|
+
* 2. Replace non-alphanumeric characters (except spaces) with spaces.
|
|
66
|
+
* 3. Split on whitespace.
|
|
67
|
+
* 4. Drop empty strings that can arise from consecutive separators.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* tokenize('Hello, World!'); // → ['hello', 'world']
|
|
72
|
+
* tokenize('foo bar\tbaz'); // → ['foo', 'bar', 'baz']
|
|
73
|
+
* tokenize(''); // → []
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @param text - The string to tokenise.
|
|
77
|
+
* @returns An array of lowercase word tokens with punctuation removed.
|
|
78
|
+
*/
|
|
79
|
+
export declare function tokenize(text: string): string[];
|
|
80
|
+
/**
|
|
81
|
+
* Normalises text by lowercasing, stripping punctuation, and collapsing
|
|
82
|
+
* internal whitespace runs to a single space.
|
|
83
|
+
*
|
|
84
|
+
* This produces a canonical form useful for fuzzy comparisons, deduplication,
|
|
85
|
+
* and pre-processing before embedding or classification.
|
|
86
|
+
*
|
|
87
|
+
* Steps performed:
|
|
88
|
+
* 1. Convert to lowercase.
|
|
89
|
+
* 2. Replace non-alphanumeric characters (except spaces) with spaces.
|
|
90
|
+
* 3. Collapse consecutive whitespace to a single space.
|
|
91
|
+
* 4. Trim leading and trailing whitespace.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* normalizeText('Hello, World!'); // → 'hello world'
|
|
96
|
+
* normalizeText(' foo bar '); // → 'foo bar'
|
|
97
|
+
* normalizeText("it's a test!"); // → 'it s a test'
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @param text - The string to normalise.
|
|
101
|
+
* @returns A normalised string.
|
|
102
|
+
*/
|
|
103
|
+
export declare function normalizeText(text: string): string;
|
|
104
|
+
/**
|
|
105
|
+
* Estimates the number of LLM tokens in a string using the rough heuristic
|
|
106
|
+
* of **1 token ≈ 4 characters** (the widely-cited GPT-family average).
|
|
107
|
+
*
|
|
108
|
+
* This is intentionally approximate. It is suitable for budget checks,
|
|
109
|
+
* sliding-window sizing, and other cost-control logic where precision is not
|
|
110
|
+
* required. For exact subword counts, use the model's native tokeniser.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* estimateTokens('Hello!'); // → 2 (6 chars / 4 → ceil(1.5) = 2)
|
|
115
|
+
* estimateTokens(''); // → 0
|
|
116
|
+
* estimateTokens('a'.repeat(8)); // → 2
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @param text - The string whose token count should be estimated.
|
|
120
|
+
* @returns A non-negative integer estimate of the token count.
|
|
121
|
+
* Returns `0` for empty or non-string input.
|
|
122
|
+
*/
|
|
123
|
+
export declare function estimateTokens(text: string): number;
|
|
124
|
+
/**
|
|
125
|
+
* Computes the cosine similarity between two numeric vectors.
|
|
126
|
+
*
|
|
127
|
+
* Cosine similarity measures the cosine of the angle between two vectors in
|
|
128
|
+
* an inner-product space. It ranges from **-1.0** (perfectly opposite
|
|
129
|
+
* directions) to **1.0** (perfectly identical directions), with **0** meaning
|
|
130
|
+
* the vectors are orthogonal (no linear similarity).
|
|
131
|
+
*
|
|
132
|
+
* This single implementation consolidates 6+ duplicate `cosineSimilarity`
|
|
133
|
+
* helpers that previously existed across the AgentOS codebase (discovery,
|
|
134
|
+
* social-posting, rag, etc.), providing a single well-tested source of truth.
|
|
135
|
+
*
|
|
136
|
+
* ### Edge-case behaviour
|
|
137
|
+
* | Condition | Return value | Reason |
|
|
138
|
+
* |---|---|---|
|
|
139
|
+
* | Empty arrays | `0` | Division by zero is undefined; 0 is the safe neutral value. |
|
|
140
|
+
* | Mismatched dimensions | `0` | Meaningless to compare vectors in different spaces. |
|
|
141
|
+
* | Either vector is the zero vector | `0` | Magnitude is 0, denominator would be 0. |
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* // Identical unit vectors → 1
|
|
146
|
+
* cosineSimilarity([1, 0], [1, 0]); // → 1.0
|
|
147
|
+
*
|
|
148
|
+
* // Orthogonal vectors → 0
|
|
149
|
+
* cosineSimilarity([1, 0], [0, 1]); // → 0
|
|
150
|
+
*
|
|
151
|
+
* // Opposite unit vectors → -1
|
|
152
|
+
* cosineSimilarity([1, 0], [-1, 0]); // → -1.0
|
|
153
|
+
*
|
|
154
|
+
* // Non-unit but parallel vectors → 1
|
|
155
|
+
* cosineSimilarity([2, 4], [1, 2]); // → 1.0
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @param a - First numeric vector (any dimension ≥ 1).
|
|
159
|
+
* @param b - Second numeric vector — must have the same length as `a`.
|
|
160
|
+
* @returns Cosine similarity in the range `[-1, 1]`.
|
|
161
|
+
* Returns `0` for mismatched dimensions, empty arrays, or zero-magnitude vectors.
|
|
162
|
+
*/
|
|
163
|
+
export declare function cosineSimilarity(a: number[], b: number[]): number;
|
|
164
|
+
//# sourceMappingURL=text-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-utils.d.ts","sourceRoot":"","sources":["../../../src/core/utils/text-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAMrE;AAMD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAwBzE;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB/C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAclD;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKnD;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAqBjE"}
|