@handlebar/governance-schema 0.0.6-dev.5 → 0.0.6-dev.7
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/dist/audit/events.base.d.ts +1 -5
- package/dist/audit/events.d.ts +29 -194
- package/dist/audit/events.llm.d.ts +7 -11
- package/dist/audit/events.tools.d.ts +162 -0
- package/dist/audit/governance-actions.d.ts +22 -0
- package/dist/audit/index.d.ts +2 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.js +70 -64
- package/dist/rules/common.d.ts +10 -0
- package/dist/rules/condition.d.ts +19 -0
- package/dist/rules/custom.d.ts +11 -0
- package/dist/rules/effects.d.ts +18 -0
- package/dist/rules/enduser.d.ts +21 -0
- package/dist/rules/index.d.ts +10 -0
- package/dist/rules/metrics.d.ts +26 -0
- package/dist/rules/rule.d.ts +23 -0
- package/dist/rules/signals.d.ts +43 -0
- package/dist/rules/time.d.ts +28 -0
- package/dist/rules/tools.d.ts +64 -0
- package/dist/rules/v2/common.d.ts +10 -0
- package/dist/rules/v2/condition.d.ts +19 -0
- package/dist/rules/v2/custom.d.ts +11 -0
- package/dist/rules/v2/effects.d.ts +18 -0
- package/dist/rules/v2/enduser.d.ts +21 -0
- package/dist/rules/v2/index.d.ts +10 -0
- package/dist/rules/v2/logical_conditions.d.ts +13 -0
- package/dist/rules/v2/metrics.d.ts +24 -0
- package/dist/rules/v2/rule.d.ts +23 -0
- package/dist/rules/v2/signals.d.ts +44 -0
- package/dist/rules/v2/time.d.ts +28 -0
- package/dist/rules/v2/tools.d.ts +64 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8,7 +8,6 @@ var __export = (target, all) => {
|
|
|
8
8
|
set: (newValue) => all[name] = () => newValue
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
|
|
12
11
|
// node_modules/zod/v4/classic/external.js
|
|
13
12
|
var exports_external = {};
|
|
14
13
|
__export(exports_external, {
|
|
@@ -12574,6 +12573,9 @@ function date4(params) {
|
|
|
12574
12573
|
|
|
12575
12574
|
// node_modules/zod/v4/classic/external.js
|
|
12576
12575
|
config(en_default());
|
|
12576
|
+
// node_modules/zod/index.js
|
|
12577
|
+
var zod_default = exports_external;
|
|
12578
|
+
|
|
12577
12579
|
// src/enduser.types.ts
|
|
12578
12580
|
var EndUserConfigSchema = exports_external.object({
|
|
12579
12581
|
externalId: exports_external.string(),
|
|
@@ -12597,11 +12599,7 @@ var AuditEnvelopeSchema = exports_external.object({
|
|
|
12597
12599
|
runId: exports_external.string(),
|
|
12598
12600
|
stepIndex: exports_external.number().min(0).optional(),
|
|
12599
12601
|
decisionId: exports_external.string().optional(),
|
|
12600
|
-
|
|
12601
|
-
userId: exports_external.string().optional(),
|
|
12602
|
-
userCategory: exports_external.string().optional(),
|
|
12603
|
-
sessionId: exports_external.string().optional()
|
|
12604
|
-
}).optional(),
|
|
12602
|
+
enduserExternalId: exports_external.string().optional(),
|
|
12605
12603
|
otel: exports_external.object({
|
|
12606
12604
|
traceId: exports_external.string().optional(),
|
|
12607
12605
|
spanId: exports_external.string().optional()
|
|
@@ -12649,6 +12647,14 @@ var MessageEventSchema = AuditEnvelopeSchema.extend({
|
|
|
12649
12647
|
});
|
|
12650
12648
|
|
|
12651
12649
|
// src/audit/governance-actions.ts
|
|
12650
|
+
var SignalSchema = exports_external.object({
|
|
12651
|
+
key: exports_external.string().max(256),
|
|
12652
|
+
args: exports_external.array(exports_external.string().max(256)).max(100).optional(),
|
|
12653
|
+
result: exports_external.union([
|
|
12654
|
+
exports_external.object({ ok: exports_external.literal(false), error: exports_external.string().optional() }),
|
|
12655
|
+
exports_external.object({ ok: exports_external.literal(true), value: exports_external.string().max(256) })
|
|
12656
|
+
])
|
|
12657
|
+
});
|
|
12652
12658
|
var AppliedActionSchema = exports_external.object({
|
|
12653
12659
|
type: exports_external.custom(),
|
|
12654
12660
|
ruleId: exports_external.string()
|
|
@@ -12658,7 +12664,8 @@ var GovernanceDecisionSchema = exports_external.object({
|
|
|
12658
12664
|
code: exports_external.custom(),
|
|
12659
12665
|
matchedRuleIds: exports_external.array(exports_external.string()),
|
|
12660
12666
|
appliedActions: exports_external.array(AppliedActionSchema),
|
|
12661
|
-
reason: exports_external.optional(exports_external.string())
|
|
12667
|
+
reason: exports_external.optional(exports_external.string()),
|
|
12668
|
+
signals: exports_external.array(SignalSchema).max(100).optional()
|
|
12662
12669
|
});
|
|
12663
12670
|
|
|
12664
12671
|
// src/audit/run-metrics.ts
|
|
@@ -12675,13 +12682,61 @@ var AgentMetrics = exports_external.object({
|
|
|
12675
12682
|
custom: CustomAgentMetrics
|
|
12676
12683
|
});
|
|
12677
12684
|
|
|
12678
|
-
// src/audit/events.ts
|
|
12679
|
-
var CountersSchema =
|
|
12680
|
-
var ToolMetaSchema =
|
|
12681
|
-
redacted:
|
|
12682
|
-
redactedFields:
|
|
12683
|
-
sizeBytesApprox:
|
|
12685
|
+
// src/audit/events.tools.ts
|
|
12686
|
+
var CountersSchema = zod_default.record(zod_default.string(), zod_default.union([zod_default.string(), zod_default.number()]));
|
|
12687
|
+
var ToolMetaSchema = zod_default.object({
|
|
12688
|
+
redacted: zod_default.boolean(),
|
|
12689
|
+
redactedFields: zod_default.array(zod_default.string()).optional(),
|
|
12690
|
+
sizeBytesApprox: zod_default.number().min(0).optional()
|
|
12691
|
+
});
|
|
12692
|
+
var ToolIdentitySchema = zod_default.object({
|
|
12693
|
+
name: zod_default.string(),
|
|
12694
|
+
categories: zod_default.array(zod_default.string()).optional()
|
|
12695
|
+
});
|
|
12696
|
+
var ToolArgsSchema = zod_default.record(zod_default.string(), zod_default.unknown());
|
|
12697
|
+
var SubjectSchema = zod_default.object({
|
|
12698
|
+
subjectType: zod_default.string().max(256),
|
|
12699
|
+
role: zod_default.string().max(256).optional(),
|
|
12700
|
+
value: zod_default.string().max(256),
|
|
12701
|
+
idSystem: zod_default.string().max(256).optional()
|
|
12702
|
+
});
|
|
12703
|
+
var HitlMetaSchema = zod_default.object({
|
|
12704
|
+
hitlActionId: zod_default.string().optional(),
|
|
12705
|
+
fingerprint: zod_default.string().optional(),
|
|
12706
|
+
status: zod_default.enum(["none", "pending", "approved", "denied"]).optional()
|
|
12707
|
+
});
|
|
12708
|
+
var ToolDecisionEventSchema = AuditEnvelopeSchema.extend({
|
|
12709
|
+
kind: zod_default.literal("tool.decision"),
|
|
12710
|
+
data: GovernanceDecisionSchema.extend({
|
|
12711
|
+
tool: ToolIdentitySchema,
|
|
12712
|
+
args: ToolArgsSchema.optional(),
|
|
12713
|
+
argsMeta: ToolMetaSchema.optional(),
|
|
12714
|
+
hitl: HitlMetaSchema.optional(),
|
|
12715
|
+
subjects: zod_default.array(SubjectSchema).max(100).optional(),
|
|
12716
|
+
signals: zod_default.array(SignalSchema).max(100).optional(),
|
|
12717
|
+
counters: CountersSchema.optional(),
|
|
12718
|
+
latencyMs: zod_default.number().min(0).optional()
|
|
12719
|
+
})
|
|
12720
|
+
});
|
|
12721
|
+
var ToolResultEventSchema = AuditEnvelopeSchema.extend({
|
|
12722
|
+
kind: zod_default.literal("tool.result"),
|
|
12723
|
+
data: zod_default.object({
|
|
12724
|
+
tool: ToolIdentitySchema,
|
|
12725
|
+
hitl: HitlMetaSchema.optional(),
|
|
12726
|
+
outcome: zod_default.enum(["success", "error"]),
|
|
12727
|
+
durationMs: zod_default.number().min(0).optional(),
|
|
12728
|
+
counters: CountersSchema.optional(),
|
|
12729
|
+
metrics: AgentMetrics.optional(),
|
|
12730
|
+
error: zod_default.object({
|
|
12731
|
+
name: zod_default.string().optional(),
|
|
12732
|
+
message: zod_default.string().optional(),
|
|
12733
|
+
stack: zod_default.string().optional()
|
|
12734
|
+
}).optional(),
|
|
12735
|
+
resultMeta: ToolMetaSchema.optional()
|
|
12736
|
+
})
|
|
12684
12737
|
});
|
|
12738
|
+
|
|
12739
|
+
// src/audit/events.ts
|
|
12685
12740
|
var RunStartedEventSchema = AuditEnvelopeSchema.extend({
|
|
12686
12741
|
kind: exports_external.literal("run.started"),
|
|
12687
12742
|
data: exports_external.object({
|
|
@@ -12714,44 +12769,6 @@ var RunStartedEventSchema = AuditEnvelopeSchema.extend({
|
|
|
12714
12769
|
}).optional()
|
|
12715
12770
|
})
|
|
12716
12771
|
});
|
|
12717
|
-
var ToolIdentitySchema = exports_external.object({
|
|
12718
|
-
name: exports_external.string(),
|
|
12719
|
-
categories: exports_external.array(exports_external.string()).optional()
|
|
12720
|
-
});
|
|
12721
|
-
var ToolArgsSchema = exports_external.record(exports_external.string(), exports_external.unknown());
|
|
12722
|
-
var HitlMetaSchema = exports_external.object({
|
|
12723
|
-
hitlActionId: exports_external.string().optional(),
|
|
12724
|
-
fingerprint: exports_external.string().optional(),
|
|
12725
|
-
status: exports_external.enum(["none", "pending", "approved", "denied"]).optional()
|
|
12726
|
-
});
|
|
12727
|
-
var ToolDecisionEventSchema = AuditEnvelopeSchema.extend({
|
|
12728
|
-
kind: exports_external.literal("tool.decision"),
|
|
12729
|
-
data: GovernanceDecisionSchema.extend({
|
|
12730
|
-
tool: ToolIdentitySchema,
|
|
12731
|
-
args: ToolArgsSchema.optional(),
|
|
12732
|
-
argsMeta: ToolMetaSchema.optional(),
|
|
12733
|
-
hitl: HitlMetaSchema.optional(),
|
|
12734
|
-
counters: CountersSchema.optional(),
|
|
12735
|
-
latencyMs: exports_external.number().min(0).optional()
|
|
12736
|
-
})
|
|
12737
|
-
});
|
|
12738
|
-
var ToolResultEventSchema = AuditEnvelopeSchema.extend({
|
|
12739
|
-
kind: exports_external.literal("tool.result"),
|
|
12740
|
-
data: exports_external.object({
|
|
12741
|
-
tool: ToolIdentitySchema,
|
|
12742
|
-
hitl: HitlMetaSchema.optional(),
|
|
12743
|
-
outcome: exports_external.enum(["success", "error"]),
|
|
12744
|
-
durationMs: exports_external.number().min(0).optional(),
|
|
12745
|
-
counters: CountersSchema.optional(),
|
|
12746
|
-
metrics: AgentMetrics.optional(),
|
|
12747
|
-
error: exports_external.object({
|
|
12748
|
-
name: exports_external.string().optional(),
|
|
12749
|
-
message: exports_external.string().optional(),
|
|
12750
|
-
stack: exports_external.string().optional()
|
|
12751
|
-
}).optional(),
|
|
12752
|
-
resultMeta: ToolMetaSchema.optional()
|
|
12753
|
-
})
|
|
12754
|
-
});
|
|
12755
12772
|
var RunEndedEventSchema = AuditEnvelopeSchema.extend({
|
|
12756
12773
|
kind: exports_external.literal("run.ended"),
|
|
12757
12774
|
data: exports_external.object({
|
|
@@ -12778,24 +12795,13 @@ var AuditEventSchema = exports_external.discriminatedUnion("kind", [
|
|
|
12778
12795
|
ErrorEventSchema,
|
|
12779
12796
|
MessageEventSchema
|
|
12780
12797
|
]);
|
|
12781
|
-
// src/rules/rule.types.ts
|
|
12782
|
-
var RuleConfigSchema = exports_external.object({
|
|
12783
|
-
priority: exports_external.number().min(0),
|
|
12784
|
-
when: exports_external.custom(),
|
|
12785
|
-
condition: exports_external.custom(),
|
|
12786
|
-
actions: exports_external.array(exports_external.custom())
|
|
12787
|
-
});
|
|
12788
|
-
var RuleSchema = exports_external.object({
|
|
12789
|
-
id: exports_external.uuid({ version: "v7" }),
|
|
12790
|
-
policy_id: exports_external.uuid({ version: "v7" })
|
|
12791
|
-
}).and(RuleConfigSchema);
|
|
12792
12798
|
export {
|
|
12793
12799
|
ToolResultEventSchema,
|
|
12794
12800
|
ToolDecisionEventSchema,
|
|
12801
|
+
SubjectSchema,
|
|
12802
|
+
SignalSchema,
|
|
12795
12803
|
RunStartedEventSchema,
|
|
12796
12804
|
RunEndedEventSchema,
|
|
12797
|
-
RuleSchema,
|
|
12798
|
-
RuleConfigSchema,
|
|
12799
12805
|
MessageSchema,
|
|
12800
12806
|
MessageRoleSchema,
|
|
12801
12807
|
MessageKindSchema,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Case-insensitive glob pattern (e.g. "search-*", "*-prod", "exact-name")
|
|
3
|
+
*/
|
|
4
|
+
export type Glob = string;
|
|
5
|
+
/**
|
|
6
|
+
* JSON-safe value for condition parameters and custom function args.
|
|
7
|
+
*/
|
|
8
|
+
export type JSONValue = string | number | boolean | null | {
|
|
9
|
+
[k: string]: JSONValue;
|
|
10
|
+
} | JSONValue[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CustomFunctionCondition } from "./custom";
|
|
2
|
+
import type { MetricWindowCondition } from "./metrics";
|
|
3
|
+
import type { EndUserTagCondition } from "./enduser";
|
|
4
|
+
import type { RequireSubjectCondition, SignalCondition } from "./signals";
|
|
5
|
+
import type { TimeGateCondition, ExecutionTimeCondition } from "./time";
|
|
6
|
+
import type { MaxCallsCondition, SequenceCondition, ToolNameCondition, ToolTagCondition } from "./tools";
|
|
7
|
+
export type AndCondition = {
|
|
8
|
+
kind: "and";
|
|
9
|
+
all: RuleCondition[];
|
|
10
|
+
};
|
|
11
|
+
export type OrCondition = {
|
|
12
|
+
kind: "or";
|
|
13
|
+
any: RuleCondition[];
|
|
14
|
+
};
|
|
15
|
+
export type NotCondition = {
|
|
16
|
+
kind: "not";
|
|
17
|
+
not: RuleCondition;
|
|
18
|
+
};
|
|
19
|
+
export type RuleCondition = ToolNameCondition | ToolTagCondition | EndUserTagCondition | ExecutionTimeCondition | SequenceCondition | MaxCallsCondition | CustomFunctionCondition | MetricWindowCondition | TimeGateCondition | RequireSubjectCondition | SignalCondition | AndCondition | OrCondition | NotCondition;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSONValue } from "./common";
|
|
2
|
+
/**
|
|
3
|
+
* Delegate condition evaluation to a user-defined function.
|
|
4
|
+
* - `name` is resolved by the host SDK/application
|
|
5
|
+
* - `args` is an opaque, JSON-serializable payload consumed by user code
|
|
6
|
+
*/
|
|
7
|
+
export type CustomFunctionCondition = {
|
|
8
|
+
kind: "custom";
|
|
9
|
+
name: string;
|
|
10
|
+
args?: JSONValue;
|
|
11
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type RuleEffectKind = "allow" | "hitl" | "block";
|
|
2
|
+
/**
|
|
3
|
+
* Direct impact of a rule breach.
|
|
4
|
+
*
|
|
5
|
+
* RuleEffect has an immediate impact on the agent run/tool action.
|
|
6
|
+
* This is in contract to side effects (yet to be defined),
|
|
7
|
+
* which would include "log" or "modify context".
|
|
8
|
+
*/
|
|
9
|
+
export type RuleEffect = {
|
|
10
|
+
type: "allow";
|
|
11
|
+
reason?: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: "hitl";
|
|
14
|
+
reason?: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "block";
|
|
17
|
+
reason?: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Match on arbitrary tags assigned to the enduser.
|
|
3
|
+
* "enduser" in this context means the users of a Handlebar user.
|
|
4
|
+
* - has: existence AND truthiness of the tag. E.g. "has:tier" would be false if "tier=0", "tier=false", or no "tier" tag exists.
|
|
5
|
+
* - hasValue: tag exists and has an exact given value
|
|
6
|
+
*/
|
|
7
|
+
export type EndUserTagCondition = {
|
|
8
|
+
kind: "enduserTag";
|
|
9
|
+
op: "has";
|
|
10
|
+
tag: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "enduserTag";
|
|
13
|
+
op: "hasValue";
|
|
14
|
+
tag: string;
|
|
15
|
+
value: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "enduserTag";
|
|
18
|
+
op: "hasValueAny";
|
|
19
|
+
tag: string;
|
|
20
|
+
values: string[];
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { RuleCondition } from "./condition";
|
|
2
|
+
export type { RulePhase, RuleSelector, Rule } from "./rule";
|
|
3
|
+
export type { RuleEffect, RuleEffectKind } from "./effects";
|
|
4
|
+
export type { RequireSubjectCondition, SignalCondition, SignalBinding } from "./signals";
|
|
5
|
+
export type { TimeGateCondition, ExecutionTimeCondition, ExecutionTimeScope } from "./time";
|
|
6
|
+
export type { MetricWindowCondition } from "./metrics";
|
|
7
|
+
export type { CustomFunctionCondition } from "./custom";
|
|
8
|
+
export type { EndUserTagCondition } from "./enduser";
|
|
9
|
+
export type { MaxCallsCondition, MaxCallsSelector, SequenceCondition, ToolNameCondition, ToolTagCondition } from "./tools";
|
|
10
|
+
export type { Glob, JSONValue } from "./common";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { InbuiltAgentMetricKind } from "../audit/run-metrics";
|
|
3
|
+
import type { Glob } from "./common";
|
|
4
|
+
import type { RuleEffectKind } from "./effects";
|
|
5
|
+
type MetricRef = {
|
|
6
|
+
kind: "inbuilt";
|
|
7
|
+
key: z.infer<typeof InbuiltAgentMetricKind>;
|
|
8
|
+
} | {
|
|
9
|
+
kind: "custom";
|
|
10
|
+
key: string;
|
|
11
|
+
};
|
|
12
|
+
export type MetricWindowCondition = {
|
|
13
|
+
kind: "metricWindow";
|
|
14
|
+
scope: "agent" | "agent_user";
|
|
15
|
+
metric: MetricRef;
|
|
16
|
+
aggregate: "sum" | "avg" | "max" | "min" | "count";
|
|
17
|
+
windowSeconds: number;
|
|
18
|
+
filter?: {
|
|
19
|
+
toolName?: Glob | Glob[];
|
|
20
|
+
toolTag?: string | string[];
|
|
21
|
+
};
|
|
22
|
+
op: "gt" | "gte" | "lt" | "lte" | "eq" | "neq";
|
|
23
|
+
value: number;
|
|
24
|
+
onMissing?: RuleEffectKind;
|
|
25
|
+
};
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Glob } from "./common";
|
|
2
|
+
import type { RuleCondition } from "./condition";
|
|
3
|
+
import type { RuleEffectKind, RuleEffect } from "./effects";
|
|
4
|
+
export type RulePhase = "tool.before" | "tool.after";
|
|
5
|
+
export type RuleSelector = {
|
|
6
|
+
phase: RulePhase;
|
|
7
|
+
tool?: {
|
|
8
|
+
name?: Glob | Glob[];
|
|
9
|
+
tagsAll?: string[];
|
|
10
|
+
tagsAny?: string[];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export type Rule = {
|
|
14
|
+
id: string;
|
|
15
|
+
policyId: string;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
priority: number;
|
|
18
|
+
name: string;
|
|
19
|
+
selector: RuleSelector;
|
|
20
|
+
condition: RuleCondition;
|
|
21
|
+
effect: RuleEffect;
|
|
22
|
+
onMissing?: RuleEffectKind;
|
|
23
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { JSONValue } from "./common";
|
|
2
|
+
import type { RuleEffectKind } from "./effects";
|
|
3
|
+
/**
|
|
4
|
+
* Requires the existence of subject data at runtime.
|
|
5
|
+
*
|
|
6
|
+
* Handlebar is agnostic to the source of the data,
|
|
7
|
+
* so long as it is present in the engine runtime.
|
|
8
|
+
*/
|
|
9
|
+
export type RequireSubjectCondition = {
|
|
10
|
+
kind: "requireSubject";
|
|
11
|
+
subjectType: string;
|
|
12
|
+
idSystem?: string;
|
|
13
|
+
};
|
|
14
|
+
export type SignalBinding = {
|
|
15
|
+
from: "enduserId";
|
|
16
|
+
} | {
|
|
17
|
+
from: "enduserTag";
|
|
18
|
+
tag: string;
|
|
19
|
+
} | {
|
|
20
|
+
from: "toolName";
|
|
21
|
+
} | {
|
|
22
|
+
from: "toolTag";
|
|
23
|
+
tag: string;
|
|
24
|
+
} | {
|
|
25
|
+
from: "toolArg";
|
|
26
|
+
path: string;
|
|
27
|
+
} | {
|
|
28
|
+
from: "subject";
|
|
29
|
+
subjectType: string;
|
|
30
|
+
role?: string;
|
|
31
|
+
field?: "id" | "idSystem";
|
|
32
|
+
} | {
|
|
33
|
+
from: "const";
|
|
34
|
+
value: JSONValue;
|
|
35
|
+
};
|
|
36
|
+
export type SignalCondition = {
|
|
37
|
+
kind: "signal";
|
|
38
|
+
key: string;
|
|
39
|
+
args: Record<string, SignalBinding>;
|
|
40
|
+
op: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "nin";
|
|
41
|
+
value: JSONValue;
|
|
42
|
+
onMissing?: RuleEffectKind;
|
|
43
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type TimeGateCondition = {
|
|
2
|
+
kind: "timeGate";
|
|
3
|
+
timezone: {
|
|
4
|
+
source: "enduserTag";
|
|
5
|
+
tag: string;
|
|
6
|
+
fallback?: "org";
|
|
7
|
+
};
|
|
8
|
+
windows: Array<{
|
|
9
|
+
days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
|
|
10
|
+
start: string;
|
|
11
|
+
end: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Scope for execution time measurement.
|
|
16
|
+
* - "tool": the single tool call duration
|
|
17
|
+
* - "total": end-to-end agent run (from start to now)
|
|
18
|
+
*/
|
|
19
|
+
export type ExecutionTimeScope = "tool" | "total";
|
|
20
|
+
/**
|
|
21
|
+
* Match against execution time thresholds (milliseconds).
|
|
22
|
+
*/
|
|
23
|
+
export type ExecutionTimeCondition = {
|
|
24
|
+
kind: "executionTime";
|
|
25
|
+
scope: ExecutionTimeScope;
|
|
26
|
+
op: "gt" | "gte" | "lt" | "lte" | "eq" | "neq";
|
|
27
|
+
ms: number;
|
|
28
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Glob } from "./common";
|
|
2
|
+
/**
|
|
3
|
+
* Match on a tool's name.
|
|
4
|
+
* - glob comparator supports wildcard matching
|
|
5
|
+
* - in comparator permits list membership check
|
|
6
|
+
*/
|
|
7
|
+
export type ToolNameCondition = {
|
|
8
|
+
kind: "toolName";
|
|
9
|
+
op: "eq" | "neq" | "contains" | "startsWith" | "endsWith" | "glob";
|
|
10
|
+
value: string | Glob;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "toolName";
|
|
13
|
+
op: "in";
|
|
14
|
+
value: (string | Glob)[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Match on tool tags present on the tool.
|
|
18
|
+
* - has: single tag must be present
|
|
19
|
+
* - anyOf: at least one tag present
|
|
20
|
+
* - allOf: every provided tag must be present
|
|
21
|
+
*/
|
|
22
|
+
export type ToolTagCondition = {
|
|
23
|
+
kind: "toolTag";
|
|
24
|
+
op: "has";
|
|
25
|
+
tag: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: "toolTag";
|
|
28
|
+
op: "anyOf";
|
|
29
|
+
tags: string[];
|
|
30
|
+
} | {
|
|
31
|
+
kind: "toolTag";
|
|
32
|
+
op: "allOf";
|
|
33
|
+
tags: string[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Enforce sequencing constraints within the current run history.
|
|
37
|
+
* - mustHaveCalled: all listed tool name patterns must have been called earlier
|
|
38
|
+
* - mustNotHaveCalled: none of the listed patterns may have been called earlier
|
|
39
|
+
*/
|
|
40
|
+
export type SequenceCondition = {
|
|
41
|
+
kind: "sequence";
|
|
42
|
+
mustHaveCalled?: Glob[];
|
|
43
|
+
mustNotHaveCalled?: Glob[];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Select tools for counting within a run.
|
|
47
|
+
* - by toolName: count calls whose name matches any provided glob patterns
|
|
48
|
+
* - by toolTag: count calls whose tool includes any of the provided tags
|
|
49
|
+
*/
|
|
50
|
+
export type MaxCallsSelector = {
|
|
51
|
+
by: "toolName";
|
|
52
|
+
patterns: Glob[];
|
|
53
|
+
} | {
|
|
54
|
+
by: "toolTag";
|
|
55
|
+
tags: string[];
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Assert a maximum number of calls within a run for the selected tools (inclusive).
|
|
59
|
+
*/
|
|
60
|
+
export type MaxCallsCondition = {
|
|
61
|
+
kind: "maxCalls";
|
|
62
|
+
selector: MaxCallsSelector;
|
|
63
|
+
max: number;
|
|
64
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Case-insensitive glob pattern (e.g. "search-*", "*-prod", "exact-name")
|
|
3
|
+
*/
|
|
4
|
+
export type Glob = string;
|
|
5
|
+
/**
|
|
6
|
+
* JSON-safe value for condition parameters and custom function args.
|
|
7
|
+
*/
|
|
8
|
+
export type JSONValue = string | number | boolean | null | {
|
|
9
|
+
[k: string]: JSONValue;
|
|
10
|
+
} | JSONValue[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CustomFunctionCondition } from "./custom";
|
|
2
|
+
import type { MetricWindowCondition } from "./metrics";
|
|
3
|
+
import type { EndUserTagCondition } from "./enduser";
|
|
4
|
+
import type { RequireSubjectCondition, SignalCondition } from "./signals";
|
|
5
|
+
import type { TimeGateCondition, ExecutionTimeCondition } from "./time";
|
|
6
|
+
import type { MaxCallsCondition, SequenceCondition, ToolNameCondition, ToolTagCondition } from "./tools";
|
|
7
|
+
export type AndCondition = {
|
|
8
|
+
kind: "and";
|
|
9
|
+
all: RuleConditionV2[];
|
|
10
|
+
};
|
|
11
|
+
export type OrCondition = {
|
|
12
|
+
kind: "or";
|
|
13
|
+
any: RuleConditionV2[];
|
|
14
|
+
};
|
|
15
|
+
export type NotCondition = {
|
|
16
|
+
kind: "not";
|
|
17
|
+
not: RuleConditionV2;
|
|
18
|
+
};
|
|
19
|
+
export type RuleConditionV2 = ToolNameCondition | ToolTagCondition | EndUserTagCondition | ExecutionTimeCondition | SequenceCondition | MaxCallsCondition | CustomFunctionCondition | MetricWindowCondition | TimeGateCondition | RequireSubjectCondition | SignalCondition | AndCondition | OrCondition | NotCondition;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSONValue } from "./common";
|
|
2
|
+
/**
|
|
3
|
+
* Delegate condition evaluation to a user-defined function.
|
|
4
|
+
* - `name` is resolved by the host SDK/application
|
|
5
|
+
* - `args` is an opaque, JSON-serializable payload consumed by user code
|
|
6
|
+
*/
|
|
7
|
+
export type CustomFunctionCondition = {
|
|
8
|
+
kind: "custom";
|
|
9
|
+
name: string;
|
|
10
|
+
args?: JSONValue;
|
|
11
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type RuleEffectKind = "allow" | "hitl" | "block";
|
|
2
|
+
/**
|
|
3
|
+
* Direct impact of a rule breach.
|
|
4
|
+
*
|
|
5
|
+
* RuleEffect has an immediate impact on the agent run/tool action.
|
|
6
|
+
* This is in contract to side effects (yet to be defined),
|
|
7
|
+
* which would include "log" or "modify context".
|
|
8
|
+
*/
|
|
9
|
+
export type RuleEffectV2 = {
|
|
10
|
+
type: "allow";
|
|
11
|
+
reason?: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: "hitl";
|
|
14
|
+
reason?: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "block";
|
|
17
|
+
reason?: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Match on arbitrary tags assigned to the enduser.
|
|
3
|
+
* "enduser" in this context means the users of a Handlebar user.
|
|
4
|
+
* - has: existence AND truthiness of the tag. E.g. "has:tier" would be false if "tier=0", "tier=false", or no "tier" tag exists.
|
|
5
|
+
* - hasValue: tag exists and has an exact given value
|
|
6
|
+
*/
|
|
7
|
+
export type EndUserTagCondition = {
|
|
8
|
+
kind: "enduserTag";
|
|
9
|
+
op: "has";
|
|
10
|
+
tag: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "enduserTag";
|
|
13
|
+
op: "hasValue";
|
|
14
|
+
tag: string;
|
|
15
|
+
value: string;
|
|
16
|
+
} | {
|
|
17
|
+
kind: "enduserTag";
|
|
18
|
+
op: "hasValueAny";
|
|
19
|
+
tag: string;
|
|
20
|
+
values: string[];
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { RuleConditionV2 } from "./condition";
|
|
2
|
+
export type { RulePhase, RuleSelector, RuleV2 } from "./rule";
|
|
3
|
+
export type { RuleEffectV2, RuleEffectKind } from "./effects";
|
|
4
|
+
export type { RequireSubjectCondition, SignalCondition } from "./signals";
|
|
5
|
+
export type { TimeGateCondition, ExecutionTimeCondition, ExecutionTimeScope } from "./time";
|
|
6
|
+
export type { MetricWindowCondition } from "./metrics";
|
|
7
|
+
export type { CustomFunctionCondition } from "./custom";
|
|
8
|
+
export type { EndUserTagCondition } from "./enduser";
|
|
9
|
+
export type { MaxCallsCondition, MaxCallsSelector, SequenceCondition, ToolNameCondition, ToolTagCondition } from "./tools";
|
|
10
|
+
export type { Glob, JSONValue } from "./common";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RuleConditionV2 } from "./condition";
|
|
2
|
+
export type AndCondition = {
|
|
3
|
+
kind: "and";
|
|
4
|
+
all: RuleConditionV2[];
|
|
5
|
+
};
|
|
6
|
+
export type OrCondition = {
|
|
7
|
+
kind: "or";
|
|
8
|
+
any: RuleConditionV2[];
|
|
9
|
+
};
|
|
10
|
+
export type NotCondition = {
|
|
11
|
+
kind: "not";
|
|
12
|
+
not: RuleConditionV2;
|
|
13
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Glob } from "./common";
|
|
2
|
+
import type { RuleEffectKind } from "./effects";
|
|
3
|
+
type MetricRef = {
|
|
4
|
+
kind: "inbuilt";
|
|
5
|
+
key: "bytes_in" | "bytes_out" | "records_in" | "records_out" | "duration_ms";
|
|
6
|
+
} | {
|
|
7
|
+
kind: "custom";
|
|
8
|
+
key: string;
|
|
9
|
+
};
|
|
10
|
+
export type MetricWindowCondition = {
|
|
11
|
+
kind: "metricWindow";
|
|
12
|
+
scope: "agent" | "agent_user";
|
|
13
|
+
metric: MetricRef;
|
|
14
|
+
aggregate: "sum" | "avg" | "max" | "min" | "count";
|
|
15
|
+
windowSeconds: number;
|
|
16
|
+
filter?: {
|
|
17
|
+
toolName?: Glob | Glob[];
|
|
18
|
+
toolTag?: string | string[];
|
|
19
|
+
};
|
|
20
|
+
op: "gt" | "gte" | "lt" | "lte" | "eq" | "neq";
|
|
21
|
+
value: number;
|
|
22
|
+
onMissing?: RuleEffectKind;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Glob } from "./common";
|
|
2
|
+
import type { RuleConditionV2 } from "./condition";
|
|
3
|
+
import type { RuleEffectKind, RuleEffectV2 } from "./effects";
|
|
4
|
+
export type RulePhase = "tool.before" | "tool.after";
|
|
5
|
+
export type RuleSelector = {
|
|
6
|
+
phase: RulePhase;
|
|
7
|
+
tool?: {
|
|
8
|
+
name?: Glob | Glob[];
|
|
9
|
+
tagsAll?: string[];
|
|
10
|
+
tagsAny?: string[];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export type RuleV2 = {
|
|
14
|
+
id: string;
|
|
15
|
+
policyId: string;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
priority: number;
|
|
18
|
+
name: string;
|
|
19
|
+
selector: RuleSelector;
|
|
20
|
+
condition: RuleConditionV2;
|
|
21
|
+
effect: RuleEffectV2;
|
|
22
|
+
onMissing?: RuleEffectKind;
|
|
23
|
+
};
|