agentrein 1.0.8 → 1.0.9

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 ADDED
@@ -0,0 +1,71 @@
1
+ # AgentRein SDK - Node.js Client
2
+
3
+ **AgentRein** is an AI Agent Reliability Platform that provides automatic rollback, approval gates, and intent verification for AI workflows. This SDK allows you to easily integrate AgentRein into your Node.js applications.
4
+
5
+ ---
6
+
7
+ ## 📦 Install
8
+
9
+ ```bash
10
+ npm install agentrein
11
+ ```
12
+
13
+ ## 🚀 Quick Start
14
+
15
+ ```typescript
16
+ import { AgentRein } from 'agentrein'
17
+
18
+ const agentrein = new AgentRein({
19
+ apiKey: process.env.AGENTREIN_API_KEY, // Your Organization API Key
20
+ intentVerification: true, // Enable LLM intent check
21
+ })
22
+
23
+ async function runAgent() {
24
+ // 1. Create a session with a clear intent
25
+ const session = await agentrein.newSession({
26
+ agentId: 'support-agent-01',
27
+ intent: 'Refund customer cus_123 for order ord_456'
28
+ })
29
+
30
+ try {
31
+ // 2. Wrap your external API calls
32
+ const result = await agentrein.call(
33
+ stripe.refunds.create, // The function to execute
34
+ session, // The current session
35
+ {
36
+ type: 'http-delete',
37
+ url: 'https://api.stripe.com/v1/refunds/re_123'
38
+ }, // Undo configuration (if rollback is needed)
39
+ { charge: 'ch_789' } // Original function arguments
40
+ )
41
+
42
+ console.log('Action executed safely:', result)
43
+ } catch (error) {
44
+ // 3. AgentRein automatically triggers rollback on failure
45
+ console.error('Action failed, rolling back previous steps...', error)
46
+ }
47
+ }
48
+ ```
49
+
50
+ ## 🧠 Key Concepts
51
+
52
+ ### Sessions
53
+ A `Session` groups multiple actions together. If any action in the session fails, AgentRein will attempt to roll back all previous successful actions in that session in reverse order.
54
+
55
+ ### Intent Verification
56
+ By providing an `intent` when creating a session, AgentRein uses an LLM to verify that each subsequent action aligns with the user's original goal. If "drift" is detected, the action can be flagged or blocked.
57
+
58
+ ### Approval Gates
59
+ You can configure rules in the [AgentRein Dashboard](https://agentrein.com/sessions) to require human approval for high-risk actions before they are executed.
60
+
61
+ ## 🛠️ Configuration
62
+
63
+ | Option | Type | Description |
64
+ | :--- | :--- | :--- |
65
+ | `apiKey` | `string` | **Required**. Your organization's API key. |
66
+ | `baseUrl` | `string` | Optional. Defaults to `https://api.agentrein.com`. |
67
+ | `intentVerification` | `boolean` | Optional. Enable/disable LLM drift detection. |
68
+
69
+ ## 📄 License
70
+
71
+ MIT
@@ -0,0 +1,64 @@
1
+ import { AgentReinUnavailableError } from './errors';
2
+ export interface AgentReinOptions {
3
+ apiKey: string;
4
+ serverUrl?: string;
5
+ failureMode?: 'open' | 'closed';
6
+ }
7
+ export interface SessionOptions {
8
+ agentId?: string;
9
+ intent?: string;
10
+ }
11
+ export interface UndoConfig {
12
+ type: 'slack-correction' | 'http-delete' | 'none';
13
+ url?: string;
14
+ headers?: Record<string, string>;
15
+ body?: Record<string, unknown>;
16
+ }
17
+ export interface Session {
18
+ id: string;
19
+ organizationId: string;
20
+ agentId: string;
21
+ intent: string | null;
22
+ status: string;
23
+ startedAt: string;
24
+ endedAt: string | null;
25
+ }
26
+ export { AgentReinUnavailableError };
27
+ export declare class AgentRein {
28
+ private readonly serverUrl;
29
+ private readonly apiKey;
30
+ private readonly failureMode;
31
+ private token;
32
+ constructor(options: AgentReinOptions);
33
+ /**
34
+ * Obtain a JWT token from the AgentRein server using the API key.
35
+ * Caches the token for subsequent requests.
36
+ */
37
+ private getToken;
38
+ /**
39
+ * Build authorization headers for server requests.
40
+ */
41
+ private authHeaders;
42
+ /**
43
+ * Create a new agent session on the AgentRein server.
44
+ *
45
+ * @param options - Session options (agentId + optional intent).
46
+ * Can also pass a plain string for backward compat (agentId).
47
+ * If omitted, a random agentId is generated.
48
+ */
49
+ newSession(options?: SessionOptions | string): Promise<Session>;
50
+ /**
51
+ * Execute an API call under AgentRein's protection.
52
+ *
53
+ * 1. Calls fn(...args)
54
+ * 2. Logs the action to the AgentRein server (async, non-blocking)
55
+ * 3. On failure, triggers server-side rollback
56
+ *
57
+ * @param fn - The function to execute
58
+ * @param session - The active AgentRein session
59
+ * @param args - Arguments forwarded to fn
60
+ */
61
+ call<T>(fn: Function, session: Session, ...args: any[]): Promise<T>;
62
+ call<T>(fn: Function, session: Session, undoConfig: UndoConfig, ...args: any[]): Promise<T>;
63
+ }
64
+ export default AgentRein;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentRein = exports.AgentReinUnavailableError = void 0;
4
+ const axios_1 = require("axios");
5
+ const errors_1 = require("./errors");
6
+ Object.defineProperty(exports, "AgentReinUnavailableError", { enumerable: true, get: function () { return errors_1.AgentReinUnavailableError; } });
7
+ // ─── AgentRein Client ─────────────────────────────────────
8
+ class AgentRein {
9
+ constructor(options) {
10
+ this.token = null;
11
+ this.serverUrl = options.serverUrl || 'https://api.agentrein.com';
12
+ this.apiKey = options.apiKey;
13
+ this.failureMode = options.failureMode ?? 'open';
14
+ }
15
+ // ── Authentication ──────────────────────────────────
16
+ /**
17
+ * Obtain a JWT token from the AgentRein server using the API key.
18
+ * Caches the token for subsequent requests.
19
+ */
20
+ async getToken() {
21
+ if (this.token)
22
+ return this.token;
23
+ try {
24
+ const res = await axios_1.default.post(`${this.serverUrl}/auth/token`, {
25
+ apiKey: this.apiKey,
26
+ });
27
+ this.token = res.data.data.token;
28
+ return this.token;
29
+ }
30
+ catch (err) {
31
+ throw new errors_1.AgentReinUnavailableError(`Failed to authenticate with AgentRein server: ${err instanceof Error ? err.message : String(err)}`);
32
+ }
33
+ }
34
+ /**
35
+ * Build authorization headers for server requests.
36
+ */
37
+ async authHeaders() {
38
+ const token = await this.getToken();
39
+ return { Authorization: `Bearer ${token}` };
40
+ }
41
+ // ── newSession ───────────────────────────────────────
42
+ /**
43
+ * Create a new agent session on the AgentRein server.
44
+ *
45
+ * @param options - Session options (agentId + optional intent).
46
+ * Can also pass a plain string for backward compat (agentId).
47
+ * If omitted, a random agentId is generated.
48
+ */
49
+ async newSession(options) {
50
+ const resolved = typeof options === 'string'
51
+ ? { agentId: options, intent: undefined }
52
+ : options ?? {};
53
+ const agentId = resolved.agentId ?? crypto.randomUUID();
54
+ const intent = resolved.intent;
55
+ const headers = await this.authHeaders();
56
+ const res = await axios_1.default.post(`${this.serverUrl}/sessions`, { agentId, intent }, { headers });
57
+ return res.data.data;
58
+ }
59
+ async call(fn, session, ...args) {
60
+ // Detect if first extra arg is an UndoConfig object
61
+ let undoConfig;
62
+ let callArgs = args;
63
+ if (args.length > 0 &&
64
+ args[0] &&
65
+ typeof args[0] === 'object' &&
66
+ 'type' in args[0] &&
67
+ ['slack-correction', 'http-delete', 'none'].includes(args[0].type)) {
68
+ undoConfig = args[0];
69
+ callArgs = args.slice(1);
70
+ }
71
+ const headers = await this.authHeaders();
72
+ try {
73
+ const result = await fn(...callArgs);
74
+ // Log action to server (fire-and-forget)
75
+ axios_1.default.post(`${this.serverUrl}/sessions/${session.id}/actions`, {
76
+ apiName: fn.name || 'anonymous',
77
+ operationType: 'CREATE',
78
+ payload: callArgs[0] ?? {},
79
+ response: result,
80
+ status: 'SUCCESS',
81
+ undoConfig,
82
+ }, { headers }).catch(() => { });
83
+ return result;
84
+ }
85
+ catch (error) {
86
+ // Trigger server-side rollback
87
+ await axios_1.default.post(`${this.serverUrl}/sessions/${session.id}/rollback`, {}, { headers }).catch(() => { });
88
+ throw error;
89
+ }
90
+ }
91
+ }
92
+ exports.AgentRein = AgentRein;
93
+ exports.default = AgentRein;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Custom errors for the AgentRein SDK.
3
+ */
4
+ export declare class AgentReinUnavailableError extends Error {
5
+ constructor(message?: string);
6
+ }
7
+ export declare class ApprovalRejectedError extends Error {
8
+ constructor(apiName: string, reason?: string);
9
+ }
10
+ export declare class ApprovalTimeoutError extends Error {
11
+ constructor(apiName: string, timeoutMinutes: number);
12
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Custom errors for the AgentRein SDK.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ApprovalTimeoutError = exports.ApprovalRejectedError = exports.AgentReinUnavailableError = void 0;
7
+ class AgentReinUnavailableError extends Error {
8
+ constructor(message) {
9
+ super(message ?? 'AgentRein safety layer is unavailable');
10
+ this.name = 'AgentReinUnavailableError';
11
+ }
12
+ }
13
+ exports.AgentReinUnavailableError = AgentReinUnavailableError;
14
+ class ApprovalRejectedError extends Error {
15
+ constructor(apiName, reason) {
16
+ super(`Action "${apiName}" was rejected by a human reviewer${reason ? `: ${reason}` : ''}`);
17
+ this.name = 'ApprovalRejectedError';
18
+ }
19
+ }
20
+ exports.ApprovalRejectedError = ApprovalRejectedError;
21
+ class ApprovalTimeoutError extends Error {
22
+ constructor(apiName, timeoutMinutes) {
23
+ super(`Action "${apiName}" was not approved within ${timeoutMinutes} minutes — auto-rejected`);
24
+ this.name = 'ApprovalTimeoutError';
25
+ }
26
+ }
27
+ exports.ApprovalTimeoutError = ApprovalTimeoutError;
@@ -0,0 +1,90 @@
1
+ import axios from 'axios';
2
+ import { AgentReinUnavailableError } from './errors';
3
+ // Re-export errors for consumer convenience
4
+ export { AgentReinUnavailableError };
5
+ // ─── AgentRein Client ─────────────────────────────────────
6
+ export class AgentRein {
7
+ constructor(options) {
8
+ this.token = null;
9
+ this.serverUrl = options.serverUrl || 'https://api.agentrein.com';
10
+ this.apiKey = options.apiKey;
11
+ this.failureMode = options.failureMode ?? 'open';
12
+ }
13
+ // ── Authentication ──────────────────────────────────
14
+ /**
15
+ * Obtain a JWT token from the AgentRein server using the API key.
16
+ * Caches the token for subsequent requests.
17
+ */
18
+ async getToken() {
19
+ if (this.token)
20
+ return this.token;
21
+ try {
22
+ const res = await axios.post(`${this.serverUrl}/auth/token`, {
23
+ apiKey: this.apiKey,
24
+ });
25
+ this.token = res.data.data.token;
26
+ return this.token;
27
+ }
28
+ catch (err) {
29
+ throw new AgentReinUnavailableError(`Failed to authenticate with AgentRein server: ${err instanceof Error ? err.message : String(err)}`);
30
+ }
31
+ }
32
+ /**
33
+ * Build authorization headers for server requests.
34
+ */
35
+ async authHeaders() {
36
+ const token = await this.getToken();
37
+ return { Authorization: `Bearer ${token}` };
38
+ }
39
+ // ── newSession ───────────────────────────────────────
40
+ /**
41
+ * Create a new agent session on the AgentRein server.
42
+ *
43
+ * @param options - Session options (agentId + optional intent).
44
+ * Can also pass a plain string for backward compat (agentId).
45
+ * If omitted, a random agentId is generated.
46
+ */
47
+ async newSession(options) {
48
+ const resolved = typeof options === 'string'
49
+ ? { agentId: options, intent: undefined }
50
+ : options ?? {};
51
+ const agentId = resolved.agentId ?? crypto.randomUUID();
52
+ const intent = resolved.intent;
53
+ const headers = await this.authHeaders();
54
+ const res = await axios.post(`${this.serverUrl}/sessions`, { agentId, intent }, { headers });
55
+ return res.data.data;
56
+ }
57
+ async call(fn, session, ...args) {
58
+ // Detect if first extra arg is an UndoConfig object
59
+ let undoConfig;
60
+ let callArgs = args;
61
+ if (args.length > 0 &&
62
+ args[0] &&
63
+ typeof args[0] === 'object' &&
64
+ 'type' in args[0] &&
65
+ ['slack-correction', 'http-delete', 'none'].includes(args[0].type)) {
66
+ undoConfig = args[0];
67
+ callArgs = args.slice(1);
68
+ }
69
+ const headers = await this.authHeaders();
70
+ try {
71
+ const result = await fn(...callArgs);
72
+ // Log action to server (fire-and-forget)
73
+ axios.post(`${this.serverUrl}/sessions/${session.id}/actions`, {
74
+ apiName: fn.name || 'anonymous',
75
+ operationType: 'CREATE',
76
+ payload: callArgs[0] ?? {},
77
+ response: result,
78
+ status: 'SUCCESS',
79
+ undoConfig,
80
+ }, { headers }).catch(() => { });
81
+ return result;
82
+ }
83
+ catch (error) {
84
+ // Trigger server-side rollback
85
+ await axios.post(`${this.serverUrl}/sessions/${session.id}/rollback`, {}, { headers }).catch(() => { });
86
+ throw error;
87
+ }
88
+ }
89
+ }
90
+ export default AgentRein;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Custom errors for the AgentRein SDK.
3
+ */
4
+ export class AgentReinUnavailableError extends Error {
5
+ constructor(message) {
6
+ super(message ?? 'AgentRein safety layer is unavailable');
7
+ this.name = 'AgentReinUnavailableError';
8
+ }
9
+ }
10
+ export class ApprovalRejectedError extends Error {
11
+ constructor(apiName, reason) {
12
+ super(`Action "${apiName}" was rejected by a human reviewer${reason ? `: ${reason}` : ''}`);
13
+ this.name = 'ApprovalRejectedError';
14
+ }
15
+ }
16
+ export class ApprovalTimeoutError extends Error {
17
+ constructor(apiName, timeoutMinutes) {
18
+ super(`Action "${apiName}" was not approved within ${timeoutMinutes} minutes — auto-rejected`);
19
+ this.name = 'ApprovalTimeoutError';
20
+ }
21
+ }
package/package.json CHANGED
@@ -1,14 +1,24 @@
1
1
  {
2
2
  "name": "agentrein",
3
- "version": "1.0.8",
4
- "main": "dist/agentreinClient.js",
5
- "types": "dist/agentreinClient.d.ts",
3
+ "version": "1.0.9",
4
+ "main": "./dist/cjs/agentreinClient.js",
5
+ "module": "./dist/esm/agentreinClient.js",
6
+ "types": "./dist/cjs/agentreinClient.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/esm/agentreinClient.js",
10
+ "require": "./dist/cjs/agentreinClient.js",
11
+ "types": "./dist/cjs/agentreinClient.d.ts"
12
+ }
13
+ },
6
14
  "files": [
7
15
  "dist/",
8
16
  "README.md"
9
17
  ],
10
18
  "scripts": {
11
- "build": "tsc",
19
+ "build": "npm run build:cjs && npm run build:esm",
20
+ "build:cjs": "tsc --project tsconfig.cjs.json",
21
+ "build:esm": "tsc --project tsconfig.esm.json",
12
22
  "prepublishOnly": "npm run build"
13
23
  },
14
24
  "dependencies": {