@oni.bot/core 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +308 -0
- package/dist/agents/context.d.ts +24 -0
- package/dist/agents/context.d.ts.map +1 -0
- package/dist/agents/context.js +93 -0
- package/dist/agents/context.js.map +1 -0
- package/dist/agents/define-agent.d.ts +10 -0
- package/dist/agents/define-agent.d.ts.map +1 -0
- package/dist/agents/define-agent.js +121 -0
- package/dist/agents/define-agent.js.map +1 -0
- package/dist/agents/functional-agent.d.ts +12 -0
- package/dist/agents/functional-agent.d.ts.map +1 -0
- package/dist/agents/functional-agent.js +115 -0
- package/dist/agents/functional-agent.js.map +1 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +7 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/types.d.ts +62 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +8 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/checkpoint.d.ts +27 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +91 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/checkpointers/index.d.ts +4 -0
- package/dist/checkpointers/index.d.ts.map +1 -0
- package/dist/checkpointers/index.js +5 -0
- package/dist/checkpointers/index.js.map +1 -0
- package/dist/checkpointers/namespaced.d.ts +12 -0
- package/dist/checkpointers/namespaced.d.ts.map +1 -0
- package/dist/checkpointers/namespaced.js +37 -0
- package/dist/checkpointers/namespaced.js.map +1 -0
- package/dist/checkpointers/postgres.d.ts +13 -0
- package/dist/checkpointers/postgres.d.ts.map +1 -0
- package/dist/checkpointers/postgres.js +100 -0
- package/dist/checkpointers/postgres.js.map +1 -0
- package/dist/checkpointers/sqlite.d.ts +14 -0
- package/dist/checkpointers/sqlite.d.ts.map +1 -0
- package/dist/checkpointers/sqlite.js +98 -0
- package/dist/checkpointers/sqlite.js.map +1 -0
- package/dist/context.d.ts +24 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +47 -0
- package/dist/context.js.map +1 -0
- package/dist/coordination/index.d.ts +3 -0
- package/dist/coordination/index.d.ts.map +1 -0
- package/dist/coordination/index.js +3 -0
- package/dist/coordination/index.js.map +1 -0
- package/dist/coordination/pubsub.d.ts +38 -0
- package/dist/coordination/pubsub.d.ts.map +1 -0
- package/dist/coordination/pubsub.js +73 -0
- package/dist/coordination/pubsub.js.map +1 -0
- package/dist/coordination/request-reply.d.ts +40 -0
- package/dist/coordination/request-reply.d.ts.map +1 -0
- package/dist/coordination/request-reply.js +77 -0
- package/dist/coordination/request-reply.js.map +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/events/bus.d.ts +13 -0
- package/dist/events/bus.d.ts.map +1 -0
- package/dist/events/bus.js +52 -0
- package/dist/events/bus.js.map +1 -0
- package/dist/events/index.d.ts +3 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +3 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +87 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +2 -0
- package/dist/events/types.js.map +1 -0
- package/dist/functional.d.ts +36 -0
- package/dist/functional.d.ts.map +1 -0
- package/dist/functional.js +103 -0
- package/dist/functional.js.map +1 -0
- package/dist/graph.d.ts +74 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +119 -0
- package/dist/graph.js.map +1 -0
- package/dist/guardrails/audit.d.ts +13 -0
- package/dist/guardrails/audit.d.ts.map +1 -0
- package/dist/guardrails/audit.js +31 -0
- package/dist/guardrails/audit.js.map +1 -0
- package/dist/guardrails/budget.d.ts +30 -0
- package/dist/guardrails/budget.d.ts.map +1 -0
- package/dist/guardrails/budget.js +154 -0
- package/dist/guardrails/budget.js.map +1 -0
- package/dist/guardrails/filters.d.ts +24 -0
- package/dist/guardrails/filters.d.ts.map +1 -0
- package/dist/guardrails/filters.js +87 -0
- package/dist/guardrails/filters.js.map +1 -0
- package/dist/guardrails/index.d.ts +8 -0
- package/dist/guardrails/index.d.ts.map +1 -0
- package/dist/guardrails/index.js +9 -0
- package/dist/guardrails/index.js.map +1 -0
- package/dist/guardrails/permissions.d.ts +9 -0
- package/dist/guardrails/permissions.d.ts.map +1 -0
- package/dist/guardrails/permissions.js +29 -0
- package/dist/guardrails/permissions.js.map +1 -0
- package/dist/guardrails/types.d.ts +30 -0
- package/dist/guardrails/types.d.ts.map +1 -0
- package/dist/guardrails/types.js +2 -0
- package/dist/guardrails/types.js.map +1 -0
- package/dist/hitl/index.d.ts +5 -0
- package/dist/hitl/index.d.ts.map +1 -0
- package/dist/hitl/index.js +3 -0
- package/dist/hitl/index.js.map +1 -0
- package/dist/hitl/interrupt.d.ts +81 -0
- package/dist/hitl/interrupt.d.ts.map +1 -0
- package/dist/hitl/interrupt.js +116 -0
- package/dist/hitl/interrupt.js.map +1 -0
- package/dist/hitl/resume.d.ts +33 -0
- package/dist/hitl/resume.d.ts.map +1 -0
- package/dist/hitl/resume.js +72 -0
- package/dist/hitl/resume.js.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/dist/injected.d.ts +26 -0
- package/dist/injected.d.ts.map +1 -0
- package/dist/injected.js +25 -0
- package/dist/injected.js.map +1 -0
- package/dist/inspect.d.ts +31 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +139 -0
- package/dist/inspect.js.map +1 -0
- package/dist/messages/index.d.ts +66 -0
- package/dist/messages/index.d.ts.map +1 -0
- package/dist/messages/index.js +123 -0
- package/dist/messages/index.js.map +1 -0
- package/dist/models/anthropic.d.ts +6 -0
- package/dist/models/anthropic.d.ts.map +1 -0
- package/dist/models/anthropic.js +317 -0
- package/dist/models/anthropic.js.map +1 -0
- package/dist/models/google.d.ts +3 -0
- package/dist/models/google.d.ts.map +1 -0
- package/dist/models/google.js +310 -0
- package/dist/models/google.js.map +1 -0
- package/dist/models/index.d.ts +6 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +5 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/ollama.d.ts +7 -0
- package/dist/models/ollama.d.ts.map +1 -0
- package/dist/models/ollama.js +205 -0
- package/dist/models/ollama.js.map +1 -0
- package/dist/models/openai.d.ts +3 -0
- package/dist/models/openai.d.ts.map +1 -0
- package/dist/models/openai.js +331 -0
- package/dist/models/openai.js.map +1 -0
- package/dist/models/types.d.ts +77 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +2 -0
- package/dist/models/types.js.map +1 -0
- package/dist/prebuilt/index.d.ts +5 -0
- package/dist/prebuilt/index.d.ts.map +1 -0
- package/dist/prebuilt/index.js +4 -0
- package/dist/prebuilt/index.js.map +1 -0
- package/dist/prebuilt/react-agent.d.ts +35 -0
- package/dist/prebuilt/react-agent.d.ts.map +1 -0
- package/dist/prebuilt/react-agent.js +55 -0
- package/dist/prebuilt/react-agent.js.map +1 -0
- package/dist/prebuilt/tool-node.d.ts +15 -0
- package/dist/prebuilt/tool-node.d.ts.map +1 -0
- package/dist/prebuilt/tool-node.js +61 -0
- package/dist/prebuilt/tool-node.js.map +1 -0
- package/dist/pregel.d.ts +48 -0
- package/dist/pregel.d.ts.map +1 -0
- package/dist/pregel.js +583 -0
- package/dist/pregel.js.map +1 -0
- package/dist/retry.d.ts +3 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +40 -0
- package/dist/retry.js.map +1 -0
- package/dist/store/index.d.ts +90 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +214 -0
- package/dist/store/index.js.map +1 -0
- package/dist/stream-events.d.ts +15 -0
- package/dist/stream-events.d.ts.map +1 -0
- package/dist/stream-events.js +53 -0
- package/dist/stream-events.js.map +1 -0
- package/dist/streaming.d.ts +56 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +143 -0
- package/dist/streaming.js.map +1 -0
- package/dist/swarm/graph.d.ts +184 -0
- package/dist/swarm/graph.d.ts.map +1 -0
- package/dist/swarm/graph.js +534 -0
- package/dist/swarm/graph.js.map +1 -0
- package/dist/swarm/index.d.ts +11 -0
- package/dist/swarm/index.d.ts.map +1 -0
- package/dist/swarm/index.js +10 -0
- package/dist/swarm/index.js.map +1 -0
- package/dist/swarm/mailbox.d.ts +12 -0
- package/dist/swarm/mailbox.d.ts.map +1 -0
- package/dist/swarm/mailbox.js +36 -0
- package/dist/swarm/mailbox.js.map +1 -0
- package/dist/swarm/pool.d.ts +27 -0
- package/dist/swarm/pool.d.ts.map +1 -0
- package/dist/swarm/pool.js +87 -0
- package/dist/swarm/pool.js.map +1 -0
- package/dist/swarm/registry.d.ts +37 -0
- package/dist/swarm/registry.d.ts.map +1 -0
- package/dist/swarm/registry.js +115 -0
- package/dist/swarm/registry.js.map +1 -0
- package/dist/swarm/supervisor.d.ts +18 -0
- package/dist/swarm/supervisor.d.ts.map +1 -0
- package/dist/swarm/supervisor.js +117 -0
- package/dist/swarm/supervisor.js.map +1 -0
- package/dist/swarm/types.d.ts +111 -0
- package/dist/swarm/types.d.ts.map +1 -0
- package/dist/swarm/types.js +16 -0
- package/dist/swarm/types.js.map +1 -0
- package/dist/tools/define.d.ts +14 -0
- package/dist/tools/define.d.ts.map +1 -0
- package/dist/tools/define.js +39 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/types.d.ts +23 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/types.d.ts +204 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +45 -0
- package/dist/types.js.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
export class BudgetExceededError extends Error {
|
|
2
|
+
kind;
|
|
3
|
+
current;
|
|
4
|
+
limit;
|
|
5
|
+
constructor(kind, current, limit) {
|
|
6
|
+
super(kind === "cost"
|
|
7
|
+
? `Budget exceeded: cost $${current.toFixed(4)} exceeds limit $${limit.toFixed(4)}`
|
|
8
|
+
: `Budget exceeded: ${current} tokens exceeds limit of ${limit} tokens (${kind})`);
|
|
9
|
+
this.kind = kind;
|
|
10
|
+
this.current = current;
|
|
11
|
+
this.limit = limit;
|
|
12
|
+
this.name = "BudgetExceededError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Default pricing per million tokens for common models */
|
|
16
|
+
export const DEFAULT_PRICING = {
|
|
17
|
+
"claude-opus-4-6": { input: 15.0, output: 75.0 },
|
|
18
|
+
"claude-sonnet-4-6": { input: 3.0, output: 15.0 },
|
|
19
|
+
"gpt-4o": { input: 2.5, output: 10.0 },
|
|
20
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6 },
|
|
21
|
+
"gemini-2.0-flash": { input: 0.1, output: 0.4 },
|
|
22
|
+
};
|
|
23
|
+
export class BudgetTracker {
|
|
24
|
+
agentTokens = new Map();
|
|
25
|
+
totalInput = 0;
|
|
26
|
+
totalOutput = 0;
|
|
27
|
+
totalCost = 0;
|
|
28
|
+
pricing;
|
|
29
|
+
config;
|
|
30
|
+
constructor(config, customPricing) {
|
|
31
|
+
this.config = config;
|
|
32
|
+
this.pricing = { ...DEFAULT_PRICING, ...customPricing };
|
|
33
|
+
}
|
|
34
|
+
record(agentName, modelId, usage) {
|
|
35
|
+
const entries = [];
|
|
36
|
+
// Update agent-level counters
|
|
37
|
+
const existing = this.agentTokens.get(agentName) ?? { input: 0, output: 0 };
|
|
38
|
+
existing.input += usage.inputTokens;
|
|
39
|
+
existing.output += usage.outputTokens;
|
|
40
|
+
this.agentTokens.set(agentName, existing);
|
|
41
|
+
// Update run-level counters
|
|
42
|
+
this.totalInput += usage.inputTokens;
|
|
43
|
+
this.totalOutput += usage.outputTokens;
|
|
44
|
+
// Calculate cost for this usage
|
|
45
|
+
const pricing = this.pricing[modelId];
|
|
46
|
+
if (pricing) {
|
|
47
|
+
const cost = (usage.inputTokens / 1_000_000) * pricing.input +
|
|
48
|
+
(usage.outputTokens / 1_000_000) * pricing.output;
|
|
49
|
+
this.totalCost += cost;
|
|
50
|
+
}
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
const agentTotal = existing.input + existing.output;
|
|
53
|
+
const runTotal = this.totalInput + this.totalOutput;
|
|
54
|
+
const mode = this.config.onBudgetExceeded ?? "error";
|
|
55
|
+
// Check per-agent limit
|
|
56
|
+
if (this.config.maxTokensPerAgent !== undefined) {
|
|
57
|
+
const limit = this.config.maxTokensPerAgent;
|
|
58
|
+
if (agentTotal > limit) {
|
|
59
|
+
if (mode === "error") {
|
|
60
|
+
throw new BudgetExceededError("agent", agentTotal, limit);
|
|
61
|
+
}
|
|
62
|
+
entries.push({
|
|
63
|
+
timestamp: now,
|
|
64
|
+
agent: agentName,
|
|
65
|
+
action: "budget.exceeded",
|
|
66
|
+
data: { kind: "agent", current: agentTotal, limit },
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (agentTotal >= limit * 0.8) {
|
|
70
|
+
entries.push({
|
|
71
|
+
timestamp: now,
|
|
72
|
+
agent: agentName,
|
|
73
|
+
action: "budget.warning",
|
|
74
|
+
data: { kind: "agent", current: agentTotal, limit, percent: Math.round((agentTotal / limit) * 100) },
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Check per-run token limit
|
|
79
|
+
if (this.config.maxTokensPerRun !== undefined) {
|
|
80
|
+
const limit = this.config.maxTokensPerRun;
|
|
81
|
+
if (runTotal > limit) {
|
|
82
|
+
if (mode === "error") {
|
|
83
|
+
throw new BudgetExceededError("run", runTotal, limit);
|
|
84
|
+
}
|
|
85
|
+
entries.push({
|
|
86
|
+
timestamp: now,
|
|
87
|
+
agent: agentName,
|
|
88
|
+
action: "budget.exceeded",
|
|
89
|
+
data: { kind: "run", current: runTotal, limit },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else if (runTotal >= limit * 0.8) {
|
|
93
|
+
entries.push({
|
|
94
|
+
timestamp: now,
|
|
95
|
+
agent: agentName,
|
|
96
|
+
action: "budget.warning",
|
|
97
|
+
data: { kind: "run", current: runTotal, limit, percent: Math.round((runTotal / limit) * 100) },
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Check cost limit
|
|
102
|
+
if (this.config.maxCostPerRun !== undefined) {
|
|
103
|
+
const limit = this.config.maxCostPerRun;
|
|
104
|
+
if (this.totalCost > limit) {
|
|
105
|
+
if (mode === "error") {
|
|
106
|
+
throw new BudgetExceededError("cost", this.totalCost, limit);
|
|
107
|
+
}
|
|
108
|
+
entries.push({
|
|
109
|
+
timestamp: now,
|
|
110
|
+
agent: agentName,
|
|
111
|
+
action: "budget.exceeded",
|
|
112
|
+
data: { kind: "cost", current: this.totalCost, limit },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else if (this.totalCost >= limit * 0.8) {
|
|
116
|
+
entries.push({
|
|
117
|
+
timestamp: now,
|
|
118
|
+
agent: agentName,
|
|
119
|
+
action: "budget.warning",
|
|
120
|
+
data: { kind: "cost", current: this.totalCost, limit, percent: Math.round((this.totalCost / limit) * 100) },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return entries;
|
|
125
|
+
}
|
|
126
|
+
getAgentTokens(name) {
|
|
127
|
+
const entry = this.agentTokens.get(name);
|
|
128
|
+
return entry ? entry.input + entry.output : 0;
|
|
129
|
+
}
|
|
130
|
+
getTotalTokens() {
|
|
131
|
+
return this.totalInput + this.totalOutput;
|
|
132
|
+
}
|
|
133
|
+
getTotalCost() {
|
|
134
|
+
return this.totalCost;
|
|
135
|
+
}
|
|
136
|
+
isOverBudget() {
|
|
137
|
+
const runTotal = this.totalInput + this.totalOutput;
|
|
138
|
+
if (this.config.maxTokensPerRun !== undefined && runTotal > this.config.maxTokensPerRun) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
if (this.config.maxCostPerRun !== undefined && this.totalCost > this.config.maxCostPerRun) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
if (this.config.maxTokensPerAgent !== undefined) {
|
|
145
|
+
for (const [, entry] of this.agentTokens) {
|
|
146
|
+
if (entry.input + entry.output > this.config.maxTokensPerAgent) {
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/guardrails/budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ContentFilter, ContentFilterResult } from "./types.js";
|
|
2
|
+
export interface PiiFilterOptions {
|
|
3
|
+
block: Array<"email" | "ssn" | "phone" | "creditCard">;
|
|
4
|
+
redact?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function piiFilter(options: PiiFilterOptions): ContentFilter;
|
|
7
|
+
export interface TopicFilterOptions {
|
|
8
|
+
blocked?: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function topicFilter(options: TopicFilterOptions): ContentFilter;
|
|
11
|
+
export interface CustomFilterOptions {
|
|
12
|
+
name: string;
|
|
13
|
+
check: (content: string) => ContentFilterResult;
|
|
14
|
+
apply: "input" | "output" | "both";
|
|
15
|
+
}
|
|
16
|
+
export declare function customFilter(options: CustomFilterOptions): ContentFilter;
|
|
17
|
+
export interface FilterPipelineResult {
|
|
18
|
+
passed: boolean;
|
|
19
|
+
content: string;
|
|
20
|
+
blockedBy?: string;
|
|
21
|
+
reason?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function runFilters(filters: ContentFilter[], content: string, direction: "input" | "output"): FilterPipelineResult;
|
|
24
|
+
//# sourceMappingURL=filters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filters.d.ts","sourceRoot":"","sources":["../../src/guardrails/filters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAkBrE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,OAAO,GAAG,YAAY,CAAC,CAAC;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CA2BlE;AAID,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAgBtE;AAID,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,mBAAmB,CAAC;IAChD,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACpC;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,aAAa,CAMxE;AAID,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,UAAU,CACxB,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,OAAO,GAAG,QAAQ,GAC5B,oBAAoB,CA2BtB"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// ── PII patterns ──────────────────────────────────────────────────
|
|
2
|
+
const PII_PATTERNS = {
|
|
3
|
+
email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,
|
|
4
|
+
ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
|
|
5
|
+
phone: /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g,
|
|
6
|
+
creditCard: /\b(?:\d{4}[-\s]?){3}\d{4}\b/g,
|
|
7
|
+
};
|
|
8
|
+
const REDACT_LABELS = {
|
|
9
|
+
email: "[EMAIL REDACTED]",
|
|
10
|
+
ssn: "[SSN REDACTED]",
|
|
11
|
+
phone: "[PHONE REDACTED]",
|
|
12
|
+
creditCard: "[CREDIT CARD REDACTED]",
|
|
13
|
+
};
|
|
14
|
+
export function piiFilter(options) {
|
|
15
|
+
const { block, redact = false } = options;
|
|
16
|
+
return {
|
|
17
|
+
name: "pii",
|
|
18
|
+
apply: "both",
|
|
19
|
+
check(content) {
|
|
20
|
+
for (const kind of block) {
|
|
21
|
+
const pattern = PII_PATTERNS[kind];
|
|
22
|
+
if (!pattern)
|
|
23
|
+
continue;
|
|
24
|
+
// Reset lastIndex for global regex
|
|
25
|
+
pattern.lastIndex = 0;
|
|
26
|
+
if (pattern.test(content)) {
|
|
27
|
+
if (redact) {
|
|
28
|
+
// Reset again for replace
|
|
29
|
+
pattern.lastIndex = 0;
|
|
30
|
+
const redacted = content.replace(pattern, REDACT_LABELS[kind]);
|
|
31
|
+
return { blocked: true, reason: `PII detected: ${kind}`, redacted };
|
|
32
|
+
}
|
|
33
|
+
return { blocked: true, reason: `PII detected: ${kind}` };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { blocked: false };
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function topicFilter(options) {
|
|
41
|
+
const blockedTopics = (options.blocked ?? []).map(t => t.toLowerCase());
|
|
42
|
+
return {
|
|
43
|
+
name: "topic",
|
|
44
|
+
apply: "both",
|
|
45
|
+
check(content) {
|
|
46
|
+
const lower = content.toLowerCase();
|
|
47
|
+
for (const topic of blockedTopics) {
|
|
48
|
+
if (lower.includes(topic)) {
|
|
49
|
+
return { blocked: true, reason: `Blocked topic: ${topic}` };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { blocked: false };
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function customFilter(options) {
|
|
57
|
+
return {
|
|
58
|
+
name: options.name,
|
|
59
|
+
apply: options.apply,
|
|
60
|
+
check: options.check,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function runFilters(filters, content, direction) {
|
|
64
|
+
let currentContent = content;
|
|
65
|
+
for (const filter of filters) {
|
|
66
|
+
// Skip filters that don't apply to this direction
|
|
67
|
+
if (filter.apply !== "both" && filter.apply !== direction) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const result = filter.check(currentContent);
|
|
71
|
+
if (result.blocked) {
|
|
72
|
+
if (result.redacted !== undefined) {
|
|
73
|
+
// Redaction mode — update content and continue
|
|
74
|
+
currentContent = result.redacted;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
passed: false,
|
|
79
|
+
content: currentContent,
|
|
80
|
+
blockedBy: filter.name,
|
|
81
|
+
reason: result.reason,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return { passed: true, content: currentContent };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filters.js","sourceRoot":"","sources":["../../src/guardrails/filters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { GuardrailsConfig, BudgetConfig, ContentFilter, ContentFilterResult, AuditEntry } from "./types.js";
|
|
2
|
+
export { ToolPermissionError, checkToolPermission, getPermittedTools } from "./permissions.js";
|
|
3
|
+
export { BudgetTracker, BudgetExceededError, DEFAULT_PRICING } from "./budget.js";
|
|
4
|
+
export type { ModelPricing } from "./budget.js";
|
|
5
|
+
export { piiFilter, topicFilter, customFilter, runFilters } from "./filters.js";
|
|
6
|
+
export type { PiiFilterOptions, TopicFilterOptions, CustomFilterOptions, FilterPipelineResult } from "./filters.js";
|
|
7
|
+
export { AuditLog } from "./audit.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guardrails/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGjH,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG/F,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClF,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChF,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGpH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Permissions
|
|
2
|
+
export { ToolPermissionError, checkToolPermission, getPermittedTools } from "./permissions.js";
|
|
3
|
+
// Budget
|
|
4
|
+
export { BudgetTracker, BudgetExceededError, DEFAULT_PRICING } from "./budget.js";
|
|
5
|
+
// Filters
|
|
6
|
+
export { piiFilter, topicFilter, customFilter, runFilters } from "./filters.js";
|
|
7
|
+
// Audit
|
|
8
|
+
export { AuditLog } from "./audit.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/guardrails/index.ts"],"names":[],"mappings":"AAGA,cAAc;AACd,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE/F,SAAS;AACT,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGlF,UAAU;AACV,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGhF,QAAQ;AACR,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ToolPermissions } from "../tools/types.js";
|
|
2
|
+
export declare class ToolPermissionError extends Error {
|
|
3
|
+
readonly agent: string;
|
|
4
|
+
readonly tool: string;
|
|
5
|
+
constructor(agent: string, tool: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function checkToolPermission(permissions: ToolPermissions, agentName: string, toolName: string): void;
|
|
8
|
+
export declare function getPermittedTools(permissions: ToolPermissions, agentName: string, allTools: string[]): string[];
|
|
9
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/guardrails/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,qBAAa,mBAAoB,SAAQ,KAAK;aAChB,KAAK,EAAE,MAAM;aAAkB,IAAI,EAAE,MAAM;gBAA3C,KAAK,EAAE,MAAM,EAAkB,IAAI,EAAE,MAAM;CAIxE;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM3G;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAK/G"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export class ToolPermissionError extends Error {
|
|
2
|
+
agent;
|
|
3
|
+
tool;
|
|
4
|
+
constructor(agent, tool) {
|
|
5
|
+
super(`Agent "${agent}" is not permitted to use tool "${tool}"`);
|
|
6
|
+
this.agent = agent;
|
|
7
|
+
this.tool = tool;
|
|
8
|
+
this.name = "ToolPermissionError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function checkToolPermission(permissions, agentName, toolName) {
|
|
12
|
+
const allowed = permissions[agentName];
|
|
13
|
+
if (allowed === undefined)
|
|
14
|
+
return;
|
|
15
|
+
if (allowed === "*")
|
|
16
|
+
return;
|
|
17
|
+
if (Array.isArray(allowed) && allowed.includes(toolName))
|
|
18
|
+
return;
|
|
19
|
+
throw new ToolPermissionError(agentName, toolName);
|
|
20
|
+
}
|
|
21
|
+
export function getPermittedTools(permissions, agentName, allTools) {
|
|
22
|
+
const allowed = permissions[agentName];
|
|
23
|
+
if (allowed === undefined)
|
|
24
|
+
return allTools;
|
|
25
|
+
if (allowed === "*")
|
|
26
|
+
return allTools;
|
|
27
|
+
return allowed.filter(t => allTools.includes(t));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/guardrails/permissions.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAChB;IAA+B;IAA3D,YAA4B,KAAa,EAAkB,IAAY;QACrE,KAAK,CAAC,UAAU,KAAK,mCAAmC,IAAI,GAAG,CAAC,CAAC;QADvC,UAAK,GAAL,KAAK,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAQ;QAErE,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,WAA4B,EAAE,SAAiB,EAAE,QAAgB;IACnG,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAClC,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO;IAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO;IACjE,MAAM,IAAI,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,WAA4B,EAAE,SAAiB,EAAE,QAAkB;IACnG,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC3C,IAAI,OAAO,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC;IACrC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ToolPermissions } from "../tools/types.js";
|
|
2
|
+
export interface BudgetConfig {
|
|
3
|
+
maxTokensPerAgent?: number;
|
|
4
|
+
maxTokensPerRun?: number;
|
|
5
|
+
maxCostPerRun?: number;
|
|
6
|
+
onBudgetExceeded?: "interrupt" | "error" | "warn";
|
|
7
|
+
}
|
|
8
|
+
export interface ContentFilterResult {
|
|
9
|
+
blocked: boolean;
|
|
10
|
+
reason?: string;
|
|
11
|
+
redacted?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ContentFilter {
|
|
14
|
+
name: string;
|
|
15
|
+
apply: "input" | "output" | "both";
|
|
16
|
+
check: (content: string) => ContentFilterResult;
|
|
17
|
+
}
|
|
18
|
+
export interface GuardrailsConfig {
|
|
19
|
+
toolPermissions?: ToolPermissions;
|
|
20
|
+
budget?: BudgetConfig;
|
|
21
|
+
filters?: ContentFilter[];
|
|
22
|
+
audit?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface AuditEntry {
|
|
25
|
+
timestamp: number;
|
|
26
|
+
agent: string;
|
|
27
|
+
action: "llm.request" | "llm.response" | "tool.call" | "tool.result" | "filter.blocked" | "budget.warning" | "budget.exceeded";
|
|
28
|
+
data: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guardrails/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,mBAAmB,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG,WAAW,GAAG,aAAa,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;IAC/H,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guardrails/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { interrupt, getUserInput, getUserApproval, getUserSelection, NodeInterruptSignal, _installInterruptContext, _clearInterruptContext, _getInterruptContext, } from "./interrupt.js";
|
|
2
|
+
export type { InterruptValue, ResumeValue, GetUserInputOptions, } from "./interrupt.js";
|
|
3
|
+
export { HITLSessionStore, HITLInterruptException, } from "./resume.js";
|
|
4
|
+
export type { HITLSession } from "./resume.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hitl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAExB,YAAY,EACV,cAAc,EACd,WAAW,EACX,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { interrupt, getUserInput, getUserApproval, getUserSelection, NodeInterruptSignal, _installInterruptContext, _clearInterruptContext, _getInterruptContext, } from "./interrupt.js";
|
|
2
|
+
export { HITLSessionStore, HITLInterruptException, } from "./resume.js";
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hitl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AAQxB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export interface InterruptValue {
|
|
2
|
+
/** Value the node is surfacing to the human */
|
|
3
|
+
value: unknown;
|
|
4
|
+
/** Which node triggered the interrupt */
|
|
5
|
+
node: string;
|
|
6
|
+
/** Unique resume key for this interrupt point */
|
|
7
|
+
resumeId: string;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ResumeValue {
|
|
11
|
+
resumeId: string;
|
|
12
|
+
value: unknown;
|
|
13
|
+
}
|
|
14
|
+
export declare class NodeInterruptSignal {
|
|
15
|
+
readonly value: unknown;
|
|
16
|
+
readonly resumeId: string;
|
|
17
|
+
readonly isNodeInterrupt = true;
|
|
18
|
+
constructor(value: unknown, resumeId: string);
|
|
19
|
+
}
|
|
20
|
+
interface InterruptContext {
|
|
21
|
+
nodeName: string;
|
|
22
|
+
resumeValue: unknown | undefined;
|
|
23
|
+
hasResume: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function _installInterruptContext(ctx: InterruptContext): void;
|
|
26
|
+
export declare function _clearInterruptContext(): void;
|
|
27
|
+
export declare function _getInterruptContext(): InterruptContext | null;
|
|
28
|
+
/**
|
|
29
|
+
* Pause execution and surface `value` to the human.
|
|
30
|
+
* Returns the human's response when execution resumes.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* addNode("review", async (state) => {
|
|
34
|
+
* const decision = await interrupt({
|
|
35
|
+
* message: "Approve this action?",
|
|
36
|
+
* data: state.pendingAction,
|
|
37
|
+
* });
|
|
38
|
+
* if (decision === "approve") {
|
|
39
|
+
* return { approved: true };
|
|
40
|
+
* }
|
|
41
|
+
* return { approved: false, reason: decision };
|
|
42
|
+
* });
|
|
43
|
+
*/
|
|
44
|
+
export declare function interrupt<T = unknown>(value: unknown): Promise<T>;
|
|
45
|
+
export interface GetUserInputOptions {
|
|
46
|
+
/** Prompt shown to the user */
|
|
47
|
+
prompt: string;
|
|
48
|
+
/** Optional field name for structured input */
|
|
49
|
+
field?: string;
|
|
50
|
+
/** Validation — if it returns false, the input is rejected */
|
|
51
|
+
validate?: (input: unknown) => boolean | string;
|
|
52
|
+
/** Expected input type hint */
|
|
53
|
+
inputType?: "text" | "boolean" | "number" | "select" | "json";
|
|
54
|
+
/** For "select" inputType — valid choices */
|
|
55
|
+
choices?: string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Pause execution and collect structured input from the human.
|
|
59
|
+
* A semantic alias for interrupt() with richer metadata.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* addNode("get_approval", async (state) => {
|
|
63
|
+
* const approved = await getUserInput({
|
|
64
|
+
* prompt: `Approve deployment of ${state.version}?`,
|
|
65
|
+
* inputType: "boolean",
|
|
66
|
+
* });
|
|
67
|
+
* return { approved: approved as boolean };
|
|
68
|
+
* });
|
|
69
|
+
*/
|
|
70
|
+
export declare function getUserInput<T = unknown>(opts: GetUserInputOptions): Promise<T>;
|
|
71
|
+
/**
|
|
72
|
+
* Ask the human for a yes/no decision.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* const ok = await getUserApproval("Deploy to production?");
|
|
76
|
+
* if (!ok) return { aborted: true };
|
|
77
|
+
*/
|
|
78
|
+
export declare function getUserApproval(prompt: string): Promise<boolean>;
|
|
79
|
+
export declare function getUserSelection(prompt: string, choices: string[]): Promise<string>;
|
|
80
|
+
export {};
|
|
81
|
+
//# sourceMappingURL=interrupt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interrupt.d.ts","sourceRoot":"","sources":["../../src/hitl/interrupt.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,KAAK,EAAK,OAAO,CAAC;IAClB,yCAAyC;IACzC,IAAI,EAAM,MAAM,CAAC;IACjB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAK,OAAO,CAAC;CACnB;AAMD,qBAAa,mBAAmB;aAGZ,KAAK,EAAK,OAAO;aACjB,QAAQ,EAAE,MAAM;IAHlC,QAAQ,CAAC,eAAe,QAAQ;gBAEd,KAAK,EAAK,OAAO,EACjB,QAAQ,EAAE,MAAM;CAEnC;AAMD,UAAU,gBAAgB;IACxB,QAAQ,EAAK,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,SAAS,EAAI,OAAO,CAAC;CACtB;AAKD,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAEpE;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED,wBAAgB,oBAAoB,IAAI,gBAAgB,GAAG,IAAI,CAE9D;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAkBvE;AAMD,MAAM,WAAW,mBAAmB;IAClC,+BAA+B;IAC/B,MAAM,EAAQ,MAAM,CAAC;IACrB,+CAA+C;IAC/C,KAAK,CAAC,EAAQ,MAAM,CAAC;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,EAAK,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,MAAM,CAAC;IACnD,+BAA+B;IAC/B,SAAS,CAAC,EAAI,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAChE,6CAA6C;IAC7C,OAAO,CAAC,EAAM,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,EAC5C,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,CAAC,CAAC,CAUZ;AAMD;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEtE;AAMD,wBAAsB,gBAAgB,CACpC,MAAM,EAAG,MAAM,EACf,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,MAAM,CAAC,CAEjB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// @oni.bot/core/hitl — interrupt() function API
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Allows calling interrupt(value) from INSIDE a node body to
|
|
5
|
+
// pause execution mid-node, surface a value to the caller,
|
|
6
|
+
// and resume with a response when the user provides one.
|
|
7
|
+
//
|
|
8
|
+
// This is fundamentally different from interruptBefore/After:
|
|
9
|
+
// - interruptBefore/After: pauses at node BOUNDARIES (compile-time)
|
|
10
|
+
// - interrupt(): pauses at ARBITRARY POINTS inside node logic (runtime)
|
|
11
|
+
//
|
|
12
|
+
// Implementation uses a context-local execution slot that the
|
|
13
|
+
// Pregel runner installs before calling each node, allowing the
|
|
14
|
+
// node to throw a structured interrupt that the runner catches,
|
|
15
|
+
// checkpoints, and re-raises to the caller.
|
|
16
|
+
// ============================================================
|
|
17
|
+
// ----------------------------------------------------------------
|
|
18
|
+
// Internal signal — thrown inside a node, caught by Pregel runner
|
|
19
|
+
// ----------------------------------------------------------------
|
|
20
|
+
export class NodeInterruptSignal {
|
|
21
|
+
value;
|
|
22
|
+
resumeId;
|
|
23
|
+
isNodeInterrupt = true;
|
|
24
|
+
constructor(value, resumeId) {
|
|
25
|
+
this.value = value;
|
|
26
|
+
this.resumeId = resumeId;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Per-async-context slot (global for now; can be AsyncLocalStorage in Node)
|
|
30
|
+
let _currentCtx = null;
|
|
31
|
+
export function _installInterruptContext(ctx) {
|
|
32
|
+
_currentCtx = ctx;
|
|
33
|
+
}
|
|
34
|
+
export function _clearInterruptContext() {
|
|
35
|
+
_currentCtx = null;
|
|
36
|
+
}
|
|
37
|
+
export function _getInterruptContext() {
|
|
38
|
+
return _currentCtx;
|
|
39
|
+
}
|
|
40
|
+
// ----------------------------------------------------------------
|
|
41
|
+
// interrupt(value) — call this inside any node
|
|
42
|
+
// ----------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Pause execution and surface `value` to the human.
|
|
45
|
+
* Returns the human's response when execution resumes.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* addNode("review", async (state) => {
|
|
49
|
+
* const decision = await interrupt({
|
|
50
|
+
* message: "Approve this action?",
|
|
51
|
+
* data: state.pendingAction,
|
|
52
|
+
* });
|
|
53
|
+
* if (decision === "approve") {
|
|
54
|
+
* return { approved: true };
|
|
55
|
+
* }
|
|
56
|
+
* return { approved: false, reason: decision };
|
|
57
|
+
* });
|
|
58
|
+
*/
|
|
59
|
+
export async function interrupt(value) {
|
|
60
|
+
const ctx = _currentCtx;
|
|
61
|
+
if (!ctx) {
|
|
62
|
+
throw new Error("interrupt() called outside of an ONI node execution context. " +
|
|
63
|
+
"Make sure you're calling interrupt() inside an addNode() function.");
|
|
64
|
+
}
|
|
65
|
+
// If we already have a resume value for this execution, return it
|
|
66
|
+
if (ctx.hasResume) {
|
|
67
|
+
return ctx.resumeValue;
|
|
68
|
+
}
|
|
69
|
+
// No resume yet — throw the interrupt signal to pause execution
|
|
70
|
+
const resumeId = `${ctx.nodeName}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
71
|
+
throw new NodeInterruptSignal(value, resumeId);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Pause execution and collect structured input from the human.
|
|
75
|
+
* A semantic alias for interrupt() with richer metadata.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* addNode("get_approval", async (state) => {
|
|
79
|
+
* const approved = await getUserInput({
|
|
80
|
+
* prompt: `Approve deployment of ${state.version}?`,
|
|
81
|
+
* inputType: "boolean",
|
|
82
|
+
* });
|
|
83
|
+
* return { approved: approved as boolean };
|
|
84
|
+
* });
|
|
85
|
+
*/
|
|
86
|
+
export async function getUserInput(opts) {
|
|
87
|
+
return interrupt({
|
|
88
|
+
__type: "user_input_request",
|
|
89
|
+
prompt: opts.prompt,
|
|
90
|
+
field: opts.field,
|
|
91
|
+
inputType: opts.inputType ?? "text",
|
|
92
|
+
choices: opts.choices,
|
|
93
|
+
// Validator serialized as string for display purposes
|
|
94
|
+
hasValidator: !!opts.validate,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// ----------------------------------------------------------------
|
|
98
|
+
// getUserApproval — boolean HITL shorthand
|
|
99
|
+
// ----------------------------------------------------------------
|
|
100
|
+
/**
|
|
101
|
+
* Ask the human for a yes/no decision.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* const ok = await getUserApproval("Deploy to production?");
|
|
105
|
+
* if (!ok) return { aborted: true };
|
|
106
|
+
*/
|
|
107
|
+
export async function getUserApproval(prompt) {
|
|
108
|
+
return getUserInput({ prompt, inputType: "boolean" });
|
|
109
|
+
}
|
|
110
|
+
// ----------------------------------------------------------------
|
|
111
|
+
// getUserSelection — pick from a list
|
|
112
|
+
// ----------------------------------------------------------------
|
|
113
|
+
export async function getUserSelection(prompt, choices) {
|
|
114
|
+
return getUserInput({ prompt, inputType: "select", choices });
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=interrupt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interrupt.js","sourceRoot":"","sources":["../../src/hitl/interrupt.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gDAAgD;AAChD,+DAA+D;AAC/D,6DAA6D;AAC7D,2DAA2D;AAC3D,yDAAyD;AACzD,EAAE;AACF,8DAA8D;AAC9D,sEAAsE;AACtE,0EAA0E;AAC1E,EAAE;AACF,8DAA8D;AAC9D,gEAAgE;AAChE,gEAAgE;AAChE,4CAA4C;AAC5C,+DAA+D;AA2B/D,mEAAmE;AACnE,kEAAkE;AAClE,mEAAmE;AAEnE,MAAM,OAAO,mBAAmB;IAGZ;IACA;IAHT,eAAe,GAAG,IAAI,CAAC;IAChC,YACkB,KAAiB,EACjB,QAAgB;QADhB,UAAK,GAAL,KAAK,CAAY;QACjB,aAAQ,GAAR,QAAQ,CAAQ;IAC/B,CAAC;CACL;AAYD,4EAA4E;AAC5E,IAAI,WAAW,GAA4B,IAAI,CAAC;AAEhD,MAAM,UAAU,wBAAwB,CAAC,GAAqB;IAC5D,WAAW,GAAG,GAAG,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,mEAAmE;AACnE,+CAA+C;AAC/C,mEAAmE;AAEnE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAc,KAAc;IACzD,MAAM,GAAG,GAAG,WAAW,CAAC;IAExB,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,+DAA+D;YAC/D,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,GAAG,CAAC,WAAgB,CAAC;IAC9B,CAAC;IAED,gEAAgE;IAChE,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,MAAM,IAAI,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAmBD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAyB;IAEzB,OAAO,SAAS,CAAI;QAClB,MAAM,EAAK,oBAAoB;QAC/B,MAAM,EAAK,IAAI,CAAC,MAAM;QACtB,KAAK,EAAM,IAAI,CAAC,KAAK;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,MAAM;QACnC,OAAO,EAAI,IAAI,CAAC,OAAO;QACvB,sDAAsD;QACtD,YAAY,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,mEAAmE;AACnE,2CAA2C;AAC3C,mEAAmE;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc;IAClD,OAAO,YAAY,CAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,mEAAmE;AACnE,sCAAsC;AACtC,mEAAmE;AAEnE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAe,EACf,OAAiB;IAEjB,OAAO,YAAY,CAAS,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AACxE,CAAC"}
|