@reactive-agents/compose 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,54 @@
1
+ import { Harness } from '@reactive-agents/core';
2
+
3
+ interface BudgetLimitOptions {
4
+ maxTokens?: number;
5
+ maxCostUSD?: number;
6
+ /** Per-token cost in USD. Default: 0.000001 (rough frontier estimate). */
7
+ costPerToken?: number;
8
+ onTrigger?: 'stop' | 'terminate';
9
+ }
10
+ declare function budgetLimit(options: BudgetLimitOptions): (harness: Harness) => void;
11
+
12
+ interface TimeoutAfterOptions {
13
+ wallClock: string | number;
14
+ onTrigger?: 'stop' | 'terminate';
15
+ }
16
+ declare function timeoutAfter(options: TimeoutAfterOptions): (harness: Harness) => void;
17
+
18
+ interface MaxIterationsOptions {
19
+ max: number;
20
+ onTrigger?: 'stop' | 'terminate';
21
+ }
22
+ declare function maxIterations(options: number | MaxIterationsOptions): (harness: Harness) => void;
23
+
24
+ interface RequireApprovalForOptions {
25
+ tools: string[];
26
+ approver: (ctx: {
27
+ toolName: string;
28
+ iteration: number;
29
+ }) => boolean;
30
+ onDeny?: 'stop' | 'terminate';
31
+ }
32
+ declare function requireApprovalFor(options: RequireApprovalForOptions): (harness: Harness) => void;
33
+
34
+ interface WatchdogOptions {
35
+ noProgressFor: string | number;
36
+ progressSignal?: 'observation.tool-result';
37
+ onTrigger?: 'stop' | 'terminate';
38
+ }
39
+ declare function watchdog(options: WatchdogOptions): (harness: Harness) => void;
40
+
41
+ interface ConfidenceFloorOptions {
42
+ verifier: number;
43
+ minSteps?: number;
44
+ earlyExit?: boolean;
45
+ }
46
+ declare function confidenceFloor(options: ConfidenceFloorOptions): (harness: Harness) => void;
47
+
48
+ declare const KILLSWITCH_NAMES: readonly ["budgetLimit", "timeoutAfter", "maxIterations", "requireApprovalFor", "watchdog", "confidenceFloor"];
49
+ type KillswitchName = typeof KILLSWITCH_NAMES[number];
50
+ declare const killswitches: {
51
+ readonly list: () => readonly KillswitchName[];
52
+ };
53
+
54
+ export { type BudgetLimitOptions, type ConfidenceFloorOptions, type MaxIterationsOptions, type RequireApprovalForOptions, type TimeoutAfterOptions, type WatchdogOptions, budgetLimit, confidenceFloor, killswitches, maxIterations, requireApprovalFor, timeoutAfter, watchdog };
package/dist/index.js ADDED
@@ -0,0 +1,151 @@
1
+ // src/killswitches/budget-limit.ts
2
+ function budgetLimit(options) {
3
+ const { maxTokens, maxCostUSD, costPerToken = 1e-6, onTrigger = "stop" } = options;
4
+ return (harness) => {
5
+ harness.before("think", (ctx) => {
6
+ const tokens = ctx.state.tokens ?? 0;
7
+ if (maxTokens !== void 0 && tokens >= maxTokens) {
8
+ return { abort: onTrigger, reason: `budget-limit:tokens:${tokens}/${maxTokens}` };
9
+ }
10
+ if (maxCostUSD !== void 0) {
11
+ const estimatedCost = tokens * costPerToken;
12
+ if (estimatedCost >= maxCostUSD) {
13
+ return { abort: onTrigger, reason: `budget-limit:cost:${estimatedCost.toFixed(4)}/${maxCostUSD}` };
14
+ }
15
+ }
16
+ return void 0;
17
+ });
18
+ };
19
+ }
20
+
21
+ // src/killswitches/timeout-after.ts
22
+ function parseMs(wallClock) {
23
+ if (typeof wallClock === "number") return wallClock;
24
+ const match = wallClock.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/);
25
+ if (!match) throw new Error(`Invalid wallClock: ${wallClock}`);
26
+ const [, n, unit] = match;
27
+ const multipliers = { ms: 1, s: 1e3, m: 6e4, h: 36e5 };
28
+ return parseFloat(n) * (multipliers[unit] ?? 1e3);
29
+ }
30
+ function timeoutAfter(options) {
31
+ const ms = parseMs(options.wallClock);
32
+ const onTrigger = options.onTrigger ?? "stop";
33
+ return (harness) => {
34
+ let timedOut = false;
35
+ let timer;
36
+ harness.before("bootstrap", () => {
37
+ timer = setTimeout(() => {
38
+ timedOut = true;
39
+ }, ms);
40
+ });
41
+ harness.before("think", () => {
42
+ if (timedOut) {
43
+ return { abort: onTrigger, reason: `timeout-after:${options.wallClock}` };
44
+ }
45
+ return void 0;
46
+ });
47
+ harness.after("complete", () => {
48
+ if (timer !== void 0) clearTimeout(timer);
49
+ });
50
+ };
51
+ }
52
+
53
+ // src/killswitches/max-iterations.ts
54
+ function maxIterations(options) {
55
+ const max = typeof options === "number" ? options : options.max;
56
+ const onTrigger = typeof options === "number" ? "stop" : options.onTrigger ?? "stop";
57
+ return (harness) => {
58
+ harness.before("think", (ctx) => {
59
+ if (ctx.iteration >= max) {
60
+ return { abort: onTrigger, reason: `max-iterations:${max}` };
61
+ }
62
+ return void 0;
63
+ });
64
+ };
65
+ }
66
+
67
+ // src/killswitches/require-approval-for.ts
68
+ function requireApprovalFor(options) {
69
+ const { tools, approver, onDeny = "stop" } = options;
70
+ const toolSet = new Set(tools);
71
+ return (harness) => {
72
+ harness.before("act", (ctx) => {
73
+ const pendingTools = ctx.state.pendingToolCalls ?? [];
74
+ for (const call of pendingTools) {
75
+ if (call.name && toolSet.has(call.name)) {
76
+ const approved = approver({ toolName: call.name, iteration: ctx.iteration });
77
+ if (!approved) {
78
+ return { abort: onDeny, reason: `require-approval-for:denied:${call.name}` };
79
+ }
80
+ }
81
+ }
82
+ return void 0;
83
+ });
84
+ };
85
+ }
86
+
87
+ // src/killswitches/watchdog.ts
88
+ function parseMs2(s) {
89
+ const match = s.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/);
90
+ if (!match) throw new Error(`Invalid duration: ${s}`);
91
+ const [, n, unit] = match;
92
+ const m = { ms: 1, s: 1e3, m: 6e4, h: 36e5 };
93
+ return parseFloat(n) * (m[unit] ?? 1e3);
94
+ }
95
+ function watchdog(options) {
96
+ const ms = typeof options.noProgressFor === "number" ? options.noProgressFor : parseMs2(options.noProgressFor);
97
+ const onTrigger = options.onTrigger ?? "stop";
98
+ return (harness) => {
99
+ let lastProgress = Date.now();
100
+ harness.tap("observation.tool-result", () => {
101
+ lastProgress = Date.now();
102
+ });
103
+ harness.before("think", () => {
104
+ const elapsed = Date.now() - lastProgress;
105
+ if (elapsed >= ms) {
106
+ return { abort: onTrigger, reason: `watchdog:no-progress-for:${elapsed}ms` };
107
+ }
108
+ return void 0;
109
+ });
110
+ };
111
+ }
112
+
113
+ // src/killswitches/confidence-floor.ts
114
+ function confidenceFloor(options) {
115
+ const { verifier: threshold, minSteps = 1, earlyExit = true } = options;
116
+ return (harness) => {
117
+ if (!earlyExit) return;
118
+ harness.before("verify", (ctx) => {
119
+ const state = ctx.state;
120
+ const stepCount = state.steps?.length ?? 0;
121
+ const score = state.verifierScore ?? 0;
122
+ if (stepCount >= minSteps && score >= threshold) {
123
+ return { abort: "stop", reason: `confidence-floor:score:${score}>=${threshold}` };
124
+ }
125
+ return void 0;
126
+ });
127
+ };
128
+ }
129
+
130
+ // src/killswitches/registry.ts
131
+ var KILLSWITCH_NAMES = [
132
+ "budgetLimit",
133
+ "timeoutAfter",
134
+ "maxIterations",
135
+ "requireApprovalFor",
136
+ "watchdog",
137
+ "confidenceFloor"
138
+ ];
139
+ var killswitches = {
140
+ list: () => KILLSWITCH_NAMES
141
+ };
142
+ export {
143
+ budgetLimit,
144
+ confidenceFloor,
145
+ killswitches,
146
+ maxIterations,
147
+ requireApprovalFor,
148
+ timeoutAfter,
149
+ watchdog
150
+ };
151
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/killswitches/budget-limit.ts","../src/killswitches/timeout-after.ts","../src/killswitches/max-iterations.ts","../src/killswitches/require-approval-for.ts","../src/killswitches/watchdog.ts","../src/killswitches/confidence-floor.ts","../src/killswitches/registry.ts"],"sourcesContent":["import type { Harness } from '@reactive-agents/core';\n\nexport interface BudgetLimitOptions {\n maxTokens?: number;\n maxCostUSD?: number;\n /** Per-token cost in USD. Default: 0.000001 (rough frontier estimate). */\n costPerToken?: number;\n onTrigger?: 'stop' | 'terminate';\n}\n\nexport function budgetLimit(options: BudgetLimitOptions): (harness: Harness) => void {\n const { maxTokens, maxCostUSD, costPerToken = 0.000001, onTrigger = 'stop' } = options;\n return (harness: Harness) => {\n harness.before('think', (ctx) => {\n const tokens = (ctx.state as { tokens?: number }).tokens ?? 0;\n if (maxTokens !== undefined && tokens >= maxTokens) {\n return { abort: onTrigger, reason: `budget-limit:tokens:${tokens}/${maxTokens}` };\n }\n if (maxCostUSD !== undefined) {\n const estimatedCost = tokens * costPerToken;\n if (estimatedCost >= maxCostUSD) {\n return { abort: onTrigger, reason: `budget-limit:cost:${estimatedCost.toFixed(4)}/${maxCostUSD}` };\n }\n }\n return undefined;\n });\n };\n}\n","import type { Harness } from '@reactive-agents/core';\n\nexport interface TimeoutAfterOptions {\n wallClock: string | number; // '60s' | '5m' | milliseconds\n onTrigger?: 'stop' | 'terminate';\n}\n\nfunction parseMs(wallClock: string | number): number {\n if (typeof wallClock === 'number') return wallClock;\n const match = wallClock.match(/^(\\d+(?:\\.\\d+)?)(ms|s|m|h)$/);\n if (!match) throw new Error(`Invalid wallClock: ${wallClock}`);\n const [, n, unit] = match;\n const multipliers: Record<string, number> = { ms: 1, s: 1000, m: 60_000, h: 3_600_000 };\n return parseFloat(n!) * (multipliers[unit!] ?? 1000);\n}\n\nexport function timeoutAfter(options: TimeoutAfterOptions): (harness: Harness) => void {\n const ms = parseMs(options.wallClock);\n const onTrigger = options.onTrigger ?? 'stop';\n return (harness: Harness) => {\n let timedOut = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n harness.before('bootstrap', () => {\n timer = setTimeout(() => { timedOut = true; }, ms);\n });\n\n harness.before('think', () => {\n if (timedOut) {\n return { abort: onTrigger, reason: `timeout-after:${options.wallClock}` };\n }\n return undefined;\n });\n\n harness.after('complete', () => {\n if (timer !== undefined) clearTimeout(timer);\n });\n };\n}\n","import type { Harness } from '@reactive-agents/core';\n\nexport interface MaxIterationsOptions {\n max: number;\n onTrigger?: 'stop' | 'terminate';\n}\n\nexport function maxIterations(options: number | MaxIterationsOptions): (harness: Harness) => void {\n const max = typeof options === 'number' ? options : options.max;\n const onTrigger = typeof options === 'number' ? 'stop' : (options.onTrigger ?? 'stop');\n return (harness: Harness) => {\n harness.before('think', (ctx) => {\n if (ctx.iteration >= max) {\n return { abort: onTrigger, reason: `max-iterations:${max}` };\n }\n return undefined;\n });\n };\n}\n","import type { Harness } from '@reactive-agents/core';\n\nexport interface RequireApprovalForOptions {\n tools: string[];\n // Synchronous check: returns true if approved, false if denied.\n // For async approvers, check externally before creating the killswitch.\n approver: (ctx: { toolName: string; iteration: number }) => boolean;\n onDeny?: 'stop' | 'terminate';\n}\n\nexport function requireApprovalFor(options: RequireApprovalForOptions): (harness: Harness) => void {\n const { tools, approver, onDeny = 'stop' } = options;\n const toolSet = new Set(tools);\n return (harness: Harness) => {\n harness.before('act', (ctx) => {\n // ctx.state has pending tool calls — extract next tool name if available\n const pendingTools = (ctx.state as { pendingToolCalls?: Array<{ name?: string }> })\n .pendingToolCalls ?? [];\n for (const call of pendingTools) {\n if (call.name && toolSet.has(call.name)) {\n const approved = approver({ toolName: call.name, iteration: ctx.iteration });\n if (!approved) {\n return { abort: onDeny, reason: `require-approval-for:denied:${call.name}` };\n }\n }\n }\n return undefined;\n });\n };\n}\n","import type { Harness } from '@reactive-agents/core';\n\nexport interface WatchdogOptions {\n noProgressFor: string | number; // '30s' | milliseconds\n progressSignal?: 'observation.tool-result'; // currently only this tag in TagMap\n onTrigger?: 'stop' | 'terminate';\n}\n\nfunction parseMs(s: string): number {\n const match = s.match(/^(\\d+(?:\\.\\d+)?)(ms|s|m|h)$/);\n if (!match) throw new Error(`Invalid duration: ${s}`);\n const [, n, unit] = match;\n const m: Record<string, number> = { ms: 1, s: 1000, m: 60_000, h: 3_600_000 };\n return parseFloat(n!) * (m[unit!] ?? 1000);\n}\n\nexport function watchdog(options: WatchdogOptions): (harness: Harness) => void {\n const ms = typeof options.noProgressFor === 'number'\n ? options.noProgressFor\n : parseMs(options.noProgressFor);\n const onTrigger = options.onTrigger ?? 'stop';\n return (harness: Harness) => {\n let lastProgress = Date.now();\n\n // Track progress via observation.tool-result events\n harness.tap('observation.tool-result', () => {\n lastProgress = Date.now();\n });\n\n harness.before('think', () => {\n const elapsed = Date.now() - lastProgress;\n if (elapsed >= ms) {\n return { abort: onTrigger, reason: `watchdog:no-progress-for:${elapsed}ms` };\n }\n return undefined;\n });\n };\n}\n","import type { Harness } from '@reactive-agents/core';\n\nexport interface ConfidenceFloorOptions {\n verifier: number; // threshold 0–1\n minSteps?: number; // minimum steps before early exit allowed\n earlyExit?: boolean;\n}\n\nexport function confidenceFloor(options: ConfidenceFloorOptions): (harness: Harness) => void {\n const { verifier: threshold, minSteps = 1, earlyExit = true } = options;\n return (harness: Harness) => {\n if (!earlyExit) return; // no-op if earlyExit disabled\n harness.before('verify', (ctx) => {\n const state = ctx.state as unknown as { steps?: unknown[]; verifierScore?: number };\n const stepCount = (state.steps?.length ?? 0) as number;\n const score = (state.verifierScore ?? 0) as number;\n if (stepCount >= minSteps && score >= threshold) {\n // Signal: confidence floor met — allow immediate completion\n // This is a 'stop' (graceful done), not terminate\n return { abort: 'stop', reason: `confidence-floor:score:${score}>=${threshold}` };\n }\n return undefined;\n });\n };\n}\n","const KILLSWITCH_NAMES = [\n 'budgetLimit',\n 'timeoutAfter',\n 'maxIterations',\n 'requireApprovalFor',\n 'watchdog',\n 'confidenceFloor',\n] as const;\n\nexport type KillswitchName = typeof KILLSWITCH_NAMES[number];\n\nexport const killswitches = {\n list: (): readonly KillswitchName[] => KILLSWITCH_NAMES,\n} as const;\n"],"mappings":"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","names":["parseMs"]}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@reactive-agents/compose",
3
+ "version": "0.11.0",
4
+ "description": "Prebuilt killswitch compositions for reactive agents",
5
+ "type": "module",
6
+ "scripts": {
7
+ "build": "tsup --config ../../tsup.config.base.ts",
8
+ "typecheck": "tsc --noEmit",
9
+ "test": "bun test --reporter=dots",
10
+ "test:watch": "bun test --watch"
11
+ },
12
+ "dependencies": {
13
+ "@reactive-agents/core": "0.11.0"
14
+ },
15
+ "devDependencies": {
16
+ "typescript": "^6.0.3",
17
+ "bun-types": "latest"
18
+ },
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/tylerjrbuell/reactive-agents-ts.git",
23
+ "directory": "packages/compose"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "exports": {
34
+ ".": {
35
+ "bun": "./dist/index.js",
36
+ "import": "./dist/index.js",
37
+ "types": "./dist/index.d.ts"
38
+ },
39
+ "./killswitches": {
40
+ "bun": "./dist/killswitches/index.js",
41
+ "import": "./dist/killswitches/index.js",
42
+ "types": "./dist/killswitches/index.d.ts"
43
+ }
44
+ },
45
+ "homepage": "https://docs.reactiveagents.dev/",
46
+ "bugs": {
47
+ "url": "https://github.com/tylerjrbuell/reactive-agents-ts/issues"
48
+ }
49
+ }