@aui-x/prism 0.0.1 → 0.0.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.
Files changed (56) hide show
  1. package/README.md +8 -10
  2. package/dist/{client-BrZstMQX.d.ts → client-CTcnqw0Y.d.ts} +21 -16
  3. package/dist/client-CTcnqw0Y.d.ts.map +1 -0
  4. package/dist/{client-C7RiAn7a.js → client-CkxOaNy0.js} +56 -25
  5. package/dist/client-CkxOaNy0.js.map +1 -0
  6. package/dist/{client-B9WXHjpz.cjs → client-DWaiEqR5.cjs} +56 -25
  7. package/dist/client-DWaiEqR5.cjs.map +1 -0
  8. package/dist/{client-BSsSpkZY.d.cts → client-DgiofMcL.d.cts} +21 -16
  9. package/dist/client-DgiofMcL.d.cts.map +1 -0
  10. package/dist/core.cjs +1 -1
  11. package/dist/core.d.cts +1 -1
  12. package/dist/core.d.ts +1 -1
  13. package/dist/core.js +1 -1
  14. package/dist/index.cjs +1 -1
  15. package/dist/index.d.cts +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/integrations/ai-sdk.cjs +16 -3
  19. package/dist/integrations/ai-sdk.cjs.map +1 -1
  20. package/dist/integrations/ai-sdk.d.cts +1 -1
  21. package/dist/integrations/ai-sdk.d.cts.map +1 -1
  22. package/dist/integrations/ai-sdk.d.ts +1 -1
  23. package/dist/integrations/ai-sdk.d.ts.map +1 -1
  24. package/dist/integrations/ai-sdk.js +16 -3
  25. package/dist/integrations/ai-sdk.js.map +1 -1
  26. package/dist/integrations/anthropic.cjs +11 -84
  27. package/dist/integrations/anthropic.cjs.map +1 -1
  28. package/dist/integrations/anthropic.d.cts +1 -1
  29. package/dist/integrations/anthropic.d.cts.map +1 -1
  30. package/dist/integrations/anthropic.d.ts +1 -1
  31. package/dist/integrations/anthropic.d.ts.map +1 -1
  32. package/dist/integrations/anthropic.js +5 -77
  33. package/dist/integrations/anthropic.js.map +1 -1
  34. package/dist/integrations/openai.cjs +13 -82
  35. package/dist/integrations/openai.cjs.map +1 -1
  36. package/dist/integrations/openai.d.cts +1 -1
  37. package/dist/integrations/openai.d.cts.map +1 -1
  38. package/dist/integrations/openai.d.ts +1 -1
  39. package/dist/integrations/openai.d.ts.map +1 -1
  40. package/dist/integrations/openai.js +6 -74
  41. package/dist/integrations/openai.js.map +1 -1
  42. package/dist/shared-CcAuQvBc.js +85 -0
  43. package/dist/shared-CcAuQvBc.js.map +1 -0
  44. package/dist/shared-Do8YbTDV.cjs +115 -0
  45. package/dist/shared-Do8YbTDV.cjs.map +1 -0
  46. package/dist/{wrapper-ByspXfxS.cjs → wrapper-3UjPvXBN.cjs} +16 -86
  47. package/dist/wrapper-3UjPvXBN.cjs.map +1 -0
  48. package/dist/{wrapper-7jRyp54U.js → wrapper-Czc4CgC-.js} +8 -78
  49. package/dist/wrapper-Czc4CgC-.js.map +1 -0
  50. package/package.json +1 -1
  51. package/dist/client-B9WXHjpz.cjs.map +0 -1
  52. package/dist/client-BSsSpkZY.d.cts.map +0 -1
  53. package/dist/client-BrZstMQX.d.ts.map +0 -1
  54. package/dist/client-C7RiAn7a.js.map +0 -1
  55. package/dist/wrapper-7jRyp54U.js.map +0 -1
  56. package/dist/wrapper-ByspXfxS.cjs.map +0 -1
package/README.md CHANGED
@@ -41,15 +41,19 @@ const { text, usage } = await generateText({
41
41
  prompt: "Hello!",
42
42
  });
43
43
 
44
+ // Token usage is captured automatically from spans — just call end():
45
+ await traced.end();
46
+
47
+ // Or pass explicit values to override:
44
48
  await traced.end({
45
49
  output: text,
46
50
  totalTokens: usage.totalTokens,
47
- promptTokens: usage.inputTokens,
48
- completionTokens: usage.outputTokens,
51
+ inputTokens: usage.inputTokens,
52
+ outputTokens: usage.outputTokens,
49
53
  });
50
54
  ```
51
55
 
52
- Multi-step tool use is handled correctly — each LLM call becomes a child span under the root trace:
56
+ Multi-step tool use is handled correctly — each LLM call becomes a child span under the root trace, and token usage is automatically aggregated:
53
57
 
54
58
  ```ts
55
59
  import { streamText, stepCountIs } from "ai";
@@ -70,13 +74,7 @@ for await (const chunk of result.textStream) {
70
74
  process.stdout.write(chunk);
71
75
  }
72
76
 
