@dropout-ai/runtime 0.4.0 → 0.4.2

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 CHANGED
@@ -1,74 +1,87 @@
1
+
1
2
  # 🕵️ Dropout AI Runtime (`@dropout-ai/runtime`)
2
3
 
3
4
  **Universal AI Behavior Analysis & Capture for Node.js**
4
5
 
5
- Dropout is a lightweight, "install-and-forget" runtime that automatically captures AI interactions (prompts & responses) from your application without requiring code changes. It acts as a passive observer, patching the network layer to ensure you never miss a conversation.
6
+ Dropout is a lightweight, "install-and-forget" runtime that automatically captures AI interactions (prompts & responses) from your application without requiring code changes to your API calls. It acts as a passive observer, patching the network layer to ensure you never miss a conversation.
6
7
 
7
8
  * **🔌 Universal:** Works with OpenAI, Anthropic, Genkit, LangChain, Axios, and `fetch`.
8
9
  * **🛡️ Safe:** Designed for production with silent failure modes and browser guards.
9
10
  * **⚡ Zero-Latency:** Uses fire-and-forget logging to ensure your app stays fast.
10
- * **🔋 Auto-Discovery:** Automatically detects framework (Next.js, NestJS) and configures itself.
11
+ * **🔋 Robust:** Explicit initialization ensures you always know when it's running.
11
12
 
12
13
  ---
13
14
 
14
- ## 🚀 Quick Start (Recommended)
15
+ ## 🚀 Quick Start (Wizard)
15
16
 
16
- Run our initialization wizard in your project root. It will detect your framework and automatically create the necessary configuration files.
17
+ The easiest way to get started is to run our installer. It will install the package and give you the exact code snippet to copy.
17
18
 
18
19
  ```bash
19
- npx @dropout-ai/runtime init
20
+ npx @dropout-ai/wizard@latest
20
21
 
21
22
  ```
22
23
 
23
- *Supports: **Next.js** (App Router), **NestJS**, **Express**, and standard **Node.js** apps.*
24
-
25
24
  ---
26
25
 
27
- ## 🛠️ Manual Installation
26
+ ## 🛠️ Manual Installation & Usage
27
+
28
+ If you prefer to install manually, follow these two steps.
28
29
 
29
- If you prefer to configure it yourself, install the package and follow the guide for your specific framework.
30
+ ### 1. Install the Package
30
31
 
31
32
  ```bash
32
33
  npm install @dropout-ai/runtime
33
34
  # or
34
- yarn add @dropout-ai/runtime
35
+ pnpm add @dropout-ai/runtime
35
36
 
36
37
  ```
37
38
 
38
- ### 1. Next.js (App Router)
39
+ ### 2. Initialize (The "Universal" Method)
40
+
41
+ To start capturing, you must explicitly initialize Dropout. Place this code snippet **as early as possible** in your application lifecycle (before you make any AI calls).
42
+
43
+ It is safe to call `init()` multiple times; it will only run once.
39
44
 
40
- Next.js uses lazy-loading, so we use `instrumentation.ts` to ensure Dropout loads immediately on server boot.
45
+ #### For Next.js (App Router)
41
46
 
42
- **Create/Edit:** `src/instrumentation.ts` (or `instrumentation.ts` in root)
47
+ **File:** `src/instrumentation.ts` (or `instrumentation.ts` in root)
43
48
 
44
49
  ```typescript
45
50
  export async function register() {
46
- // Ensure we only run on the Node.js server runtime
47
51
  if (process.env.NEXT_RUNTIME === 'nodejs') {
48
- await import('@dropout-ai/runtime');
49
- console.log('✅ Dropout AI Monitoring Active');
52
+ const { default: Dropout } = await import('@dropout-ai/runtime');
53
+
54
+ Dropout.init({
55
+ apiKey: process.env.DROPOUT_API_KEY,
56
+ projectId: process.env.DROPOUT_PROJECT_ID,
57
+ debug: true // Set to false in production
58
+ });
50
59
  }
51
60
  }
52
61
 
53
62
  ```
