@mynitorai/sdk 0.1.1 → 0.1.3

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/dist/index.d.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  */
5
5
  export interface MyNitorConfig {
6
6
  apiKey: string;
7
- environment?: string;
8
7
  endpoint?: string;
9
8
  }
10
9
  export declare class MyNitor {
@@ -17,6 +16,7 @@ export declare class MyNitor {
17
16
  * Automatically detect and wrap AI libraries like OpenAI
18
17
  */
19
18
  instrument(): void;
19
+ private getCallSite;
20
20
  private sendEvent;
21
21
  private wrapOpenAI;
22
22
  }
package/dist/index.js CHANGED
@@ -9,8 +9,7 @@ class MyNitor {
9
9
  constructor(config) {
10
10
  this.isInstrumented = false;
11
11
  this.config = {
12
- environment: 'production',
13
- endpoint: 'https://www.mynitor.ai/api/v1/events',
12
+ endpoint: 'https://app.mynitor.ai/api/v1/events',
14
13
  ...config
15
14
  };
16
15
  }
@@ -30,9 +29,39 @@ class MyNitor {
30
29
  this.isInstrumented = true;
31
30
  console.log('🚀 MyNitor: Auto-instrumentation active.');
32
31
  }
32
+ getCallSite() {
33
+ try {
34
+ const err = new Error();
35
+ const stack = err.stack?.split('\n') || [];
36
+ // Look for the frame that called the LLM method
37
+ // Stack usually: Error -> getCallSite -> wrapOpenAI wrapper -> USER CODE
38
+ // We iterate to find the first frame NOT in MyNitor SDK
39
+ for (const line of stack) {
40
+ if (!line.includes('mynitor') && !line.includes('Error') && line.includes('/')) {
41
+ // Typical format: " at Object.myFunction (/path/to/file.ts:10:5)"
42
+ const match = line.match(/at\s+(?:(.+?)\s+\()?(.*?):(\d+):(\d+)\)?/);
43
+ if (match) {
44
+ const func = match[1] || 'anonymous';
45
+ const fullPath = match[2];
46
+ const filename = fullPath.split('/').pop()?.split('.')[0] || 'unknown';
47
+ return {
48
+ file: fullPath,
49
+ line: parseInt(match[3]),
50
+ functionName: func,
51
+ workflowGuess: `${filename}:${func}`.replace('Object.', '')
52
+ };
53
+ }
54
+ }
55
+ }
56
+ }
57
+ catch (e) {
58
+ // fail safe
59
+ }
60
+ return { file: 'unknown', line: 0, functionName: 'unknown', workflowGuess: 'default-workflow' };
61
+ }
33
62
  async sendEvent(payload) {
34
63
  try {
35
- // Fire and forget - we don't await this to keep the user's app fast
64
+ // Fire and forget
36
65
  fetch(this.config.endpoint, {
37
66
  method: 'POST',
38
67
  headers: {
@@ -41,20 +70,14 @@ class MyNitor {
41
70
  },
42
71
  body: JSON.stringify({
43
72
  ...payload,
44
- environment: this.config.environment,
45
73
  eventVersion: '1.0'
46
74
  })
47
- }).catch(() => {
48
- /* Silently fail to protect the user's production app */
49
- });
50
- }
51
- catch (e) {
52
- /* Silently fail */
75
+ }).catch(() => { });
53
76
  }
77
+ catch (e) { }
54
78
  }
55
79
  wrapOpenAI() {
56
80
  try {
57
- // Detect if OpenAI is installed
58
81
  const OpenAI = require('openai');
59
82
  if (!OpenAI || !OpenAI.OpenAI)
60
83
  return;
@@ -63,14 +86,19 @@ class MyNitor {
63
86
  OpenAI.OpenAI.Chat.Completions.prototype.create = async function (...args) {
64
87
  const start = Date.now();
65
88
  const body = args[0];
89
+ const callsite = self.getCallSite();
66
90
  try {
67
91
  const result = await originalChatCreate.apply(this, args);
68
92
  const end = Date.now();
69
- // Background capture
70
93
  self.sendEvent({
71
94
  requestId: result.id || `req_${Date.now()}`,
72
95
  model: result.model || body.model,
73
96
  provider: 'openai',
97
+ agent: 'default-agent',
98
+ workflow: callsite.workflowGuess,
99
+ file: callsite.file,
100
+ functionName: callsite.functionName,
101
+ lineNumber: callsite.line,
74
102
  inputTokens: result.usage?.prompt_tokens || 0,
75
103
  outputTokens: result.usage?.completion_tokens || 0,
76
104
  latencyMs: end - start,
@@ -84,8 +112,10 @@ class MyNitor {
84
112
  requestId: `err_${Date.now()}`,
85
113
  model: body?.model || 'unknown',
86
114
  provider: 'openai',
87
- inputTokens: 0,
88
- outputTokens: 0,
115
+ agent: 'default-agent',
116
+ workflow: callsite.workflowGuess,
117
+ file: callsite.file,
118
+ functionName: callsite.functionName,
89
119
  latencyMs: end - start,
90
120
  status: 'error',
91
121
  errorType: error?.constructor?.name || 'Error'
@@ -94,11 +124,9 @@ class MyNitor {
94
124
  }
95
125
  };
96
126
  }
97
- catch (e) {
98
- // Library not found or version mismatch - skip silently
99
- }
127
+ catch (e) { }
100
128
  }
101
129
  }
102
130
  exports.MyNitor = MyNitor;
103
- // Global accessor for snippet simplicity
131
+ // Global accessor
104
132
  exports.init = MyNitor.init;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mynitorai/sdk",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Production safety and observability for AI systems.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",