@dropout-ai/runtime 0.1.0 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +55 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dropout-ai/runtime",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Invisible Node.js runtime for capturing AI interactions.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -40,17 +40,49 @@
40
40
  }
41
41
  }
42
42
 
43
- // 5. The Monkey Patch
43
+ // 5. Detection Helpers
44
+ function matchesKnownProvider(url) {
45
+ return (
46
+ url &&
47
+ (
48
+ url.includes('openai.com/v1') ||
49
+ url.includes('api.anthropic.com') ||
50
+ url.includes('generativelanguage.googleapis.com') ||
51
+ url.includes('api-inference.huggingface.co')
52
+ )
53
+ );
54
+ }
55
+
56
+ function matchesGenericLLMPayload(init) {
57
+ try {
58
+ if (!init || typeof init.body !== 'string') return false;
59
+
60
+ const body = JSON.parse(init.body);
61
+
62
+ // Common LLM request shapes
63
+ return (
64
+ body.messages ||
65
+ body.prompt ||
66
+ body.input
67
+ );
68
+ } catch (e) {
69
+ return false;
70
+ }
71
+ }
72
+
73
+ // 6. The Monkey Patch
44
74
  global.fetch = async function (input, init) {
45
75
  const start = Date.now();
46
76
  const response = await originalFetch(input, init);
47
77
 
48
78
  try {
49
- // 6. Detection Logic (Dumb detection + Config Check)
79
+ // 7. Detection Logic (Dumb detection + Config Check)
50
80
  const url = typeof input === 'string' ? input : (input && input.url);
51
- const isAIProvider = config.enabledProviders.some(p => url && url.includes(`${p}.com/v1`));
81
+ const isLikelyAI =
82
+ matchesKnownProvider(url) ||
83
+ matchesGenericLLMPayload(init);
52
84
 
53
- if (url && isAIProvider) {
85
+ if (url && isLikelyAI) {
54
86
  const latency = Date.now() - start;
55
87
  const contentType = response.headers.get('content-type') || '';
56
88
  const isStream = contentType.includes('text/event-stream');
@@ -80,7 +112,8 @@
80
112
  }
81
113
 
82
114
  const payload = {
83
- provider: 'openai',
115
+ provider: url.includes('openai.com') ? 'openai' : 'unknown',
116
+ confidence: matchesKnownProvider(url) ? 'high' : 'heuristic',
84
117
  url,
85
118
  model,
86
119
  prompt,
@@ -98,4 +131,21 @@
98
131
  };
99
132
 
100
133
  global.fetch.__dropout_patched__ = true;
134
+
135
+ // 10. Manual capture (combo mode)
136
+ if (typeof module !== 'undefined' && module.exports) {
137
+ module.exports.capture = function capture(event) {
138
+ try {
139
+ setTimeout(() => {
140
+ safeSendTelemetry({
141
+ ...event,
142
+ source: 'manual',
143
+ timestamp: Math.floor(Date.now() / 1000)
144
+ });
145
+ }, 0);
146
+ } catch (e) {
147
+ // silent
148
+ }
149
+ };
150
+ }
101
151
  })();