54
63
 
55
- ### 2. Node.js / Express / Fastify
64
+ #### For Node.js / Express / Fastify
56
65
 
57
- Initialize Dropout at the **very top** of your entry file (`index.js` or `server.js`), before importing other libraries.
66
+ **File:** `index.js` or `server.js` (Top of file)
58
67
 
59
68
  ```javascript
60
- // MUST be the first line
61
- require('@dropout-ai/runtime');
69
+ require('dotenv').config(); // Ensure env vars are loaded first
70
+ const Dropout = require('@dropout-ai/runtime');
71
+
72
+ Dropout.init({
73
+ apiKey: process.env.DROPOUT_API_KEY,
74
+ projectId: process.env.DROPOUT_PROJECT_ID,
75
+ debug: process.env.NODE_ENV !== 'production'
76
+ });
62
77
 
63
78
  const express = require('express');
64
79
  const app = express();
65
- // ... rest of your code
80
+ // ...
66
81
 
67
82
  ```
68
83
 
69
- ### 3. NestJS
70
-
71
- Initialize Dropout inside your `bootstrap()` function before creating the Nest app.
84
+ #### For NestJS
72
85
 
73
86
  **File:** `src/main.ts`
74
87
 
@@ -78,10 +91,11 @@ import { AppModule } from './app.module';
78
91
  import Dropout from '@dropout-ai/runtime';
79
92
 
