@handlebar/governance-schema 0.0.6-dev.4 → 0.0.6-dev.6
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.d.ts +2 -2
- package/dist/audit/run-metrics.d.ts +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +1 -14
- 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 +24 -0
- package/dist/rules/rule.d.ts +23 -0
- package/dist/rules/signals.d.ts +44 -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/audit/events.d.ts
CHANGED
|
@@ -192,7 +192,7 @@ export declare const ToolResultEventSchema: z.ZodObject<{
|
|
|
192
192
|
duration_ms: "duration_ms";
|
|
193
193
|
records_in: "records_in";
|
|
194
194
|
records_out: "records_out";
|
|
195
|
-
}
|
|
195
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
196
196
|
value: z.ZodNumber;
|
|
197
197
|
unit: z.ZodOptional<z.ZodString>;
|
|
198
198
|
}, z.core.$strip>>;
|
|
@@ -471,7 +471,7 @@ export declare const AuditEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
471
471
|
duration_ms: "duration_ms";
|
|
472
472
|
records_in: "records_in";
|
|
473
473
|
records_out: "records_out";
|
|
474
|
-
}
|
|
474
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
475
475
|
value: z.ZodNumber;
|
|
476
476
|
unit: z.ZodOptional<z.ZodString>;
|
|
477
477
|
}, z.core.$strip>>;
|
|
@@ -14,7 +14,7 @@ export declare const AgentMetrics: z.ZodObject<{
|
|
|
14
14
|
duration_ms: "duration_ms";
|
|
15
15
|
records_in: "records_in";
|
|
16
16
|
records_out: "records_out";
|
|
17
|
-
}
|
|
17
|
+
}> & z.core.$partial, z.ZodObject<{
|
|
18
18
|
value: z.ZodNumber;
|
|
19
19
|
unit: z.ZodOptional<z.ZodString>;
|
|
20
20
|
}, z.core.$strip>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,4 @@ export * from "./audit/events.llm";
|
|
|
4
4
|
export * from "./audit/run-metrics";
|
|
5
5
|
export * from "./audit/governance-actions";
|
|
6
6
|
export type { EndUserConfig, EndUserGroupConfig } from "./enduser.types";
|
|
7
|
-
export * from "./rules
|
|
8
|
-
export * from "./rules/condition.types";
|
|
9
|
-
export * from "./rules/rule.types";
|
|
7
|
+
export * from "./rules";
|
package/dist/index.js
CHANGED
|
@@ -12668,7 +12668,7 @@ var AgentMetricInfo = exports_external.object({
|
|
|
12668
12668
|
value: exports_external.number(),
|
|
12669
12669
|
unit: exports_external.string().min(1).max(64).optional()
|
|
12670
12670
|
});
|
|
12671
|
-
var InbuiltAgentMetrics = exports_external.
|
|
12671
|
+
var InbuiltAgentMetrics = exports_external.partialRecord(InbuiltAgentMetricKind, AgentMetricInfo);
|
|
12672
12672
|
var CustomAgentMetrics = exports_external.record(CustomAgentMetricKind, AgentMetricInfo);
|
|
12673
12673
|
var AgentMetrics = exports_external.object({
|
|
12674
12674
|
inbuilt: InbuiltAgentMetrics,
|
|
@@ -12778,24 +12778,11 @@ var AuditEventSchema = exports_external.discriminatedUnion("kind", [
|
|
|
12778
12778
|
ErrorEventSchema,
|
|
12779
12779
|
MessageEventSchema
|
|
12780
12780
|
]);
|
|
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
12781
|
export {
|
|
12793
12782
|
ToolResultEventSchema,
|
|
12794
12783
|
ToolDecisionEventSchema,
|
|
12795
12784
|
RunStartedEventSchema,
|
|
12796
12785
|
RunEndedEventSchema,
|
|
12797
|
-
RuleSchema,
|
|
12798
|
-
RuleConfigSchema,
|
|
12799
12786
|
MessageSchema,
|
|
12800
12787
|
MessageRoleSchema,
|
|
12801
12788
|
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 } 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,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 { 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,44 @@
|
|
|
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
|
+
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
|
+
};
|
|
44
|
+
export {};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
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
|
+
};
|
|
44
|
+
export {};
|
|
@@ -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
|
+
};
|