Parent directory

types.ts

2781 bytes
  1export const DECISION_CATEGORIES = [
  2  "read_only",
  3  "build_test",
  4  "git_local",
  5  "git_remote",
  6  "file_mutation",
  7  "system",
  8  "network",
  9  "uncertain",
 10  "dangerous",
 11  "config_allow",
 12  "web_read",
 13  "empty",
 14  "session_allow",
 15  "external_directory",
 16  "bash",
 17  "read",
 18  "write",
 19  "edit",
 20  "find",
 21  "grep",
 22  "ls",
 23  "webfetch",
 24] as const;
 25
 26export type DecisionCategory = (typeof DECISION_CATEGORIES)[number];
 27
 28const decisionCategorySet: ReadonlySet<string> = new Set(DECISION_CATEGORIES);
 29
 30export function isDecisionCategory(value: unknown): value is DecisionCategory {
 31  return typeof value === "string" && decisionCategorySet.has(value);
 32}
 33
 34export type Decision = {
 35  decision: "allow" | "deny" | "ask";
 36  reason: string;
 37  category: DecisionCategory;
 38};
 39
 40export type LLMEvaluationResult = {
 41  decision: Decision;
 42  source?: "llm" | "none";
 43  rawResponse?: string;
 44  error?: string;
 45};
 46
 47export type PolicyReviewer = {
 48  evaluate(request: PolicyRequest, context: PolicyContext): Promise<LLMEvaluationResult>;
 49};
 50
 51export type PiReasoningEffort = "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
 52
 53export type ClassifierReviewerConfig = {
 54  kind: "classifier";
 55  provider: string;
 56  model: string;
 57  askThreshold: number;
 58};
 59
 60export type ReviewerConfig =
 61  | ClassifierReviewerConfig
 62  | {
 63      kind: "none";
 64    }
 65  | {
 66      kind: "pi";
 67      provider: string;
 68      model: string;
 69      reasoningEffort?: PiReasoningEffort;
 70      promptCacheKey?: string;
 71    }
 72  | {
 73      kind: "llama.cpp";
 74      baseUrl: string;
 75      model: string;
 76      enableThinking: boolean;
 77    };
 78
 79export type CacheEntry = {
 80  key: string;
 81  toolName: string;
 82  decision: Decision;
 83  source: "llm";
 84  createdAt: string;
 85};
 86
 87export type DecisionCache = {
 88  lookup(key: string): Promise<Decision | undefined>;
 89  write(entry: CacheEntry): Promise<void>;
 90};
 91
 92export type DecisionSource = "session" | "static" | "deterministic" | "cache" | "llm" | "none";
 93
 94export type AuditEntry = {
 95  toolName: string;
 96  inputSummary: string;
 97  decision: Decision;
 98  source: DecisionSource;
 99  timingMs: number;
100  sessionId?: string;
101  rawResponse?: string;
102};
103
104export type DecisionAudit = {
105  record(entry: AuditEntry): Promise<void>;
106};
107
108export type PolicyEvaluation = {
109  decision: Decision;
110  source: DecisionSource;
111  rawResponse?: string;
112  error?: string;
113  approvalRequests?: PolicyRequest[];
114};
115
116export type PolicyRequest = {
117  toolName: string;
118  input: Record<string, unknown>;
119};
120
121export type PolicyContext = {
122  sessionId?: string;
123  cwd?: string;
124  signal?: AbortSignal;
125};
126
127export type PolicyPrecheck = {
128  source: Exclude<DecisionSource, "llm" | "cache" | "deterministic" | "none">;
129  decide(request: PolicyRequest, context: PolicyContext): Promise<Decision | undefined>;
130};