80
93
  async function bootstrap() {
81
- // ✅ Initialize first - Sends "Boot Ping" immediately
82
- new Dropout({
83
- projectId: process.env.DROPOUT_PROJECT_ID,
84
- apiKey: process.env.DROPOUT_API_KEY
94
+ // ✅ Initialize before the app starts
95
+ Dropout.init({
96
+ apiKey: process.env.DROPOUT_API_KEY,
97
+ projectId: process.env.DROPOUT_PROJECT_ID,
98
+ debug: true
85
99
  });
86
100
 
87
101
  const app = await NestFactory.create(AppModule);
@@ -91,96 +105,54 @@ bootstrap();
91
105
 
92
106
  ```
93
107
 
94
- ### 4. Docker / Zero-Code Injection
95
-
96
- You can inject Dropout into any Node.js application without editing a single file by using the Node `--require` flag. This is perfect for Docker containers or PaaS deployments.
97
-
98
- ```bash
99
- # 1. Set credentials
100
- export DROPOUT_PROJECT_ID="your_project_id"
101
- export DROPOUT_API_KEY="dp_live_..."
108
+ ---
102
109
 
103
- # 2. Run your app with the runtime injected
104
- node -r @dropout-ai/runtime dist/index.js
110
+ ## ⚙️ Configuration
105
111
 
106
- ```
112
+ | Option | Type | Description | Required |
113
+ | --- | --- | --- | --- |
114
+ | `projectId` | `string` | Your Project ID from the dashboard. | ✅ |
115
+ | `apiKey` | `string` | Your Secret Key (`dp_live_...`). | ✅ |
116
+ | `debug` | `boolean` | Set `true` to see "🟢 Online" logs and errors in console. | No |
117
+ | `privacy` | `string` | `full` (capture text) or `mask` (metadata only). Default: `full`. | No |
107
118
 
108
119
  ---
109
120
 
110
- ## ⚙️ Configuration
121
+ ## Troubleshooting
111
122
 
112
- You can configure Dropout via **Environment Variables** (Recommended) or by passing options to the constructor.
123
+ **Q: How do I know if it's working?**
124
+ Set `debug: true` in your config. When your app starts, you should see this message immediately:
113
125
 
114
- | Environment Variable | Config Option | Description | Required |
115
- | --- | --- | --- | --- |
116
- | `DROPOUT_PROJECT_ID` | `projectId` | Your Project ID from dashboard. | ✅ |
117
- | `DROPOUT_API_KEY` | `apiKey` | Your Secret Key (`dp_live_...`). | ✅ |
118
- | `DROPOUT_DEBUG` | `debug` | Set `true` to see logs in console and enable connectivity checks. | No |
119
- | `DROPOUT_PRIVACY` | `privacy` | `full` (capture text) or `mask` (metadata only). | No |
126
+ > `[Dropout] 🟢 Online | Project: <Your-Project-ID>`
120
127
 
121
- **Example `.env` file:**
128
+ **Q: I don't see any logs.**
122
129
 
123
- ```bash
124
- DROPOUT_PROJECT_ID="HomeOS"
125
- DROPOUT_API_KEY="dp_live_xyz123..."
126
- DROPOUT_DEBUG="true"
130
+ 1. Check that you called `Dropout.init()`.
131
+ 2. Ensure your `apiKey` and `projectId` are not undefined (log them to check).
132
+ 3. If using Next.js, ensure `instrumentation.ts` is in the correct folder (`src/` if you use it).
127
133
 
128
- ```
134
+ **Q: Does this work with Edge Functions?**
135
+ No. This runtime relies on Node.js core modules (`http`, `https`). It does not support Vercel Edge Runtime or Cloudflare Workers.
129
136
 
130
137
  ---
131
138
 
132
- ## 🌐 Supported Environments
133
-
134
- | Language/Framework | Status | Integration Method |
135
- | --- | --- | --- |
136
- | **Node.js** (v18+) | ✅ Ready | `require('@dropout-ai/runtime')` |
137
- | **Next.js** | ✅ Ready | `instrumentation.ts` |
138
- | **NestJS** | ✅ Ready | `main.ts` import |
139
- | **Python / Java / Go** | 🚧 Beta | Use REST API (see below) |
140
-
141
139
  ### Non-Node.js Usage (REST API)
142
140
 
143
- If you are using Python, Java, or Go, you can manually send interaction logs to our ingestion endpoint.
141
+ If you are using Python, Go, or other languages, you can manually send interaction logs to our ingestion endpoint.
144
142
 
145
143
  **Endpoint:** `POST https://hipughmjlwmwjxzyxfzs.supabase.co/functions/v1/capture-sealed`
144
+ **Headers:** `x-dropout-key: <YOUR_API_KEY>`
146
145
 
147
- **Headers:**
148
-
149
- * `Content-Type: application/json`
150
- * `x-dropout-key: YOUR_API_KEY`
151
-
152
- **Payload:**
153
-
154
- ```json
146
+ json
155
147
  {
156
148
  "project_id": "your_project_id",
157
- "turn_role": "assistant", // or "user"
149
+ "turn_role": "assistant",
158
150
  "content": "AI response text...",
159
- "model": "gpt-4", // optional
160
- "provider": "openai", // optional
161
- "latency_ms": 1250 // optional
151
+ "model": "gpt-4",
152
+ "provider": "openai"
162
153
  }
163
154
 
164
- ```
165
-
166
- ---
167
-
168
- ## ❓ Troubleshooting
169
-
170
- **Q: I don't see any logs in the dashboard.**
171
-
172
- 1. Ensure `DROPOUT_DEBUG="true"` is set.
173
- 2. Check your console for `[Dropout] 🟢 Online: <ProjectID>`.
174
- 3. If using Next.js, ensure you created `instrumentation.ts` in the correct folder (root or `src`).
175
-
176
- **Q: Does this work with Edge Functions (Vercel Edge / Cloudflare)?**
177
- No. This runtime relies on Node.js core modules (`http`, `https`) to capture traffic. It does not currently support Vercel Edge Runtime or Cloudflare Workers. Please ensure your API routes use the Node.js runtime.
178
-
179
- **Q: Will this crash my app if the API is down?**
180
- No. The SDK is built with a "Safety Fuse." If it cannot connect or encounters an error, it fails silently and your application continues running without interruption.
181
-
182
- ---
183
-
184
155
  ### License
185
156
 
186
- MIT
157
+ MIT
158
+
package/package.json CHANGED
@@ -1,12 +1,9 @@
1
1
  {
2
2
  "name": "@dropout-ai/runtime",
3
- "version": "0.4.0",
4
- "description": "Invisible Node.js runtime for understanding behavoiral impact of AI interactions.",
3
+ "version": "0.4.2",
4
+ "description": "Invisible Node.js runtime for understanding behavioral impact of AI interactions.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
7
- "bin": {
8
- "init": "./bin/init.js"
9
- },
10
7
  "scripts": {
11
8
  "test": "echo \"Error: no test specified\" && exit 1"
12
9
  },
@@ -17,7 +14,7 @@
17
14
  "invisible",
18
15
  "observability",
19
16
  "ai",
20
- "behavoiral analysis",
17
+ "behavioral analysis",
21
18
  "ai forensic",
22
19
  "llm",
23
20
  "monitoring",
@@ -30,16 +27,12 @@
30
27
  "url": "git+https://github.com/vaibhavv4re/dropout.git",
31
28
  "directory": "packages/runtime"
32
29
  },
33
- "dependencies": {
34
- "dotenv": "^16.4.5"
35
- },
30
+ "dependencies": {},
36
31
  "exports": {
37
- ".": "./src/index.js",
38
- "./register": "./src/autoload.js"
32
+ ".": "./src/index.js"
39
33
  },
40
34
  "files": [
41
- "src",
42
- "bin"
35
+ "src"
43
36
  ],
44
37
  "publishConfig": {
45
38
  "access": "public"
package/src/index.d.ts CHANGED
@@ -1,33 +1,38 @@
1
+ // packages/runtime/src/index.d.ts
2
+
1
3
  export interface DropoutConfig {
4
+ projectId: string;
5
+ apiKey: string;
6
+ debug?: boolean;
7
+ privacy?: 'full' | 'mask';
8
+ }
9
+
10
+ export default class Dropout {
2
11
  /**
3
- * Your project ID from the Dropout Dashboard.
12
+ * The project ID associated with this instance.
4
13
  */
5
14
  projectId: string;
6
15
 
7
16
  /**
8
- * Your secret API Key (starts with dp_live_...).
17
+ * The API Key used for authentication.
9
18
  */
10
19
  apiKey: string;
11
20
 
12
21
  /**
13
- * Data Privacy Level.
14
- * 'full' - Captures prompts and responses (Default).
15
- * 'mask' - Captures metadata only, redacts text.
22
+ * Enable debug mode for verbose logging.
16
23
  */
17
- privacy?: 'full' | 'mask';
24
+ debug: boolean;
18
25
 
19
26
  /**
20
- * Enable verbose logging for connection debugging.
21
- * Default: false
27
+ * Privacy setting ('full' captures text, 'mask' captures metadata only).
22
28
  */
23
- debug?: boolean;
24
- }
25
-
26
- export default class Dropout {
27
- constructor(config: DropoutConfig);
29
+ privacy: 'full' | 'mask';
28
30
 
29
31
  /**
30
- * Manually log a message to the debug stream.
32
+ * Universal Initialization Method (Idempotent).
33
+ * Safe to call multiple times; will only initialize once.
31
34
  */
32
- log(msg: string, ...args: any[]): void;
35
+ static init(config: DropoutConfig): Dropout;
36
+
37
+ constructor(config: DropoutConfig);
33
38
  }
package/bin/init.js DELETED
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require('fs');
3
- const path = require('path');
4
-
5
- const colors = {
6
- reset: "\x1b[0m",
7
- green: "\x1b[32m",
8
- yellow: "\x1b[33m",
9
- cyan: "\x1b[36m"
10
- };
11
-
12
- const log = (color, msg) => console.log(`${color}${msg}${colors.reset}`);
13
-
14
- function detectFramework() {
15
- const cwd = process.cwd();
16
- if (fs.existsSync(path.resolve(cwd, 'package.json'))) {
17
- const pkg = JSON.parse(fs.readFileSync(path.resolve(cwd, 'package.json'), 'utf-8'));
18
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
19
- if (deps.next) return 'nextjs';
20
- if (deps['@nestjs/core']) return 'nestjs';
21
- return 'node';
22
- }
23
- return 'unknown';
24
- }
25
-
26
- function setupNextJs() {
27
- log(colors.cyan, '🔍 Next.js project detected.');
28
- const hasSrc = fs.existsSync(path.resolve(process.cwd(), 'src'));
29
- const targetDir = hasSrc ? 'src' : '.';
30
- const isTs = fs.existsSync(path.resolve(process.cwd(), 'tsconfig.json'));
31
- const ext = isTs ? 'ts' : 'js';
32
- const filePath = path.resolve(process.cwd(), targetDir, `instrumentation.${ext}`);
33
-
34
- const content = `export async function register() {
35
- if (process.env.NEXT_RUNTIME === 'nodejs') {
36
- await import('@dropout-ai/runtime');
37
- console.log('[Dropout] 🟢 Initialized via instrumentation hook');
38
- }
39
- }`;
40
-
41
- if (fs.existsSync(filePath)) {
42
- log(colors.yellow, `⚠️ File exists: ${filePath}`);
43
- log(colors.yellow, `👉 Please add the register() hook manually.`);
44
- } else {
45
- fs.writeFileSync(filePath, content);
46
- log(colors.green, `✅ Created: ${targetDir}/instrumentation.${ext}`);
47
- }
48
-
49
- log(colors.cyan, '\nNEXT STEP: Add .env keys (DROPOUT_PROJECT_ID, DROPOUT_API_KEY).');
50
- }
51
-
52
- function run() {
53
- console.log(colors.cyan + "\nDropout AI - Init Wizard 🧙‍♂️" + colors.reset);
54
- const framework = detectFramework();
55
-
56
- switch (framework) {
57
- case 'nextjs': setupNextJs(); break;
58
- case 'nestjs':
59
- log(colors.cyan, '🔍 NestJS detected.');
60
- log(colors.green, '👉 Initialize in src/main.ts before bootstrap().');
61
- break;
62
- case 'node':
63
- log(colors.cyan, '🔍 Node/Express detected.');
64
- log(colors.green, '👉 Add require("@dropout-ai/runtime") at the top of index.js.');
65
- break;
66
- default:
67
- log(colors.yellow, '⚠️ Unknown framework. Check docs for manual setup.');
68
- }
69
- }
70
-
71
- run();
package/src/autoload.js DELETED
@@ -1,35 +0,0 @@
1
- // packages/runtime/src/autoload.js
2
- const fs = require('fs');
3
- const path = require('path');
4
- const Dropout = require('./index');
5
-
6
- // 1. Force Load Environment Variables (Fixes the "undefined" error)
7
- try {
8
- const dotenv = require('dotenv');
9
- const cwd = process.cwd();
10
-
11
- // We explicitly look for .env.local first (Next.js standard), then .env
12
- const envFiles = ['.env.local', '.env'];
13
-
14
- envFiles.forEach(file => {
15
- const envPath = path.resolve(cwd, file);
16
- if (fs.existsSync(envPath)) {
17
- dotenv.config({ path: envPath, override: true });
18
- }
19
- });
20
- } catch (e) {
21
- // dotenv might not be installed, ignore if using system env vars
22
- }
23
-
24
- // 2. Initialize Immediately
25
- if (process.env.DROPOUT_PROJECT_ID && process.env.DROPOUT_API_KEY) {
26
- new Dropout({
27
- projectId: process.env.DROPOUT_PROJECT_ID,
28
- apiKey: process.env.DROPOUT_API_KEY,
29
- debug: process.env.DROPOUT_DEBUG === 'true'
30
- });
31
- // Log strictly for debug verification
32
- if (process.env.DROPOUT_DEBUG === 'true') {
33
- console.log(`[Dropout] 🚀 Global Autoload Active: ${process.env.DROPOUT_PROJECT_ID}`);
34
- }
35
- }