adonis-ai-kit 0.0.0-stage → 1.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.
- package/CHANGELOG.md +74 -0
- package/LICENSE +21 -0
- package/README.md +397 -2
- package/dist/commands/ai_test.d.ts +12 -0
- package/dist/commands/ai_test.d.ts.map +1 -0
- package/dist/commands/ai_test.js +98 -0
- package/dist/commands/ai_test.js.map +1 -0
- package/dist/commands/main.d.ts +14 -0
- package/dist/commands/main.d.ts.map +1 -0
- package/dist/commands/main.js +31 -0
- package/dist/commands/main.js.map +1 -0
- package/dist/commands/make_agent.d.ts +13 -0
- package/dist/commands/make_agent.d.ts.map +1 -0
- package/dist/commands/make_agent.js +116 -0
- package/dist/commands/make_agent.js.map +1 -0
- package/dist/providers/ai_provider.d.ts +23 -0
- package/dist/providers/ai_provider.d.ts.map +1 -0
- package/dist/providers/ai_provider.js +34 -0
- package/dist/providers/ai_provider.js.map +1 -0
- package/dist/services/main.d.ts +4 -0
- package/dist/services/main.d.ts.map +1 -0
- package/dist/services/main.js +7 -0
- package/dist/services/main.js.map +1 -0
- package/dist/src/acp/acp_agents.d.ts +89 -0
- package/dist/src/acp/acp_agents.d.ts.map +1 -0
- package/dist/src/acp/acp_agents.js +367 -0
- package/dist/src/acp/acp_agents.js.map +1 -0
- package/dist/src/acp/index.d.ts +4 -0
- package/dist/src/acp/index.d.ts.map +1 -0
- package/dist/src/acp/index.js +4 -0
- package/dist/src/acp/index.js.map +1 -0
- package/dist/src/acp/provider.d.ts +74 -0
- package/dist/src/acp/provider.d.ts.map +1 -0
- package/dist/src/acp/provider.js +276 -0
- package/dist/src/acp/provider.js.map +1 -0
- package/dist/src/acp/types.d.ts +128 -0
- package/dist/src/acp/types.d.ts.map +1 -0
- package/dist/src/acp/types.js +2 -0
- package/dist/src/acp/types.js.map +1 -0
- package/dist/src/agents/agent_runner.d.ts +60 -0
- package/dist/src/agents/agent_runner.d.ts.map +1 -0
- package/dist/src/agents/agent_runner.js +134 -0
- package/dist/src/agents/agent_runner.js.map +1 -0
- package/dist/src/agents/index.d.ts +4 -0
- package/dist/src/agents/index.d.ts.map +1 -0
- package/dist/src/agents/index.js +4 -0
- package/dist/src/agents/index.js.map +1 -0
- package/dist/src/agents/loader.d.ts +56 -0
- package/dist/src/agents/loader.d.ts.map +1 -0
- package/dist/src/agents/loader.js +184 -0
- package/dist/src/agents/loader.js.map +1 -0
- package/dist/src/agents/manifest.d.ts +61 -0
- package/dist/src/agents/manifest.d.ts.map +1 -0
- package/dist/src/agents/manifest.js +35 -0
- package/dist/src/agents/manifest.js.map +1 -0
- package/dist/src/ai_manager.d.ts +140 -0
- package/dist/src/ai_manager.d.ts.map +1 -0
- package/dist/src/ai_manager.js +814 -0
- package/dist/src/ai_manager.js.map +1 -0
- package/dist/src/budget/budget_allocator.d.ts +37 -0
- package/dist/src/budget/budget_allocator.d.ts.map +1 -0
- package/dist/src/budget/budget_allocator.js +98 -0
- package/dist/src/budget/budget_allocator.js.map +1 -0
- package/dist/src/budget/budget_enforcer.d.ts +70 -0
- package/dist/src/budget/budget_enforcer.d.ts.map +1 -0
- package/dist/src/budget/budget_enforcer.js +195 -0
- package/dist/src/budget/budget_enforcer.js.map +1 -0
- package/dist/src/budget/cost_tracker.d.ts +71 -0
- package/dist/src/budget/cost_tracker.d.ts.map +1 -0
- package/dist/src/budget/cost_tracker.js +199 -0
- package/dist/src/budget/cost_tracker.js.map +1 -0
- package/dist/src/budget/index.d.ts +6 -0
- package/dist/src/budget/index.d.ts.map +1 -0
- package/dist/src/budget/index.js +6 -0
- package/dist/src/budget/index.js.map +1 -0
- package/dist/src/budget/pricing.d.ts +35 -0
- package/dist/src/budget/pricing.d.ts.map +1 -0
- package/dist/src/budget/pricing.js +129 -0
- package/dist/src/budget/pricing.js.map +1 -0
- package/dist/src/budget/types.d.ts +86 -0
- package/dist/src/budget/types.d.ts.map +1 -0
- package/dist/src/budget/types.js +2 -0
- package/dist/src/budget/types.js.map +1 -0
- package/dist/src/catalog/index.d.ts +3 -0
- package/dist/src/catalog/index.d.ts.map +1 -0
- package/dist/src/catalog/index.js +3 -0
- package/dist/src/catalog/index.js.map +1 -0
- package/dist/src/catalog/models_dev.d.ts +87 -0
- package/dist/src/catalog/models_dev.d.ts.map +1 -0
- package/dist/src/catalog/models_dev.js +38 -0
- package/dist/src/catalog/models_dev.js.map +1 -0
- package/dist/src/catalog/source.d.ts +67 -0
- package/dist/src/catalog/source.d.ts.map +1 -0
- package/dist/src/catalog/source.js +678 -0
- package/dist/src/catalog/source.js.map +1 -0
- package/dist/src/circuit_breaker.d.ts +61 -0
- package/dist/src/circuit_breaker.d.ts.map +1 -0
- package/dist/src/circuit_breaker.js +217 -0
- package/dist/src/circuit_breaker.js.map +1 -0
- package/dist/src/define_config.d.ts +11 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +48 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/error_classifier.d.ts +50 -0
- package/dist/src/error_classifier.d.ts.map +1 -0
- package/dist/src/error_classifier.js +206 -0
- package/dist/src/error_classifier.js.map +1 -0
- package/dist/src/errors.d.ts +52 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +70 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/guard/confirmation.d.ts +67 -0
- package/dist/src/guard/confirmation.d.ts.map +1 -0
- package/dist/src/guard/confirmation.js +180 -0
- package/dist/src/guard/confirmation.js.map +1 -0
- package/dist/src/guard/errors.d.ts +10 -0
- package/dist/src/guard/errors.d.ts.map +1 -0
- package/dist/src/guard/errors.js +14 -0
- package/dist/src/guard/errors.js.map +1 -0
- package/dist/src/guard/guard.d.ts +47 -0
- package/dist/src/guard/guard.d.ts.map +1 -0
- package/dist/src/guard/guard.js +133 -0
- package/dist/src/guard/guard.js.map +1 -0
- package/dist/src/guard/index.d.ts +7 -0
- package/dist/src/guard/index.d.ts.map +1 -0
- package/dist/src/guard/index.js +7 -0
- package/dist/src/guard/index.js.map +1 -0
- package/dist/src/guard/registry.d.ts +72 -0
- package/dist/src/guard/registry.d.ts.map +1 -0
- package/dist/src/guard/registry.js +192 -0
- package/dist/src/guard/registry.js.map +1 -0
- package/dist/src/guard/schema_registry.d.ts +37 -0
- package/dist/src/guard/schema_registry.d.ts.map +1 -0
- package/dist/src/guard/schema_registry.js +57 -0
- package/dist/src/guard/schema_registry.js.map +1 -0
- package/dist/src/guard/types.d.ts +63 -0
- package/dist/src/guard/types.d.ts.map +1 -0
- package/dist/src/guard/types.js +2 -0
- package/dist/src/guard/types.js.map +1 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +14 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logger.d.ts +7 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +2 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/models/catalog_resolver.d.ts +24 -0
- package/dist/src/models/catalog_resolver.d.ts.map +1 -0
- package/dist/src/models/catalog_resolver.js +66 -0
- package/dist/src/models/catalog_resolver.js.map +1 -0
- package/dist/src/models/index.d.ts +14 -0
- package/dist/src/models/index.d.ts.map +1 -0
- package/dist/src/models/index.js +8 -0
- package/dist/src/models/index.js.map +1 -0
- package/dist/src/models/keys.d.ts +9 -0
- package/dist/src/models/keys.d.ts.map +1 -0
- package/dist/src/models/keys.js +12 -0
- package/dist/src/models/keys.js.map +1 -0
- package/dist/src/models/language_model_factory.d.ts +44 -0
- package/dist/src/models/language_model_factory.d.ts.map +1 -0
- package/dist/src/models/language_model_factory.js +193 -0
- package/dist/src/models/language_model_factory.js.map +1 -0
- package/dist/src/models/model_chain.d.ts +58 -0
- package/dist/src/models/model_chain.d.ts.map +1 -0
- package/dist/src/models/model_chain.js +144 -0
- package/dist/src/models/model_chain.js.map +1 -0
- package/dist/src/models/model_ref.d.ts +12 -0
- package/dist/src/models/model_ref.d.ts.map +1 -0
- package/dist/src/models/model_ref.js +33 -0
- package/dist/src/models/model_ref.js.map +1 -0
- package/dist/src/models/protocols.d.ts +6 -0
- package/dist/src/models/protocols.d.ts.map +1 -0
- package/dist/src/models/protocols.js +33 -0
- package/dist/src/models/protocols.js.map +1 -0
- package/dist/src/models/provider_factories.d.ts +19 -0
- package/dist/src/models/provider_factories.d.ts.map +1 -0
- package/dist/src/models/provider_factories.js +70 -0
- package/dist/src/models/provider_factories.js.map +1 -0
- package/dist/src/models/types.d.ts +17 -0
- package/dist/src/models/types.d.ts.map +1 -0
- package/dist/src/models/types.js +2 -0
- package/dist/src/models/types.js.map +1 -0
- package/dist/src/response_macro.d.ts +16 -0
- package/dist/src/response_macro.d.ts.map +1 -0
- package/dist/src/response_macro.js +151 -0
- package/dist/src/response_macro.js.map +1 -0
- package/dist/src/types.d.ts +340 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/usage.d.ts +13 -0
- package/dist/src/usage.d.ts.map +1 -0
- package/dist/src/usage.js +61 -0
- package/dist/src/usage.js.map +1 -0
- package/package.json +208 -4
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ActionGuard, ExecutionReconciliation } from './types.js';
|
|
2
|
+
export interface ParameterRule<T = unknown> {
|
|
3
|
+
field: string;
|
|
4
|
+
validate: (value: T, allArgs: Record<string, unknown>) => string | null;
|
|
5
|
+
}
|
|
6
|
+
export interface PolicyGuardOptions {
|
|
7
|
+
maxCalls?: number;
|
|
8
|
+
allowedTools?: string[];
|
|
9
|
+
rules?: Record<string, ParameterRule[]>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Flexible policy guard for constraining tool arguments and invocation counts.
|
|
13
|
+
*
|
|
14
|
+
* `check()` reserves a call slot when it allows a call, so parallel tool calls cannot all pass
|
|
15
|
+
* the `maxCalls` check before any of them is recorded. The slot is turned into a counted call by
|
|
16
|
+
* `record()`, or given back by `release()`.
|
|
17
|
+
*/
|
|
18
|
+
export declare class PolicyGuard implements ActionGuard {
|
|
19
|
+
private callCount;
|
|
20
|
+
private successfulCalls;
|
|
21
|
+
private inFlight;
|
|
22
|
+
private maxCalls;
|
|
23
|
+
private allowedTools?;
|
|
24
|
+
private rules;
|
|
25
|
+
constructor(opts?: PolicyGuardOptions);
|
|
26
|
+
addRule(toolName: string, rule: ParameterRule): this;
|
|
27
|
+
check(toolName: string, args: unknown): string | null;
|
|
28
|
+
record(_toolName: string, result: unknown): void;
|
|
29
|
+
release(_toolName: string): void;
|
|
30
|
+
get totalCalls(): number;
|
|
31
|
+
get acceptedCalls(): number;
|
|
32
|
+
summary(): Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Reconciles the number of claims made by an LLM with the verified executions in the guard.
|
|
36
|
+
*/
|
|
37
|
+
export declare function reconcileExecutionClaims(claimedCount: unknown, guard?: ActionGuard): ExecutionReconciliation;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a numeric range validation rule.
|
|
40
|
+
* Only real numbers (or numeric strings) pass: `''`, `null`, booleans and arrays are rejected.
|
|
41
|
+
*/
|
|
42
|
+
export declare function rangeRule(field: string, min: number, max: number, label?: string): ParameterRule<unknown>;
|
|
43
|
+
/**
|
|
44
|
+
* Creates an allowed values enum validation rule.
|
|
45
|
+
*/
|
|
46
|
+
export declare function enumRule<T extends string>(field: string, allowed: readonly T[], label?: string): ParameterRule<unknown>;
|
|
47
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/guard/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAEtE,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,IAAI,CAAA;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAA;CACxC;AAED;;;;;;GAMG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,YAAY,CAAC,CAAa;IAClC,OAAO,CAAC,KAAK,CAA0C;gBAE3C,IAAI,GAAE,kBAAuB;IAYzC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAOpD,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IA4BrD,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAehD,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIhC,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAOnC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,OAAO,EACrB,KAAK,CAAC,EAAE,WAAW,GAClB,uBAAuB,CAWzB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAAc,GACpB,aAAa,CAAC,OAAO,CAAC,CAgBxB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,SAAS,CAAC,EAAE,EACrB,KAAK,GAAE,MAAc,GACpB,aAAa,CAAC,OAAO,CAAC,CAUxB"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flexible policy guard for constraining tool arguments and invocation counts.
|
|
3
|
+
*
|
|
4
|
+
* `check()` reserves a call slot when it allows a call, so parallel tool calls cannot all pass
|
|
5
|
+
* the `maxCalls` check before any of them is recorded. The slot is turned into a counted call by
|
|
6
|
+
* `record()`, or given back by `release()`.
|
|
7
|
+
*/
|
|
8
|
+
export class PolicyGuard {
|
|
9
|
+
callCount = 0;
|
|
10
|
+
successfulCalls = 0;
|
|
11
|
+
inFlight = 0;
|
|
12
|
+
maxCalls;
|
|
13
|
+
allowedTools;
|
|
14
|
+
rules = new Map();
|
|
15
|
+
constructor(opts = {}) {
|
|
16
|
+
this.maxCalls = opts.maxCalls ?? Infinity;
|
|
17
|
+
if (opts.allowedTools) {
|
|
18
|
+
this.allowedTools = new Set(opts.allowedTools);
|
|
19
|
+
}
|
|
20
|
+
if (opts.rules) {
|
|
21
|
+
for (const [tool, rules] of Object.entries(opts.rules)) {
|
|
22
|
+
this.rules.set(tool, [...rules]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
addRule(toolName, rule) {
|
|
27
|
+
const existing = this.rules.get(toolName) ?? [];
|
|
28
|
+
existing.push(rule);
|
|
29
|
+
this.rules.set(toolName, existing);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
check(toolName, args) {
|
|
33
|
+
if (this.allowedTools && !this.allowedTools.has(toolName)) {
|
|
34
|
+
return `Tool "${toolName}" is not permitted by policy`;
|
|
35
|
+
}
|
|
36
|
+
if (this.callCount + this.inFlight >= this.maxCalls) {
|
|
37
|
+
return `Maximum allowed calls (${this.maxCalls}) exceeded for policy`;
|
|
38
|
+
}
|
|
39
|
+
const toolRules = this.rules.get(toolName);
|
|
40
|
+
if (toolRules && toolRules.length > 0) {
|
|
41
|
+
// Fail-closed: rules cannot be evaluated against non-object arguments.
|
|
42
|
+
if (typeof args !== 'object' || args === null || Array.isArray(args)) {
|
|
43
|
+
return `Arguments for "${toolName}" must be an object to be validated by policy`;
|
|
44
|
+
}
|
|
45
|
+
const record = args;
|
|
46
|
+
for (const rule of toolRules) {
|
|
47
|
+
const violation = rule.validate(record[rule.field], record);
|
|
48
|
+
if (violation) {
|
|
49
|
+
return violation;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
this.inFlight += 1;
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
record(_toolName, result) {
|
|
57
|
+
this.inFlight = Math.max(0, this.inFlight - 1);
|
|
58
|
+
this.callCount += 1;
|
|
59
|
+
if (result &&
|
|
60
|
+
typeof result === 'object' &&
|
|
61
|
+
'error' in result &&
|
|
62
|
+
result.error) {
|
|
63
|
+
// Failed call
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.successfulCalls += 1;
|
|
67
|
+
}
|
|
68
|
+
release(_toolName) {
|
|
69
|
+
this.inFlight = Math.max(0, this.inFlight - 1);
|
|
70
|
+
}
|
|
71
|
+
get totalCalls() {
|
|
72
|
+
return this.callCount;
|
|
73
|
+
}
|
|
74
|
+
get acceptedCalls() {
|
|
75
|
+
return this.successfulCalls;
|
|
76
|
+
}
|
|
77
|
+
summary() {
|
|
78
|
+
return {
|
|
79
|
+
totalCalls: this.callCount,
|
|
80
|
+
acceptedCalls: this.successfulCalls,
|
|
81
|
+
maxCalls: this.maxCalls,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Reconciles the number of claims made by an LLM with the verified executions in the guard.
|
|
87
|
+
*/
|
|
88
|
+
export function reconcileExecutionClaims(claimedCount, guard) {
|
|
89
|
+
const parsed = Number(claimedCount ?? 0);
|
|
90
|
+
const claimed = Number.isFinite(parsed) ? parsed : 0;
|
|
91
|
+
const summary = guard?.summary?.();
|
|
92
|
+
const verified = typeof summary?.acceptedCalls === 'number' ? summary.acceptedCalls : 0;
|
|
93
|
+
return {
|
|
94
|
+
claimed,
|
|
95
|
+
verified,
|
|
96
|
+
mismatch: claimed !== verified,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates a numeric range validation rule.
|
|
101
|
+
* Only real numbers (or numeric strings) pass: `''`, `null`, booleans and arrays are rejected.
|
|
102
|
+
*/
|
|
103
|
+
export function rangeRule(field, min, max, label = field) {
|
|
104
|
+
return {
|
|
105
|
+
field,
|
|
106
|
+
validate: (val) => {
|
|
107
|
+
const isNumeric = typeof val === 'number' || (typeof val === 'string' && val.trim() !== '');
|
|
108
|
+
const num = isNumeric ? Number(val) : Number.NaN;
|
|
109
|
+
if (!Number.isFinite(num)) {
|
|
110
|
+
return `${label} must be a valid number`;
|
|
111
|
+
}
|
|
112
|
+
if (num < min || num > max) {
|
|
113
|
+
return `${label} ${num} is out of permitted range [${min}, ${max}]`;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Creates an allowed values enum validation rule.
|
|
121
|
+
*/
|
|
122
|
+
export function enumRule(field, allowed, label = field) {
|
|
123
|
+
return {
|
|
124
|
+
field,
|
|
125
|
+
validate: (val) => {
|
|
126
|
+
if (typeof val !== 'string' || !allowed.includes(val)) {
|
|
127
|
+
return `${label} "${String(val)}" is not allowed. Permitted: ${allowed.join(', ')}`;
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/guard/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/guard/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/guard/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ActionGuard, Logger, ToolDefinition, ToolPermission } from './types.js';
|
|
2
|
+
import type { ConfirmationService } from './confirmation.js';
|
|
3
|
+
export interface ToolAccessOptions {
|
|
4
|
+
guard?: ActionGuard;
|
|
5
|
+
confirmation?: ConfirmationService;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
/** Agent whose permission matrix applies in `getToolsByList()`. */
|
|
9
|
+
agentName?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Per-call permission map. When given, it is the only source of permissions for this call:
|
|
12
|
+
* tools missing from it get the registry's `defaultPermission`. The agent matrix is neither
|
|
13
|
+
* read nor modified, so nothing leaks into later calls.
|
|
14
|
+
*/
|
|
15
|
+
permissions?: Record<string, ToolPermission>;
|
|
16
|
+
}
|
|
17
|
+
export interface WrapToolOptions extends ToolAccessOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Effective permission of the tool. `ask` requires a `confirmation` service (otherwise every
|
|
20
|
+
* call is refused with `PolicyViolationError`); `deny` refuses every call.
|
|
21
|
+
* Defaults to `allow` because `wrapTool()` is a low-level primitive; the registry's
|
|
22
|
+
* `getToolsForAgent()` / `getToolsByList()` always pass the resolved permission.
|
|
23
|
+
*/
|
|
24
|
+
permission?: ToolPermission;
|
|
25
|
+
}
|
|
26
|
+
export interface ToolRegistryOptions {
|
|
27
|
+
logger?: Logger;
|
|
28
|
+
askByDefault?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Permission of tools that have neither an agent-specific nor a tool-level permission.
|
|
31
|
+
* Default: `deny` (fail-closed).
|
|
32
|
+
*/
|
|
33
|
+
defaultPermission?: ToolPermission;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Registry for managing AI agent tools, access permissions, policy guards,
|
|
37
|
+
* and Human-in-the-loop confirmation hooks.
|
|
38
|
+
*
|
|
39
|
+
* Fail-closed: unknown permissions resolve to `deny`, `ask` without a confirmation service
|
|
40
|
+
* never executes, and every tool that is handed out goes through the policy guard.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ToolRegistry {
|
|
43
|
+
private tools;
|
|
44
|
+
private agentPermissions;
|
|
45
|
+
private defaultPermissions;
|
|
46
|
+
private askByDefault;
|
|
47
|
+
private defaultPermission;
|
|
48
|
+
private logger?;
|
|
49
|
+
constructor(opts?: ToolRegistryOptions);
|
|
50
|
+
setLogger(logger: Logger): void;
|
|
51
|
+
registerTool(name: string, tool: ToolDefinition, defaultPermission?: ToolPermission): this;
|
|
52
|
+
registerTools(tools: Record<string, ToolDefinition>, defaultPermission?: ToolPermission): this;
|
|
53
|
+
setAgentPermissions(agentName: string, permissions: Record<string, ToolPermission>): this;
|
|
54
|
+
getAgentPermission(agentName: string, toolName: string): ToolPermission;
|
|
55
|
+
/**
|
|
56
|
+
* Wraps a tool with policy guard validation and, for `ask`, Human-in-the-loop confirmation.
|
|
57
|
+
* Tools without an `execute` function (provider-executed / client-side tools) are returned as is.
|
|
58
|
+
*/
|
|
59
|
+
wrapTool(name: string, tool: ToolDefinition, options?: WrapToolOptions): ToolDefinition;
|
|
60
|
+
/**
|
|
61
|
+
* Returns the tools an agent may use. `deny` tools are omitted, `ask` tools require
|
|
62
|
+
* confirmation, and every returned tool is checked by `options.guard` when one is provided.
|
|
63
|
+
*/
|
|
64
|
+
getToolsForAgent(agentName: string, options?: ToolAccessOptions): Record<string, ToolDefinition>;
|
|
65
|
+
/**
|
|
66
|
+
* Returns the requested tools, subject to the permission matrix of `options.agentName`
|
|
67
|
+
* (or the tool-level / registry defaults when no agent is given).
|
|
68
|
+
*/
|
|
69
|
+
getToolsByList(toolNames: string[], options?: ToolAccessOptions): Record<string, ToolDefinition>;
|
|
70
|
+
private resolveTool;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/guard/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,MAAM,EACN,cAAc,EACd,cAAc,EACf,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAG5D,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CAC7C;AAED,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,cAAc,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,cAAc,CAAA;CACnC;AASD;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAyC;IACtD,OAAO,CAAC,gBAAgB,CAAsD;IAC9E,OAAO,CAAC,kBAAkB,CAAyC;IACnE,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,MAAM,CAAC,CAAQ;gBAEX,IAAI,GAAE,mBAAwB;IAM1C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,iBAAiB,CAAC,EAAE,cAAc,GAAG,IAAI;IAQ1F,aAAa,CACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,EACrC,iBAAiB,CAAC,EAAE,cAAc,GACjC,IAAI;IAOP,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI;IASzF,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc;IAcvE;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc;IA8F3F;;;OAGG;IACH,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAWjC;;;OAGG;IACH,cAAc,CACZ,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC;IAiBjC,OAAO,CAAC,WAAW;CA2BpB"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { PolicyViolationError } from './errors.js';
|
|
2
|
+
/** A tool description may be a function (AI SDK v7); fall back to the tool name then. */
|
|
3
|
+
function describeTool(tool, fallback) {
|
|
4
|
+
return typeof tool.description === 'string' && tool.description.length > 0
|
|
5
|
+
? tool.description
|
|
6
|
+
: fallback;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Registry for managing AI agent tools, access permissions, policy guards,
|
|
10
|
+
* and Human-in-the-loop confirmation hooks.
|
|
11
|
+
*
|
|
12
|
+
* Fail-closed: unknown permissions resolve to `deny`, `ask` without a confirmation service
|
|
13
|
+
* never executes, and every tool that is handed out goes through the policy guard.
|
|
14
|
+
*/
|
|
15
|
+
export class ToolRegistry {
|
|
16
|
+
tools = new Map();
|
|
17
|
+
agentPermissions = new Map();
|
|
18
|
+
defaultPermissions = new Map();
|
|
19
|
+
askByDefault;
|
|
20
|
+
defaultPermission;
|
|
21
|
+
logger;
|
|
22
|
+
constructor(opts = {}) {
|
|
23
|
+
this.logger = opts.logger;
|
|
24
|
+
this.askByDefault = new Set(opts.askByDefault ?? []);
|
|
25
|
+
this.defaultPermission = opts.defaultPermission ?? 'deny';
|
|
26
|
+
}
|
|
27
|
+
setLogger(logger) {
|
|
28
|
+
this.logger = logger;
|
|
29
|
+
}
|
|
30
|
+
registerTool(name, tool, defaultPermission) {
|
|
31
|
+
this.tools.set(name, tool);
|
|
32
|
+
if (defaultPermission) {
|
|
33
|
+
this.defaultPermissions.set(name, defaultPermission);
|
|
34
|
+
}
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
registerTools(tools, defaultPermission) {
|
|
38
|
+
for (const [name, tool] of Object.entries(tools)) {
|
|
39
|
+
this.registerTool(name, tool, defaultPermission);
|
|
40
|
+
}
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
setAgentPermissions(agentName, permissions) {
|
|
44
|
+
const map = this.agentPermissions.get(agentName) ?? new Map();
|
|
45
|
+
for (const [tool, perm] of Object.entries(permissions)) {
|
|
46
|
+
map.set(tool, perm);
|
|
47
|
+
}
|
|
48
|
+
this.agentPermissions.set(agentName, map);
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
getAgentPermission(agentName, toolName) {
|
|
52
|
+
const agentMap = this.agentPermissions.get(agentName);
|
|
53
|
+
if (agentMap?.has(toolName)) {
|
|
54
|
+
return agentMap.get(toolName);
|
|
55
|
+
}
|
|
56
|
+
if (this.defaultPermissions.has(toolName)) {
|
|
57
|
+
return this.defaultPermissions.get(toolName);
|
|
58
|
+
}
|
|
59
|
+
if (this.askByDefault.has(toolName)) {
|
|
60
|
+
return 'ask';
|
|
61
|
+
}
|
|
62
|
+
return this.defaultPermission;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Wraps a tool with policy guard validation and, for `ask`, Human-in-the-loop confirmation.
|
|
66
|
+
* Tools without an `execute` function (provider-executed / client-side tools) are returned as is.
|
|
67
|
+
*/
|
|
68
|
+
wrapTool(name, tool, options = {}) {
|
|
69
|
+
const originalExecute = tool.execute?.bind(tool);
|
|
70
|
+
if (!originalExecute) {
|
|
71
|
+
return tool;
|
|
72
|
+
}
|
|
73
|
+
const permission = options.permission ?? 'allow';
|
|
74
|
+
return {
|
|
75
|
+
...tool,
|
|
76
|
+
execute: async (args, execOptions) => {
|
|
77
|
+
// 0. Defense in depth: a denied tool never runs, even if it slipped past filtering.
|
|
78
|
+
if (permission === 'deny') {
|
|
79
|
+
throw new PolicyViolationError(name, 'permission is "deny"');
|
|
80
|
+
}
|
|
81
|
+
// 1. Guard check (also reserves a call slot in guards that support it)
|
|
82
|
+
if (options.guard) {
|
|
83
|
+
const violation = options.guard.check(name, args);
|
|
84
|
+
if (violation) {
|
|
85
|
+
this.logger?.warn?.(`[ToolRegistry] Tool "${name}" call rejected by guard: ${violation}`, args);
|
|
86
|
+
return {
|
|
87
|
+
error: `Rejected by policy guard: ${violation}. Adjust parameters to match approved bounds.`,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// From here on a call slot may be held in the guard: it must end in exactly one
|
|
92
|
+
// record() (tool ran) or release() (tool did not run).
|
|
93
|
+
let executed = false;
|
|
94
|
+
let slotSettled = false;
|
|
95
|
+
const settleSlot = (result) => {
|
|
96
|
+
if (slotSettled)
|
|
97
|
+
return;
|
|
98
|
+
slotSettled = true;
|
|
99
|
+
options.guard?.record?.(name, result);
|
|
100
|
+
};
|
|
101
|
+
try {
|
|
102
|
+
// 2. Human-in-the-loop confirmation. Fail-closed: `ask` without a service never runs.
|
|
103
|
+
if (permission === 'ask') {
|
|
104
|
+
if (!options.confirmation) {
|
|
105
|
+
throw new PolicyViolationError(name, 'permission is "ask" but no ConfirmationService was provided');
|
|
106
|
+
}
|
|
107
|
+
this.logger?.info?.(`[ToolRegistry] Requesting confirmation for "${name}"`);
|
|
108
|
+
const confirmation = await options.confirmation.waitForResponse({
|
|
109
|
+
sessionId: options.sessionId,
|
|
110
|
+
toolName: name,
|
|
111
|
+
action: describeTool(tool, name),
|
|
112
|
+
params: args ?? {},
|
|
113
|
+
}, options.timeoutMs, execOptions?.abortSignal);
|
|
114
|
+
if (confirmation.status !== 'approved') {
|
|
115
|
+
this.logger?.warn?.(`[ToolRegistry] Tool "${name}" execution not approved: ${confirmation.status} (${confirmation.reason ?? 'no reason'})`);
|
|
116
|
+
return {
|
|
117
|
+
error: `Tool "${name}" was not executed: ${confirmation.status}. ${confirmation.reason ?? ''}`.trim(),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// 3. Execute underlying tool
|
|
122
|
+
executed = true;
|
|
123
|
+
const result = await originalExecute(args, execOptions);
|
|
124
|
+
// 4. Record execution stats in guard
|
|
125
|
+
settleSlot(result);
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
if (executed) {
|
|
130
|
+
settleSlot({ error: err instanceof Error ? err.message : String(err) });
|
|
131
|
+
}
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
if (!slotSettled && options.guard) {
|
|
136
|
+
slotSettled = true;
|
|
137
|
+
options.guard.release?.(name);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns the tools an agent may use. `deny` tools are omitted, `ask` tools require
|
|
145
|
+
* confirmation, and every returned tool is checked by `options.guard` when one is provided.
|
|
146
|
+
*/
|
|
147
|
+
getToolsForAgent(agentName, options = {}) {
|
|
148
|
+
const result = {};
|
|
149
|
+
for (const [name, tool] of this.tools.entries()) {
|
|
150
|
+
const wrapped = this.resolveTool(agentName, name, tool, options);
|
|
151
|
+
if (wrapped)
|
|
152
|
+
result[name] = wrapped;
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Returns the requested tools, subject to the permission matrix of `options.agentName`
|
|
158
|
+
* (or the tool-level / registry defaults when no agent is given).
|
|
159
|
+
*/
|
|
160
|
+
getToolsByList(toolNames, options = {}) {
|
|
161
|
+
const result = {};
|
|
162
|
+
for (const name of toolNames) {
|
|
163
|
+
const tool = this.tools.get(name);
|
|
164
|
+
if (!tool) {
|
|
165
|
+
this.logger?.warn?.(`[ToolRegistry] Unknown tool requested: "${name}"`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const wrapped = this.resolveTool(options.agentName ?? '', name, tool, options);
|
|
169
|
+
if (wrapped)
|
|
170
|
+
result[name] = wrapped;
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
173
|
+
}
|
|
174
|
+
resolveTool(agentName, name, tool, options) {
|
|
175
|
+
const permission = options.permissions
|
|
176
|
+
? Object.hasOwn(options.permissions, name)
|
|
177
|
+
? options.permissions[name]
|
|
178
|
+
: this.defaultPermission
|
|
179
|
+
: this.getAgentPermission(agentName, name);
|
|
180
|
+
if (permission === 'deny') {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
if (permission === 'ask' && !options.confirmation) {
|
|
184
|
+
this.logger?.warn?.(`[ToolRegistry] Tool "${name}" requires confirmation but no ConfirmationService was provided; calls will be refused.`);
|
|
185
|
+
}
|
|
186
|
+
if (permission === 'allow' && !options.guard) {
|
|
187
|
+
return tool;
|
|
188
|
+
}
|
|
189
|
+
return this.wrapTool(name, tool, { ...options, permission });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/guard/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structural view of a Zod issue.
|
|
4
|
+
* Declared locally so the package works unchanged with Zod 3.24+ (`ZodIssue`) and Zod 4
|
|
5
|
+
* (`$ZodIssue`, where `ZodIssue` is deprecated).
|
|
6
|
+
*/
|
|
7
|
+
export interface SchemaIssue {
|
|
8
|
+
code?: string;
|
|
9
|
+
message: string;
|
|
10
|
+
path: ReadonlyArray<PropertyKey>;
|
|
11
|
+
}
|
|
12
|
+
export interface ValidationSuccess<T> {
|
|
13
|
+
success: true;
|
|
14
|
+
data: T;
|
|
15
|
+
}
|
|
16
|
+
export interface ValidationFailure {
|
|
17
|
+
success: false;
|
|
18
|
+
error: string;
|
|
19
|
+
issues: SchemaIssue[];
|
|
20
|
+
}
|
|
21
|
+
export type ValidationResult<T> = ValidationSuccess<T> | ValidationFailure;
|
|
22
|
+
/**
|
|
23
|
+
* Registry for structured agent outputs and input schemas using Zod.
|
|
24
|
+
*/
|
|
25
|
+
export declare class SchemaRegistry {
|
|
26
|
+
private schemas;
|
|
27
|
+
register(name: string, schema: z.ZodTypeAny): this;
|
|
28
|
+
registerMany(schemas: Record<string, z.ZodTypeAny>): this;
|
|
29
|
+
get(name: string): z.ZodTypeAny | undefined;
|
|
30
|
+
validate<T = unknown>(schemaName: string, data: unknown): ValidationResult<T>;
|
|
31
|
+
/**
|
|
32
|
+
* Formats Zod validation issues into actionable prompt text for LLM self-correction.
|
|
33
|
+
*/
|
|
34
|
+
formatZodIssues(issues: ReadonlyArray<SchemaIssue>): string;
|
|
35
|
+
getAllNames(): string[];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=schema_registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema_registry.d.ts","sourceRoot":"","sources":["../../../src/guard/schema_registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,CAAC,CAAA;CACR;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,WAAW,EAAE,CAAA;CACtB;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAA;AAE1E;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAkC;IAEjD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,UAAU,GAAG,IAAI;IAKlD,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI;IAOzD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,GAAG,SAAS;IAI3C,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAAC,CAAC,CAAC;IA0B7E;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,MAAM;IAS3D,WAAW,IAAI,MAAM,EAAE;CAGxB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry for structured agent outputs and input schemas using Zod.
|
|
3
|
+
*/
|
|
4
|
+
export class SchemaRegistry {
|
|
5
|
+
schemas = new Map();
|
|
6
|
+
register(name, schema) {
|
|
7
|
+
this.schemas.set(name, schema);
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
registerMany(schemas) {
|
|
11
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
12
|
+
this.schemas.set(name, schema);
|
|
13
|
+
}
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
get(name) {
|
|
17
|
+
return this.schemas.get(name);
|
|
18
|
+
}
|
|
19
|
+
validate(schemaName, data) {
|
|
20
|
+
const schema = this.get(schemaName);
|
|
21
|
+
if (!schema) {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
error: `Schema "${schemaName}" is not registered in SchemaRegistry`,
|
|
25
|
+
issues: [],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const parsed = schema.safeParse(data);
|
|
29
|
+
if (parsed.success) {
|
|
30
|
+
return {
|
|
31
|
+
success: true,
|
|
32
|
+
data: parsed.data,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const issues = parsed.error.issues;
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: this.formatZodIssues(issues),
|
|
39
|
+
issues,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Formats Zod validation issues into actionable prompt text for LLM self-correction.
|
|
44
|
+
*/
|
|
45
|
+
formatZodIssues(issues) {
|
|
46
|
+
return issues
|
|
47
|
+
.map((issue) => {
|
|
48
|
+
const path = issue.path.length > 0 ? issue.path.map(String).join('.') : 'root';
|
|
49
|
+
return `- Field "${path}": ${issue.message}`;
|
|
50
|
+
})
|
|
51
|
+
.join('\n');
|
|
52
|
+
}
|
|
53
|
+
getAllNames() {
|
|
54
|
+
return Array.from(this.schemas.keys());
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=schema_registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema_registry.js","sourceRoot":"","sources":["../../../src/guard/schema_registry.ts"],"names":[],"mappings":"AA0BA;;GAEG;AACH,MAAM,OAAO,cAAc;IACjB,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAA;IAEjD,QAAQ,CAAC,IAAY,EAAE,MAAoB;QACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,YAAY,CAAC,OAAqC;QAChD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAChC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC/B,CAAC;IAED,QAAQ,CAAc,UAAkB,EAAE,IAAa;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,WAAW,UAAU,uCAAuC;gBACnE,MAAM,EAAE,EAAE;aACX,CAAA;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,MAAM,CAAC,IAAS;aACvB,CAAA;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAuB,CAAA;QACnD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YACnC,MAAM;SACP,CAAA;IACH,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,MAAkC;QAChD,OAAO,MAAM;aACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;YAC9E,OAAO,YAAY,IAAI,MAAM,KAAK,CAAC,OAAO,EAAE,CAAA;QAC9C,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAA;IACf,CAAC;IAED,WAAW;QACT,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;CACF"}
|