@atlasburn/sdk 1.0.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.
- package/index.ts +137 -0
- package/package.json +20 -0
package/index.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AtlasBurn Forensic SDK - Institutional v1.9
|
|
3
|
+
*
|
|
4
|
+
* DESIGN PRINCIPLE: Non-blocking ingestion via background flush.
|
|
5
|
+
* This SDK wraps any LLM client (OpenAI, Anthropic, etc.) and forwards
|
|
6
|
+
* forensic metadata to the AtlasBurn control plane.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface AtlasBurnSDKOptions {
|
|
10
|
+
apiKey: string; // Raw Ingest Key (Stored in .env)
|
|
11
|
+
projectId: string; // Your AtlasBurn Project ID
|
|
12
|
+
ingestUrl?: string; // The absolute URL of your AtlasBurn deployment
|
|
13
|
+
batchSize?: number;
|
|
14
|
+
maxQueueSize?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AtlasBurnMetadata {
|
|
18
|
+
featureId?: string; // Product feature attribution
|
|
19
|
+
userTier?: string; // Customer segment attribution
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function generateForensicId(): string {
|
|
23
|
+
try {
|
|
24
|
+
if (typeof globalThis !== 'undefined' && globalThis.crypto?.randomUUID) {
|
|
25
|
+
return globalThis.crypto.randomUUID();
|
|
26
|
+
}
|
|
27
|
+
} catch (e) { /* Fallback */ }
|
|
28
|
+
return `abn-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class AtlasBurnIngestor {
|
|
32
|
+
private queue: any[] = [];
|
|
33
|
+
private options: AtlasBurnSDKOptions;
|
|
34
|
+
private isProcessing: boolean = false;
|
|
35
|
+
private maxRetries: number = 3;
|
|
36
|
+
|
|
37
|
+
constructor(options: AtlasBurnSDKOptions) {
|
|
38
|
+
this.options = {
|
|
39
|
+
ingestUrl: options.ingestUrl || (typeof window !== 'undefined'
|
|
40
|
+
? `${window.location.origin}/api/ingest`
|
|
41
|
+
: '/api/ingest'),
|
|
42
|
+
batchSize: 5,
|
|
43
|
+
maxQueueSize: 200,
|
|
44
|
+
...options
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public enqueue(event: any) {
|
|
49
|
+
if (this.queue.length >= (this.options.maxQueueSize || 200)) {
|
|
50
|
+
this.queue.shift();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.queue.push({
|
|
54
|
+
...event,
|
|
55
|
+
eventId: generateForensicId(),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (this.queue.length >= (this.options.batchSize || 5)) {
|
|
59
|
+
this.flush();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public async flush() {
|
|
64
|
+
if (this.isProcessing || this.queue.length === 0) return;
|
|
65
|
+
|
|
66
|
+
this.isProcessing = true;
|
|
67
|
+
const eventsToProcess = [...this.queue];
|
|
68
|
+
this.queue = [];
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
await this.sendWithRetry(eventsToProcess, 0);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.warn('AtlasBurn SDK: Background ingestion failed.', err);
|
|
74
|
+
} finally {
|
|
75
|
+
this.isProcessing = false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private async sendWithRetry(events: any[], attempt: number): Promise<void> {
|
|
80
|
+
try {
|
|
81
|
+
const response = await fetch(this.options.ingestUrl!, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: { 'Content-Type': 'application/json' },
|
|
84
|
+
body: JSON.stringify({
|
|
85
|
+
apiKey: this.options.apiKey,
|
|
86
|
+
projectId: this.options.projectId,
|
|
87
|
+
events: events
|
|
88
|
+
}),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
throw new Error(`AtlasBurn Ingest Failure: Status ${response.status}`);
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
if (attempt < this.maxRetries) {
|
|
96
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
97
|
+
await new Promise(r => setTimeout(r, delay));
|
|
98
|
+
return this.sendWithRetry(events, attempt + 1);
|
|
99
|
+
}
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let globalIngestor: AtlasBurnIngestor | null = null;
|
|
106
|
+
|
|
107
|
+
export function withAtlasBurn(client: any, options: AtlasBurnSDKOptions) {
|
|
108
|
+
if (!globalIngestor) {
|
|
109
|
+
globalIngestor = new AtlasBurnIngestor(options);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
async chat(
|
|
114
|
+
payload: { model: string; messages: any[] } & AtlasBurnMetadata
|
|
115
|
+
): Promise<any> {
|
|
116
|
+
const response = await client.chat(payload);
|
|
117
|
+
const usage = response.usage || { prompt_tokens: 0, completion_tokens: 0 };
|
|
118
|
+
|
|
119
|
+
globalIngestor?.enqueue({
|
|
120
|
+
model: payload.model,
|
|
121
|
+
featureId: payload.featureId || 'default',
|
|
122
|
+
userTier: payload.userTier || 'standard',
|
|
123
|
+
usage: {
|
|
124
|
+
prompt_tokens: usage.prompt_tokens,
|
|
125
|
+
completion_tokens: usage.completion_tokens,
|
|
126
|
+
},
|
|
127
|
+
timestamp: new Date().toISOString(),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return response;
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
async flush() {
|
|
134
|
+
await globalIngestor?.flush();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlasburn/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Institutional Forensic SDK for AI Governance and Burn Monitoring",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"ai",
|
|
12
|
+
"governance",
|
|
13
|
+
"forensics",
|
|
14
|
+
"monitoring",
|
|
15
|
+
"burn",
|
|
16
|
+
"llm"
|
|
17
|
+
],
|
|
18
|
+
"author": "AtlasBurn Institutional",
|
|
19
|
+
"license": "MIT"
|
|
20
|
+
}
|