73
- const usage = await result.usage;
74
- await traced.end({
75
- output: await result.text,
76
- totalTokens: usage.totalTokens,
77
- promptTokens: usage.inputTokens,
78
- completionTokens: usage.outputTokens,
79
- });
77
+ await traced.end();
80
78
  ```
81
79
 
82
80
  ### OpenAI
@@ -7,7 +7,7 @@ interface AuixPrismConfig {
7
7
  /** Custom transport — bypasses HTTP when provided. */
8
8
  transport?: (events: TraceEvent[]) => Promise<void>;
9
9
  /** Called when a flush fails after retry. */
10
- onFlushError?: (error: unknown) => void;
10
+ onFlushError?: (error: unknown, events: TraceEvent[]) => void;
11
11
  }
12
12
  interface TraceOptions {
13
13
  name: string;
@@ -25,10 +25,11 @@ interface TraceEndOptions {
25
25
  output?: string;
26
26
  status?: "completed" | "error";
27
27
  totalTokens?: number;
28
- promptTokens?: number;
29
- completionTokens?: number;
28
+ inputTokens?: number;
29
+ outputTokens?: number;
30
30
  }
31
31
  type TraceEvent = {
32
+ v: 1;
32
33
  type: "trace.start";
33
34
  traceId: string;
34
35
  name?: string;
@@ -42,18 +43,20 @@ type TraceEvent = {
42
43
  sessionId?: string;
43
44
  startedAt: string;
44
45
  } | {
46
+ v: 1;
45
47
  type: "trace.end";
46
48
  traceId: string;
47
49
  output?: unknown;
48
50
  status: "completed" | "error";
49
51
  error?: string;
50
52
  totalTokens?: number;
51
- promptTokens?: number;
52
- completionTokens?: number;
53
+ inputTokens?: number;
54
+ outputTokens?: number;
53
55
  ttftMs?: number;
54
56
  latencyMs?: number;
55
57
  endedAt: string;
56
58
  } | {
59
+ v: 1;
57
60
  type: "span.start";
58
61
  traceId: string;
59
62
  spanId: string;
@@ -66,6 +69,7 @@ type TraceEvent = {
66
69
  metadata?: Record<string, unknown>;
67
70
  startedAt: string;
68
71
  } | {
72
+ v: 1;
69
73
  type: "span.end";
70
74
  traceId: string;
71
75
  spanId: string;
@@ -73,8 +77,8 @@ type TraceEvent = {
73
77
  status: "completed" | "error";
74
78
  error?: string;
75
79
  totalTokens?: number;
76
- promptTokens?: number;
77
- completionTokens?: number;
80
+ inputTokens?: number;
81
+ outputTokens?: number;
78
82
  ttftMs?: number;
79
83
  latencyMs?: number;
80
84
  endedAt: string;
@@ -91,6 +95,7 @@ declare class AuixPrism {
91
95
  private events;
92
96
  private timer;
93
97
  private _flushChain;
98
+ private destroyed;
94
99
  constructor(config: AuixPrismConfig);
95
100
  enqueue(event: TraceEvent): void;
96
101
  flush(): Promise<void>;
@@ -118,8 +123,8 @@ declare class AuixPrism {
118
123
  declare class TraceHandle {
119
124
  private tracer;
120
125
  readonly traceId: string;
121
- private startedAt;
122
- constructor(tracer: AuixPrism, traceId: string, startedAt: string);
126
+ private startMs;
127
+ constructor(tracer: AuixPrism, traceId: string);
123
128
  startSpan(opts: {
124
129
  name: string;
125
130
  type: "llm" | "tool" | "retrieval" | "custom";
@@ -131,8 +136,8 @@ declare class TraceHandle {
131
136
  status?: "completed" | "error";
132
137
  error?: string;
133
138
  totalTokens?: number;
134
- promptTokens?: number;
135
- completionTokens?: number;
139
+ inputTokens?: number;
140
+ outputTokens?: number;
136
141
  ttftMs?: number;
137
142
  }): void;
138
143
  }
@@ -140,18 +145,18 @@ declare class SpanHandle {
140
145
  private tracer;
141
146
  private traceId;
142
147
  readonly spanId: string;
143
- private startedAt;
144
- constructor(tracer: AuixPrism, traceId: string, spanId: string, startedAt: string);
148
+ private startMs;
149
+ constructor(tracer: AuixPrism, traceId: string, spanId: string);
145
150
  end(opts?: {
146
151
  output?: unknown;
147
152
  status?: "completed" | "error";
148
153
  error?: string;
149
154
  totalTokens?: number;
150
- promptTokens?: number;
151
- completionTokens?: number;
155
+ inputTokens?: number;
156
+ outputTokens?: number;
152
157
  ttftMs?: number;
153
158
  }): void;
154
159
  }
155
160
  //#endregion
156
161
  export { TraceEndOptions as a, TraceResult as c, AuixPrismConfig as i, SpanHandle as n, TraceEvent as o, TraceHandle as r, TraceOptions as s, AuixPrism as t };
157
- //# sourceMappingURL=client-BrZstMQX.d.ts.map
162
+ //# sourceMappingURL=client-CTcnqw0Y.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-CTcnqw0Y.d.ts","names":[],"sources":["../src/types.ts","../src/client.ts"],"mappings":";UAAiB,eAAA;EACf,MAAA;EACA,OAAA;EACA,OAAA;EACA,SAAA;EAEsC;EAAtC,SAAA,IAAa,MAAA,EAAQ,UAAA,OAAiB,OAAA;EAEY;EAAlD,YAAA,IAAgB,KAAA,WAAgB,MAAA,EAAQ,UAAA;AAAA;AAAA,UAGzB,YAAA;EACf,IAAA;EACA,KAAA;EACA,QAAA;EACA,SAAA;EACA,IAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,WAAA;EACf,KAAA,EAD0B,WAAA;EAE1B,MAAA,GAAS,IAAA,GAAO,eAAA,KAAoB,OAAA;AAAA;AAAA,UAGrB,eAAA;EACf,MAAA;EACA,MAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;AAAA;AAAA,KAGU,UAAA;EAEN,CAAA;EACA,IAAA;EACA,OAAA;EACA,IAAA;EACA,KAAA;EACA,KAAA;EACA,QAAA;EACA,SAAA;EACA,QAAA,GAAW,MAAA;EACX,IAAA;EACA,OAAA;EACA,SAAA;EACA,SAAA;AAAA;EAGA,CAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA;EACA,MAAA;EACA,KAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,MAAA;EACA,SAAA;EACA,OAAA;AAAA;EAGA,CAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA;EACA,YAAA;EACA,IAAA;EACA,QAAA;EACA,KAAA;EACA,KAAA;EACA,QAAA;EACA,QAAA,GAAW,MAAA;EACX,SAAA;AAAA;EAGA,CAAA;EACA,IAAA;EACA,OAAA;EACA,MAAA;EACA,MAAA;EACA,MAAA;EACA,KAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,MAAA;EACA,SAAA;EACA,OAAA;AAAA;;;cCpEO,SAAA;EAAA,QACH,MAAA;EAAA,QACA,OAAA;EAAA,QACA,OAAA;EAAA,QACA,SAAA;EAAA,QACA,SAAA;EAAA,QACA,YAAA;EAAA,QACA,MAAA;EAAA,QACA,KAAA;EAAA,QACA,WAAA;EAAA,QACA,SAAA;cAEI,MAAA,EAAQ,eAAA;EAUpB,OAAA,CAAQ,KAAA,EAAO,UAAA;EAWf,KAAA,CAAA,GAAS,OAAA;EAmCT,UAAA,CAAW,IAAA;IACT,IAAA;IACA,KAAA;IACA,KAAA;IACA,QAAA;IACA,SAAA;IACA,QAAA,GAAW,MAAA;IACX,IAAA;EAAA,IACE,WAAA;EAuBJ,gBAAA,CACE,OAAA,UACA,IAAA;IACE,IAAA;IACA,IAAA;IACA,KAAA;IACA,KAAA;IACA,QAAA;IACA,YAAA;IACA,QAAA,GAAW,MAAA;EAAA,IAEZ,UAAA;EAsBH,KAAA,CAAM,IAAA,EAAM,YAAA,GAAe,WAAA;EAS3B,OAAA,CAAA,GAAW,OAAA;AAAA;AAAA,cAOA,WAAA;EAAA,QAID,MAAA;EAAA,SACC,OAAA;EAAA,QAJH,OAAA;cAGE,MAAA,EAAQ,SAAA,EACP,OAAA;EAGX,SAAA,CAAU,IAAA;IACR,IAAA;IACA,IAAA;IACA,KAAA;IACA,KAAA;EAAA,IACE,UAAA;EAmBJ,GAAA,CAAI,IAAA;IACF,MAAA;IACA,MAAA;IACA,KAAA;IACA,WAAA;IACA,WAAA;IACA,YAAA;IACA,MAAA;EAAA;AAAA;AAAA,cAsBS,UAAA;EAAA,QAID,MAAA;EAAA,QACA,OAAA;EAAA,SACC,MAAA;EAAA,QALH,OAAA;cAGE,MAAA,EAAQ,SAAA,EACR,OAAA,UACC,MAAA;EAGX,GAAA,CAAI,IAAA;IACF,MAAA;IACA,MAAA;IACA,KAAA;IACA,WAAA;IACA,WAAA;IACA,YAAA;IACA,MAAA;EAAA;AAAA"}
@@ -1,9 +1,15 @@
1
1
  //#region src/utils.ts
2
2
  const CHARS = "0123456789abcdefghjkmnpqrstvwxyz";
3
- function ulid() {
3
+ function generateId() {
4
4
  const ts = Date.now().toString(36);
5
5
  let rand = "";
6
- for (let i = 0; i < 16; i++) rand += CHARS[Math.floor(Math.random() * 32)];
6
+ const bytes = new Uint8Array(16);
7
+ try {
8
+ crypto.getRandomValues(bytes);
9
+ } catch {
10
+ for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);
11
+ }
12
+ for (let i = 0; i < 16; i++) rand += CHARS[bytes[i] % 32];
7
13
  return ts + rand;
8
14
  }
9
15
  function nowISO() {
@@ -14,10 +20,19 @@ function nowISO() {
14
20
  //#region src/client.ts
15
21
  const FLUSH_INTERVAL_MS = 1e3;
16
22
  const FLUSH_BATCH_SIZE = 10;
23
+ const MAX_BUFFER = 1e3;
24
+ const SDK_VERSION = "0.0.1";
25
+ function normalizeModel(model) {
26
+ return model?.trim();
27
+ }
28
+ function normalizeProvider(provider) {
29
+ return provider?.trim().toLowerCase();
30
+ }
17
31
  var AuixPrism = class {
18
32
  constructor(config) {
19
33
  this.events = [];
20
34
  this._flushChain = Promise.resolve();
35
+ this.destroyed = false;
21
36
  this.apiKey = config.apiKey;
22
37
  this.baseUrl = config.baseUrl ?? "https://api.auix.dev";
23
38
  this.project = config.project;
@@ -27,6 +42,10 @@ var AuixPrism = class {
27
42
  this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
28
43
  }
29
44
  enqueue(event) {
45
+ if (this.destroyed) {
46
+ console.warn("[@auix/prism] enqueue called after destroy");
47
+ return;
48
+ }
30
49
  this.events.push(event);
31
50
  if (this.events.length >= FLUSH_BATCH_SIZE) this.flush();
32
51
  }
@@ -41,25 +60,32 @@ var AuixPrism = class {
41
60
  "Content-Type": "application/json",
42
61
  Authorization: `Bearer ${this.apiKey}`
43
62
  },
44
- body: JSON.stringify({ events: batch })
63
+ body: JSON.stringify({
64
+ v: 1,
65
+ sdk: SDK_VERSION,
66
+ events: batch
67
+ })
45
68
  }).then(() => {});
46
69
  };
47
70
  this._flushChain = this._flushChain.then(() => send().catch(() => send().catch((err) => {
48
71
  console.warn("[@auix/prism] flush failed after retry", err);
49
- this.onFlushError?.(err);
72
+ this.events.unshift(...batch);
73
+ if (this.events.length > MAX_BUFFER) this.events.length = MAX_BUFFER;
74
+ this.onFlushError?.(err, batch);
50
75
  })));
51
76
  return this._flushChain;
52
77
  }
53
78
  startTrace(opts) {
54
- const traceId = ulid();
79
+ const traceId = generateId();
55
80
  const startedAt = nowISO();
56
81
  this.enqueue({
82
+ v: 1,
57
83
  type: "trace.start",
58
84
  traceId,
59
85
  name: opts.name,
60
86
  input: opts.input,
61
- model: opts.model,
62
- provider: opts.provider,
87
+ model: normalizeModel(opts.model),
88
+ provider: normalizeProvider(opts.provider),
63
89
  endUserId: opts.endUserId,
64
90
  metadata: opts.metadata,
65
91
  tags: opts.tags,
@@ -67,12 +93,13 @@ var AuixPrism = class {
67
93
  sessionId: this.sessionId,
68
94
  startedAt
69
95
  });
70
- return new TraceHandle(this, traceId, startedAt);
96
+ return new TraceHandle(this, traceId);
71
97
  }
72
98
  startSpanOnTrace(traceId, opts) {
73
- const spanId = ulid();
99
+ const spanId = generateId();
74
100
  const startedAt = nowISO();
75
101
  this.enqueue({
102
+ v: 1,
76
103
  type: "span.start",
77
104
  traceId,
78
105
  spanId,
@@ -80,12 +107,12 @@ var AuixPrism = class {
80
107
  name: opts.name,
81
108
  spanType: opts.type,
82
109
  input: opts.input,
83
- model: opts.model,
84
- provider: opts.provider,
110
+ model: normalizeModel(opts.model),
111
+ provider: normalizeProvider(opts.provider),
85
112
  metadata: opts.metadata,
86
113
  startedAt
87
114
  });
88
- return new SpanHandle(this, traceId, spanId, startedAt);
115
+ return new SpanHandle(this, traceId, spanId);
89
116
  }
90
117
  trace(opts) {
91
118
  const traceHandle = this.startTrace(opts);
@@ -99,20 +126,22 @@ var AuixPrism = class {
99
126
  };
100
127
  }
101
128
  destroy() {
129
+ this.destroyed = true;
102
130
  clearInterval(this.timer);
103
131
  return this.flush();
104
132
  }
105
133
  };
106
134
  var TraceHandle = class {
107
- constructor(tracer, traceId, startedAt) {
135
+ constructor(tracer, traceId) {
108
136
  this.tracer = tracer;
109
137
  this.traceId = traceId;
110
- this.startedAt = startedAt;
138
+ this.startMs = Date.now();
111
139
  }
112
140
  startSpan(opts) {
113
- const spanId = ulid();
141
+ const spanId = generateId();
114
142
  const startedAt = nowISO();
115
143
  this.tracer.enqueue({
144
+ v: 1,
116
145
  type: "span.start",
117
146
  traceId: this.traceId,
118
147
  spanId,
@@ -122,20 +151,21 @@ var TraceHandle = class {
122
151
  model: opts.model,
123
152
  startedAt
124
153
  });
125
- return new SpanHandle(this.tracer, this.traceId, spanId, startedAt);
154
+ return new SpanHandle(this.tracer, this.traceId, spanId);
126
155
  }
127
156
  end(opts) {
128
157
  const endedAt = nowISO();
129
- const latencyMs = new Date(endedAt).getTime() - new Date(this.startedAt).getTime();
158
+ const latencyMs = Date.now() - this.startMs;
130
159
  this.tracer.enqueue({
160
+ v: 1,
131
161
  type: "trace.end",
132
162
  traceId: this.traceId,
133
163
  output: opts?.output,
134
164
  status: opts?.status ?? "completed",
135
165
  error: opts?.error,
136
166
  totalTokens: opts?.totalTokens,
137
- promptTokens: opts?.promptTokens,
138
- completionTokens: opts?.completionTokens,
167
+ inputTokens: opts?.inputTokens,
168
+ outputTokens: opts?.outputTokens,
139
169
  ttftMs: opts?.ttftMs,
140
170
  latencyMs,
141
171
  endedAt
@@ -143,16 +173,17 @@ var TraceHandle = class {
143
173
  }
144
174
  };
145
175
  var SpanHandle = class {
146
- constructor(tracer, traceId, spanId, startedAt) {
176
+ constructor(tracer, traceId, spanId) {
147
177
  this.tracer = tracer;
148
178
  this.traceId = traceId;
149
179
  this.spanId = spanId;
150
- this.startedAt = startedAt;
180
+ this.startMs = Date.now();
151
181
  }
152
182
  end(opts) {
153
183
  const endedAt = nowISO();
154
- const latencyMs = new Date(endedAt).getTime() - new Date(this.startedAt).getTime();
184
+ const latencyMs = Date.now() - this.startMs;
155
185
  this.tracer.enqueue({
186
+ v: 1,
156
187
  type: "span.end",
157
188
  traceId: this.traceId,
158
189
  spanId: this.spanId,
@@ -160,8 +191,8 @@ var SpanHandle = class {
160
191
  status: opts?.status ?? "completed",
161
192
  error: opts?.error,
162
193
  totalTokens: opts?.totalTokens,
163
- promptTokens: opts?.promptTokens,
164
- completionTokens: opts?.completionTokens,
194
+ inputTokens: opts?.inputTokens,
195
+ outputTokens: opts?.outputTokens,
165
196
  ttftMs: opts?.ttftMs,
166
197
  latencyMs,
167
198
  endedAt
@@ -171,4 +202,4 @@ var SpanHandle = class {
171
202
 
172
203
  //#endregion
173
204
  export { SpanHandle as n, TraceHandle as r, AuixPrism as t };
174
- //# sourceMappingURL=client-C7RiAn7a.js.map
205
+ //# sourceMappingURL=client-CkxOaNy0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-CkxOaNy0.js","names":[],"sources":["../src/utils.ts","../src/client.ts"],"sourcesContent":["const CHARS = \"0123456789abcdefghjkmnpqrstvwxyz\";\n\nexport function generateId(): string {\n const ts = Date.now().toString(36);\n let rand = \"\";\n const bytes = new Uint8Array(16);\n try {\n crypto.getRandomValues(bytes);\n } catch {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n for (let i = 0; i < 16; i++) {\n rand += CHARS[bytes[i] % CHARS.length];\n }\n return ts + rand;\n}\n\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n","import type {\n AuixPrismConfig,\n TraceEndOptions,\n TraceEvent,\n TraceOptions,\n TraceResult,\n} from \"./types\";\nimport { generateId, nowISO } from \"./utils\";\n\nconst FLUSH_INTERVAL_MS = 1000;\nconst FLUSH_BATCH_SIZE = 10;\nconst MAX_BUFFER = 1000;\nconst SDK_VERSION = \"0.0.1\";\n\nfunction normalizeModel(model?: string): string | undefined {\n return model?.trim();\n}\n\nfunction normalizeProvider(provider?: string): string | undefined {\n return provider?.trim().toLowerCase();\n}\n\nexport class AuixPrism {\n private apiKey: string;\n private baseUrl: string;\n private project?: string;\n private sessionId?: string;\n private transport?: (events: TraceEvent[]) => Promise<void>;\n private onFlushError?: (error: unknown, events: TraceEvent[]) => void;\n private events: TraceEvent[] = [];\n private timer: ReturnType<typeof setInterval>;\n private _flushChain: Promise<void> = Promise.resolve();\n private destroyed = false;\n\n constructor(config: AuixPrismConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl ?? \"https://api.auix.dev\";\n this.project = config.project;\n this.sessionId = config.sessionId;\n this.transport = config.transport;\n this.onFlushError = config.onFlushError;\n this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);\n }\n\n enqueue(event: TraceEvent): void {\n if (this.destroyed) {\n console.warn(\"[@auix/prism] enqueue called after destroy\");\n return;\n }\n this.events.push(event);\n if (this.events.length >= FLUSH_BATCH_SIZE) {\n this.flush();\n }\n }\n\n flush(): Promise<void> {\n if (this.events.length === 0) return this._flushChain;\n\n const batch = this.events.splice(0);\n const send = () => {\n if (this.transport) return this.transport(batch);\n return fetch(`${this.baseUrl}/v1/prism/ingest`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n v: 1,\n sdk: SDK_VERSION,\n events: batch,\n }),\n }).then(() => {});\n };\n\n this._flushChain = this._flushChain.then(() =>\n send().catch(() =>\n send().catch((err) => {\n console.warn(\"[@auix/prism] flush failed after retry\", err);\n this.events.unshift(...batch);\n if (this.events.length > MAX_BUFFER) {\n this.events.length = MAX_BUFFER;\n }\n this.onFlushError?.(err, batch);\n }),\n ),\n );\n return this._flushChain;\n }\n\n startTrace(opts: {\n name?: string;\n input?: unknown;\n model?: string;\n provider?: string;\n endUserId?: string;\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): TraceHandle {\n const traceId = generateId();\n const startedAt = nowISO();\n\n this.enqueue({\n v: 1,\n type: \"trace.start\",\n traceId,\n name: opts.name,\n input: opts.input,\n model: normalizeModel(opts.model),\n provider: normalizeProvider(opts.provider),\n endUserId: opts.endUserId,\n metadata: opts.metadata,\n tags: opts.tags,\n project: this.project,\n sessionId: this.sessionId,\n startedAt,\n });\n\n return new TraceHandle(this, traceId);\n }\n\n startSpanOnTrace(\n traceId: string,\n opts: {\n name: string;\n type: \"llm\" | \"tool\" | \"retrieval\" | \"custom\";\n input?: unknown;\n model?: string;\n provider?: string;\n parentSpanId?: string;\n metadata?: Record<string, unknown>;\n },\n ): SpanHandle {\n const spanId = generateId();\n const startedAt = nowISO();\n\n this.enqueue({\n v: 1,\n type: \"span.start\",\n traceId,\n spanId,\n parentSpanId: opts.parentSpanId,\n name: opts.name,\n spanType: opts.type,\n input: opts.input,\n model: normalizeModel(opts.model),\n provider: normalizeProvider(opts.provider),\n metadata: opts.metadata,\n startedAt,\n });\n\n return new SpanHandle(this, traceId, spanId);\n }\n\n trace(opts: TraceOptions): TraceResult {\n const traceHandle = this.startTrace(opts);\n const finish = async (endOpts?: TraceEndOptions) => {\n traceHandle.end(endOpts);\n await this.destroy();\n };\n return { trace: traceHandle, finish };\n }\n\n destroy(): Promise<void> {\n this.destroyed = true;\n clearInterval(this.timer);\n return this.flush();\n }\n}\n\nexport class TraceHandle {\n private startMs = Date.now();\n\n constructor(\n private tracer: AuixPrism,\n readonly traceId: string,\n ) {}\n\n startSpan(opts: {\n name: string;\n type: \"llm\" | \"tool\" | \"retrieval\" | \"custom\";\n input?: unknown;\n model?: string;\n }): SpanHandle {\n const spanId = generateId();\n const startedAt = nowISO();\n\n this.tracer.enqueue({\n v: 1,\n type: \"span.start\",\n traceId: this.traceId,\n spanId,\n name: opts.name,\n spanType: opts.type,\n input: opts.input,\n model: opts.model,\n startedAt,\n });\n\n return new SpanHandle(this.tracer, this.traceId, spanId);\n }\n\n end(opts?: {\n output?: unknown;\n status?: \"completed\" | \"error\";\n error?: string;\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n ttftMs?: number;\n }): void {\n const endedAt = nowISO();\n const latencyMs = Date.now() - this.startMs;\n\n this.tracer.enqueue({\n v: 1,\n type: \"trace.end\",\n traceId: this.traceId,\n output: opts?.output,\n status: opts?.status ?? \"completed\",\n error: opts?.error,\n totalTokens: opts?.totalTokens,\n inputTokens: opts?.inputTokens,\n outputTokens: opts?.outputTokens,\n ttftMs: opts?.ttftMs,\n latencyMs,\n endedAt,\n });\n }\n}\n\nexport class SpanHandle {\n private startMs = Date.now();\n\n constructor(\n private tracer: AuixPrism,\n private traceId: string,\n readonly spanId: string,\n ) {}\n\n end(opts?: {\n output?: unknown;\n status?: \"completed\" | \"error\";\n error?: string;\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n ttftMs?: number;\n }): void {\n const endedAt = nowISO();\n const latencyMs = Date.now() - this.startMs;\n\n this.tracer.enqueue({\n v: 1,\n type: \"span.end\",\n traceId: this.traceId,\n spanId: this.spanId,\n output: opts?.output,\n status: opts?.status ?? \"completed\",\n error: opts?.error,\n totalTokens: opts?.totalTokens,\n inputTokens: opts?.inputTokens,\n outputTokens: opts?.outputTokens,\n ttftMs: opts?.ttftMs,\n latencyMs,\n endedAt,\n });\n }\n}\n"],"mappings":"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"}
@@ -1,10 +1,16 @@
1
1
 
2
2
  //#region src/utils.ts
3
3
  const CHARS = "0123456789abcdefghjkmnpqrstvwxyz";
4
- function ulid() {
4
+ function generateId() {
5
5
  const ts = Date.now().toString(36);
6
6
  let rand = "";
7
- for (let i = 0; i < 16; i++) rand += CHARS[Math.floor(Math.random() * 32)];
7
+ const bytes = new Uint8Array(16);
8
+ try {
9
+ crypto.getRandomValues(bytes);
10
+ } catch {
11
+ for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256);
12
+ }
13
+ for (let i = 0; i < 16; i++) rand += CHARS[bytes[i] % 32];
8
14
  return ts + rand;
9
15
  }
10
16
  function nowISO() {
@@ -15,10 +21,19 @@ function nowISO() {
15
21
  //#region src/client.ts
16
22
  const FLUSH_INTERVAL_MS = 1e3;
17
23
  const FLUSH_BATCH_SIZE = 10;
24
+ const MAX_BUFFER = 1e3;
25
+ const SDK_VERSION = "0.0.1";
26
+ function normalizeModel(model) {
27
+ return model?.trim();
28
+ }
29
+ function normalizeProvider(provider) {
30
+ return provider?.trim().toLowerCase();
31
+ }
18
32
  var AuixPrism = class {
19
33
  constructor(config) {
20
34
  this.events = [];
21
35
  this._flushChain = Promise.resolve();
36
+ this.destroyed = false;
22
37
  this.apiKey = config.apiKey;
23
38
  this.baseUrl = config.baseUrl ?? "https://api.auix.dev";
24
39
  this.project = config.project;
@@ -28,6 +43,10 @@ var AuixPrism = class {
28
43
  this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
29
44
  }
30
45
  enqueue(event) {
46
+ if (this.destroyed) {
47
+ console.warn("[@auix/prism] enqueue called after destroy");
48
+ return;
49
+ }
31
50
  this.events.push(event);
32
51
  if (this.events.length >= FLUSH_BATCH_SIZE) this.flush();
33
52
  }
@@ -42,25 +61,32 @@ var AuixPrism = class {
42
61
  "Content-Type": "application/json",
43
62
  Authorization: `Bearer ${this.apiKey}`
44
63
  },
45
- body: JSON.stringify({ events: batch })
64
+ body: JSON.stringify({
65
+ v: 1,
66
+ sdk: SDK_VERSION,
67
+ events: batch
68
+ })
46
69
  }).then(() => {});
47
70
  };
48
71
  this._flushChain = this._flushChain.then(() => send().catch(() => send().catch((err) => {
49
72
  console.warn("[@auix/prism] flush failed after retry", err);
50
- this.onFlushError?.(err);
73
+ this.events.unshift(...batch);
74
+ if (this.events.length > MAX_BUFFER) this.events.length = MAX_BUFFER;
75
+ this.onFlushError?.(err, batch);
51
76
  })));
52
77
  return this._flushChain;
53
78
  }
54
79
  startTrace(opts) {
55
- const traceId = ulid();
80
+ const traceId = generateId();
56
81
  const startedAt = nowISO();
57
82
  this.enqueue({
83
+ v: 1,
58
84
  type: "trace.start",
59
85
  traceId,
60
86
  name: opts.name,
61
87
  input: opts.input,
62
- model: opts.model,
63
- provider: opts.provider,
88
+ model: normalizeModel(opts.model),
89
+ provider: normalizeProvider(opts.provider),
64
90
  endUserId: opts.endUserId,
65
91
  metadata: opts.metadata,
66
92
  tags: opts.tags,
@@ -68,12 +94,13 @@ var AuixPrism = class {
68
94
  sessionId: this.sessionId,
69
95
  startedAt
70
96
  });
71
- return new TraceHandle(this, traceId, startedAt);
97
+ return new TraceHandle(this, traceId);
72
98
  }
73
99
  startSpanOnTrace(traceId, opts) {
74
- const spanId = ulid();
100
+ const spanId = generateId();
75
101
  const startedAt = nowISO();
76
102
  this.enqueue({
103
+ v: 1,
77
104
  type: "span.start",
78
105
  traceId,
79
106
  spanId,
@@ -81,12 +108,12 @@ var AuixPrism = class {
81
108
  name: opts.name,
82
109
  spanType: opts.type,
83
110
  input: opts.input,
84
- model: opts.model,
85
- provider: opts.provider,
111
+ model: normalizeModel(opts.model),
112
+ provider: normalizeProvider(opts.provider),
86
113
  metadata: opts.metadata,
87
114
  startedAt
88
115
  });
89
- return new SpanHandle(this, traceId, spanId, startedAt);
116
+ return new SpanHandle(this, traceId, spanId);
90
117
  }
91
118
  trace(opts) {
92
119
  const traceHandle = this.startTrace(opts);
@@ -100,20 +127,22 @@ var AuixPrism = class {
100
127
  };
101
128
  }
102
129
  destroy() {
130
+ this.destroyed = true;
103
131
  clearInterval(this.timer);
104
132
  return this.flush();
105
133
  }
106
134
  };
107
135
  var TraceHandle = class {
108
- constructor(tracer, traceId, startedAt) {
136
+ constructor(tracer, traceId) {
109
137
  this.tracer = tracer;
110
138
  this.traceId = traceId;
111
- this.startedAt = startedAt;
139
+ this.startMs = Date.now();
112
140
  }
113
141
  startSpan(opts) {
114
- const spanId = ulid();
142
+ const spanId = generateId();
115
143
  const startedAt = nowISO();
116
144
  this.tracer.enqueue({
145
+ v: 1,
117
146
  type: "span.start",
118
147
  traceId: this.traceId,
119
148
  spanId,
@@ -123,20 +152,21 @@ var TraceHandle = class {
123
152
  model: opts.model,
124
153
  startedAt
125
154
  });
126
- return new SpanHandle(this.tracer, this.traceId, spanId, startedAt);
155
+ return new SpanHandle(this.tracer, this.traceId, spanId);
127
156
  }
128
157
  end(opts) {
129
158
  const endedAt = nowISO();
130
- const latencyMs = new Date(endedAt).getTime() - new Date(this.startedAt).getTime();
159
+ const latencyMs = Date.now() - this.startMs;
131
160
  this.tracer.enqueue({
161
+ v: 1,
132
162
  type: "trace.end",
133
163
  traceId: this.traceId,
134
164
  output: opts?.output,
135
165
  status: opts?.status ?? "completed",
136
166
  error: opts?.error,
137
167
  totalTokens: opts?.totalTokens,
138
- promptTokens: opts?.promptTokens,
139
- completionTokens: opts?.completionTokens,
168
+ inputTokens: opts?.inputTokens,
169
+ outputTokens: opts?.outputTokens,
140
170
  ttftMs: opts?.ttftMs,
141
171
  latencyMs,
142
172
  endedAt
@@ -144,16 +174,17 @@ var TraceHandle = class {
144
174
  }
145
175
  };
146
176
  var SpanHandle = class {
147
- constructor(tracer, traceId, spanId, startedAt) {
177
+ constructor(tracer, traceId, spanId) {
148
178
  this.tracer = tracer;
149
179
  this.traceId = traceId;
150
180
  this.spanId = spanId;
151
- this.startedAt = startedAt;
181
+ this.startMs = Date.now();
152
182
  }
153
183
  end(opts) {
154
184
  const endedAt = nowISO();
155
- const latencyMs = new Date(endedAt).getTime() - new Date(this.startedAt).getTime();
185
+ const latencyMs = Date.now() - this.startMs;
156
186
  this.tracer.enqueue({
187
+ v: 1,
157
188
  type: "span.end",
158
189
  traceId: this.traceId,
159
190
  spanId: this.spanId,
@@ -161,8 +192,8 @@ var SpanHandle = class {
161
192
  status: opts?.status ?? "completed",
162
193
  error: opts?.error,
163
194
  totalTokens: opts?.totalTokens,
164
- promptTokens: opts?.promptTokens,
165
- completionTokens: opts?.completionTokens,
195
+ inputTokens: opts?.inputTokens,
196
+ outputTokens: opts?.outputTokens,
166
197
  ttftMs: opts?.ttftMs,
167
198
  latencyMs,
168
199
  endedAt
@@ -189,4 +220,4 @@ Object.defineProperty(exports, 'TraceHandle', {
189
220
  return TraceHandle;
190
221
  }
191
222
  });
192
- //# sourceMappingURL=client-B9WXHjpz.cjs.map
223
+ //# sourceMappingURL=client-DWaiEqR5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-DWaiEqR5.cjs","names":[],"sources":["../src/utils.ts","../src/client.ts"],"sourcesContent":["const CHARS = \"0123456789abcdefghjkmnpqrstvwxyz\";\n\nexport function generateId(): string {\n const ts = Date.now().toString(36);\n let rand = \"\";\n const bytes = new Uint8Array(16);\n try {\n crypto.getRandomValues(bytes);\n } catch {\n for (let i = 0; i < 16; i++) {\n bytes[i] = Math.floor(Math.random() * 256);\n }\n }\n for (let i = 0; i < 16; i++) {\n rand += CHARS[bytes[i] % CHARS.length];\n }\n return ts + rand;\n}\n\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n","import type {\n AuixPrismConfig,\n TraceEndOptions,\n TraceEvent,\n TraceOptions,\n TraceResult,\n} from \"./types\";\nimport { generateId, nowISO } from \"./utils\";\n\nconst FLUSH_INTERVAL_MS = 1000;\nconst FLUSH_BATCH_SIZE = 10;\nconst MAX_BUFFER = 1000;\nconst SDK_VERSION = \"0.0.1\";\n\nfunction normalizeModel(model?: string): string | undefined {\n return model?.trim();\n}\n\nfunction normalizeProvider(provider?: string): string | undefined {\n return provider?.trim().toLowerCase();\n}\n\nexport class AuixPrism {\n private apiKey: string;\n private baseUrl: string;\n private project?: string;\n private sessionId?: string;\n private transport?: (events: TraceEvent[]) => Promise<void>;\n private onFlushError?: (error: unknown, events: TraceEvent[]) => void;\n private events: TraceEvent[] = [];\n private timer: ReturnType<typeof setInterval>;\n private _flushChain: Promise<void> = Promise.resolve();\n private destroyed = false;\n\n constructor(config: AuixPrismConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl ?? \"https://api.auix.dev\";\n this.project = config.project;\n this.sessionId = config.sessionId;\n this.transport = config.transport;\n this.onFlushError = config.onFlushError;\n this.timer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);\n }\n\n enqueue(event: TraceEvent): void {\n if (this.destroyed) {\n console.warn(\"[@auix/prism] enqueue called after destroy\");\n return;\n }\n this.events.push(event);\n if (this.events.length >= FLUSH_BATCH_SIZE) {\n this.flush();\n }\n }\n\n flush(): Promise<void> {\n if (this.events.length === 0) return this._flushChain;\n\n const batch = this.events.splice(0);\n const send = () => {\n if (this.transport) return this.transport(batch);\n return fetch(`${this.baseUrl}/v1/prism/ingest`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({\n v: 1,\n sdk: SDK_VERSION,\n events: batch,\n }),\n }).then(() => {});\n };\n\n this._flushChain = this._flushChain.then(() =>\n send().catch(() =>\n send().catch((err) => {\n console.warn(\"[@auix/prism] flush failed after retry\", err);\n this.events.unshift(...batch);\n if (this.events.length > MAX_BUFFER) {\n this.events.length = MAX_BUFFER;\n }\n this.onFlushError?.(err, batch);\n }),\n ),\n );\n return this._flushChain;\n }\n\n startTrace(opts: {\n name?: string;\n input?: unknown;\n model?: string;\n provider?: string;\n endUserId?: string;\n metadata?: Record<string, unknown>;\n tags?: string[];\n }): TraceHandle {\n const traceId = generateId();\n const startedAt = nowISO();\n\n this.enqueue({\n v: 1,\n type: \"trace.start\",\n traceId,\n name: opts.name,\n input: opts.input,\n model: normalizeModel(opts.model),\n provider: normalizeProvider(opts.provider),\n endUserId: opts.endUserId,\n metadata: opts.metadata,\n tags: opts.tags,\n project: this.project,\n sessionId: this.sessionId,\n startedAt,\n });\n\n return new TraceHandle(this, traceId);\n }\n\n startSpanOnTrace(\n traceId: string,\n opts: {\n name: string;\n type: \"llm\" | \"tool\" | \"retrieval\" | \"custom\";\n input?: unknown;\n model?: string;\n provider?: string;\n parentSpanId?: string;\n metadata?: Record<string, unknown>;\n },\n ): SpanHandle {\n const spanId = generateId();\n const startedAt = nowISO();\n\n this.enqueue({\n v: 1,\n type: \"span.start\",\n traceId,\n spanId,\n parentSpanId: opts.parentSpanId,\n name: opts.name,\n spanType: opts.type,\n input: opts.input,\n model: normalizeModel(opts.model),\n provider: normalizeProvider(opts.provider),\n metadata: opts.metadata,\n startedAt,\n });\n\n return new SpanHandle(this, traceId, spanId);\n }\n\n trace(opts: TraceOptions): TraceResult {\n const traceHandle = this.startTrace(opts);\n const finish = async (endOpts?: TraceEndOptions) => {\n traceHandle.end(endOpts);\n await this.destroy();\n };\n return { trace: traceHandle, finish };\n }\n\n destroy(): Promise<void> {\n this.destroyed = true;\n clearInterval(this.timer);\n return this.flush();\n }\n}\n\nexport class TraceHandle {\n private startMs = Date.now();\n\n constructor(\n private tracer: AuixPrism,\n readonly traceId: string,\n ) {}\n\n startSpan(opts: {\n name: string;\n type: \"llm\" | \"tool\" | \"retrieval\" | \"custom\";\n input?: unknown;\n model?: string;\n }): SpanHandle {\n const spanId = generateId();\n const startedAt = nowISO();\n\n this.tracer.enqueue({\n v: 1,\n type: \"span.start\",\n traceId: this.traceId,\n spanId,\n name: opts.name,\n spanType: opts.type,\n input: opts.input,\n model: opts.model,\n startedAt,\n });\n\n return new SpanHandle(this.tracer, this.traceId, spanId);\n }\n\n end(opts?: {\n output?: unknown;\n status?: \"completed\" | \"error\";\n error?: string;\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n ttftMs?: number;\n }): void {\n const endedAt = nowISO();\n const latencyMs = Date.now() - this.startMs;\n\n this.tracer.enqueue({\n v: 1,\n type: \"trace.end\",\n traceId: this.traceId,\n output: opts?.output,\n status: opts?.status ?? \"completed\",\n error: opts?.error,\n totalTokens: opts?.totalTokens,\n inputTokens: opts?.inputTokens,\n outputTokens: opts?.outputTokens,\n ttftMs: opts?.ttftMs,\n latencyMs,\n endedAt,\n });\n }\n}\n\nexport class SpanHandle {\n private startMs = Date.now();\n\n constructor(\n private tracer: AuixPrism,\n private traceId: string,\n readonly spanId: string,\n ) {}\n\n end(opts?: {\n output?: unknown;\n status?: \"completed\" | \"error\";\n error?: string;\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n ttftMs?: number;\n }): void {\n const endedAt = nowISO();\n const latencyMs = Date.now() - this.startMs;\n\n this.tracer.enqueue({\n v: 1,\n type: \"span.end\",\n traceId: this.traceId,\n spanId: this.spanId,\n output: opts?.output,\n status: opts?.status ?? \"completed\",\n error: opts?.error,\n totalTokens: opts?.totalTokens,\n inputTokens: opts?.inputTokens,\n outputTokens: opts?.outputTokens,\n ttftMs: opts?.ttftMs,\n latencyMs,\n endedAt,\n });\n }\n}\n"],"mappings":"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"}