observa-sdk 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.
package/README.md CHANGED
@@ -15,6 +15,7 @@ npm install observa-sdk
15
15
  Get your API key by signing up at [https://app.observa.ai/signup](https://app.observa.ai/signup) (or your Observa API endpoint).
16
16
 
17
17
  The signup process automatically:
18
+
18
19
  - Creates your tenant account
19
20
  - Sets up a default "Production" project
20
21
  - Provisions your Tinybird token
@@ -53,12 +54,15 @@ const observa = init({
53
54
  });
54
55
 
55
56
  // Track AI interactions with simple wrapping
56
- const response = await observa.track(
57
- { query: "What is the weather?" },
58
- () => fetch("https://api.openai.com/v1/chat/completions", {
57
+ const response = await observa.track({ query: "What is the weather?" }, () =>
58
+ fetch("https://api.openai.com/v1/chat/completions", {
59
59
  method: "POST",
60
- headers: { /* ... */ },
61
- body: JSON.stringify({ /* ... */ }),
60
+ headers: {
61
+ /* ... */
62
+ },
63
+ body: JSON.stringify({
64
+ /* ... */
65
+ }),
62
66
  })
63
67
  );
64
68
  ```
@@ -116,6 +120,7 @@ The SDK supports JWT-formatted API keys that encode tenant context:
116
120
  ```
117
121
 
118
122
  **JWT Structure**:
123
+
119
124
  - `tenantId` (required): Unique identifier for the tenant/organization
120
125
  - `projectId` (required): Project identifier within the tenant
121
126
  - `environment` (optional): `"dev"` or `"prod"` (defaults to `"dev"`)
@@ -163,6 +168,7 @@ Initialize the Observa SDK instance.
163
168
  Track an AI interaction.
164
169
 
165
170
  **Parameters**:
171
+
166
172
  - `event.query` (required): The user query/prompt
167
173
  - `event.context` (optional): Additional context
168
174
  - `event.model` (optional): Model identifier
@@ -172,6 +178,7 @@ Track an AI interaction.
172
178
  **Returns**: `Promise<Response>` (the original response, unmodified)
173
179
 
174
180
  **Example**:
181
+
175
182
  ```typescript
176
183
  const response = await observa.track(
177
184
  {
@@ -179,17 +186,18 @@ const response = await observa.track(
179
186
  model: "gpt-4",
180
187
  metadata: { userId: "123" },
181
188
  },
182
- () => fetch("https://api.openai.com/v1/chat/completions", {
183
- method: "POST",
184
- headers: {
185
- "Authorization": `Bearer ${openaiKey}`,
186
- "Content-Type": "application/json",
187
- },
188
- body: JSON.stringify({
189
- model: "gpt-4",
190
- messages: [{ role: "user", content: "What is machine learning?" }],
191
- }),
192
- })
189
+ () =>
190
+ fetch("https://api.openai.com/v1/chat/completions", {
191
+ method: "POST",
192
+ headers: {
193
+ Authorization: `Bearer ${openaiKey}`,
194
+ "Content-Type": "application/json",
195
+ },
196
+ body: JSON.stringify({
197
+ model: "gpt-4",
198
+ messages: [{ role: "user", content: "What is machine learning?" }],
199
+ }),
200
+ })
193
201
  );
194
202
  ```
195
203
 
@@ -248,4 +256,3 @@ The entire onboarding process takes less than 5 minutes, and you can start track
248
256
  ## License
249
257
 
250
258
  MIT
251
-
package/dist/index.cjs CHANGED
@@ -427,32 +427,55 @@ var Observa = class {
427
427
  }
428
428
  try {
429
429
  const url = `${this.apiUrl}/api/v1/traces/ingest`;
430
- const response = await fetch(url, {
431
- method: "POST",
432
- headers: {
433
- Authorization: `Bearer ${this.apiKey}`,
434
- "Content-Type": "application/json"
435
- },
436
- body: JSON.stringify(trace)
437
- });
438
- if (!response.ok) {
439
- const errorText = await response.text().catch(() => "Unknown error");
440
- let errorJson;
441
- try {
442
- errorJson = JSON.parse(errorText);
443
- } catch {
444
- errorJson = { error: errorText };
430
+ console.log(`[Observa] Sending trace - URL: ${url}, TraceID: ${trace.traceId}, Tenant: ${trace.tenantId}, Project: ${trace.projectId}, APIKey: ${this.apiKey ? `Yes(${this.apiKey.length} chars)` : "No"}`);
431
+ const controller = new AbortController();
432
+ const timeoutId = setTimeout(() => controller.abort(), 1e4);
433
+ try {
434
+ const response = await fetch(url, {
435
+ method: "POST",
436
+ headers: {
437
+ Authorization: `Bearer ${this.apiKey}`,
438
+ "Content-Type": "application/json"
439
+ },
440
+ body: JSON.stringify(trace),
441
+ signal: controller.signal
442
+ });
443
+ clearTimeout(timeoutId);
444
+ console.log(`[Observa] Response status: ${response.status} ${response.statusText}`);
445
+ if (!response.ok) {
446
+ const errorText = await response.text().catch(() => "Unknown error");
447
+ let errorJson;
448
+ try {
449
+ errorJson = JSON.parse(errorText);
450
+ } catch {
451
+ errorJson = { error: errorText };
452
+ }
453
+ console.error(
454
+ `[Observa] Backend API error: ${response.status} ${response.statusText}`,
455
+ errorJson.error || errorText
456
+ );
457
+ } else {
458
+ console.log(`\u2705 [Observa] Trace sent successfully - Trace ID: ${trace.traceId}`);
445
459
  }
446
- console.error(
447
- `[Observa] Backend API error: ${response.status} ${response.statusText}`,
448
- errorJson.error || errorText
449
- );
450
- } else if (!this.isProduction) {
451
- console.log(`\u2705 [Observa] Trace sent successfully`);
452
- console.log(` Trace ID: ${trace.traceId}`);
460
+ } catch (fetchError) {
461
+ clearTimeout(timeoutId);
462
+ if (fetchError instanceof Error && fetchError.name === "AbortError") {
463
+ console.error("[Observa] Request timeout after 10 seconds");
464
+ }
465
+ throw fetchError;
453
466
  }
454
467
  } catch (error) {
455
468
  console.error("[Observa] Failed to send trace:", error);
469
+ if (error instanceof Error) {
470
+ console.error("[Observa] Error message:", error.message);
471
+ console.error("[Observa] Error name:", error.name);
472
+ if (error.name === "AbortError") {
473
+ console.error("[Observa] Request timed out - check network connectivity and API URL");
474
+ }
475
+ if (error.stack) {
476
+ console.error("[Observa] Error stack:", error.stack);
477
+ }
478
+ }
456
479
  }
457
480
  }
458
481
  };
package/dist/index.js CHANGED
@@ -402,32 +402,55 @@ var Observa = class {
402
402
  }
403
403
  try {
404
404
  const url = `${this.apiUrl}/api/v1/traces/ingest`;
405
- const response = await fetch(url, {
406
- method: "POST",
407
- headers: {
408
- Authorization: `Bearer ${this.apiKey}`,
409
- "Content-Type": "application/json"
410
- },
411
- body: JSON.stringify(trace)
412
- });
413
- if (!response.ok) {
414
- const errorText = await response.text().catch(() => "Unknown error");
415
- let errorJson;
416
- try {
417
- errorJson = JSON.parse(errorText);
418
- } catch {
419
- errorJson = { error: errorText };
405
+ console.log(`[Observa] Sending trace - URL: ${url}, TraceID: ${trace.traceId}, Tenant: ${trace.tenantId}, Project: ${trace.projectId}, APIKey: ${this.apiKey ? `Yes(${this.apiKey.length} chars)` : "No"}`);
406
+ const controller = new AbortController();
407
+ const timeoutId = setTimeout(() => controller.abort(), 1e4);
408
+ try {
409
+ const response = await fetch(url, {
410
+ method: "POST",
411
+ headers: {
412
+ Authorization: `Bearer ${this.apiKey}`,
413
+ "Content-Type": "application/json"
414
+ },
415
+ body: JSON.stringify(trace),
416
+ signal: controller.signal
417
+ });
418
+ clearTimeout(timeoutId);
419
+ console.log(`[Observa] Response status: ${response.status} ${response.statusText}`);
420
+ if (!response.ok) {
421
+ const errorText = await response.text().catch(() => "Unknown error");
422
+ let errorJson;
423
+ try {
424
+ errorJson = JSON.parse(errorText);
425
+ } catch {
426
+ errorJson = { error: errorText };
427
+ }
428
+ console.error(
429
+ `[Observa] Backend API error: ${response.status} ${response.statusText}`,
430
+ errorJson.error || errorText
431
+ );
432
+ } else {
433
+ console.log(`\u2705 [Observa] Trace sent successfully - Trace ID: ${trace.traceId}`);
420
434
  }
421
- console.error(
422
- `[Observa] Backend API error: ${response.status} ${response.statusText}`,
423
- errorJson.error || errorText
424
- );
425
- } else if (!this.isProduction) {
426
- console.log(`\u2705 [Observa] Trace sent successfully`);
427
- console.log(` Trace ID: ${trace.traceId}`);
435
+ } catch (fetchError) {
436
+ clearTimeout(timeoutId);
437
+ if (fetchError instanceof Error && fetchError.name === "AbortError") {
438
+ console.error("[Observa] Request timeout after 10 seconds");
439
+ }
440
+ throw fetchError;
428
441
  }
429
442
  } catch (error) {
430
443
  console.error("[Observa] Failed to send trace:", error);
444
+ if (error instanceof Error) {
445
+ console.error("[Observa] Error message:", error.message);
446
+ console.error("[Observa] Error name:", error.name);
447
+ if (error.name === "AbortError") {
448
+ console.error("[Observa] Request timed out - check network connectivity and API URL");
449
+ }
450
+ if (error.stack) {
451
+ console.error("[Observa] Error stack:", error.stack);
452
+ }
453
+ }
431
454
  }
432
455
  }
433
456
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "observa-sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Enterprise-grade observability SDK for AI applications. Track and monitor LLM interactions with zero friction.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",