trickle-observe 0.2.121 → 0.2.123

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.
@@ -54,6 +54,12 @@ let llmFile = null;
54
54
  let eventCount = 0;
55
55
  const MAX_LLM_EVENTS = 500;
56
56
  const TRUNCATE_LEN = 500;
57
+ // Token budget enforcement
58
+ let cumulativeTokens = 0;
59
+ let cumulativeCost = 0;
60
+ let budgetWarned = false;
61
+ const TOKEN_BUDGET = parseInt(process.env.TRICKLE_TOKEN_BUDGET || '0', 10);
62
+ const COST_BUDGET = parseFloat(process.env.TRICKLE_COST_BUDGET || '0');
57
63
  // Approximate pricing per 1M tokens (USD) — used for cost estimation
58
64
  const PRICING = {
59
65
  'gpt-4o': { input: 2.5, output: 10 },
@@ -88,6 +94,19 @@ function writeLlmEvent(event) {
88
94
  if (eventCount >= MAX_LLM_EVENTS)
89
95
  return;
90
96
  eventCount++;
97
+ // Track cumulative usage for budget enforcement
98
+ cumulativeTokens += event.totalTokens || 0;
99
+ cumulativeCost += event.estimatedCostUsd || 0;
100
+ if (!budgetWarned) {
101
+ if (TOKEN_BUDGET > 0 && cumulativeTokens > TOKEN_BUDGET) {
102
+ console.warn(`[trickle] ⚠ Token budget exceeded: ${cumulativeTokens} tokens used (budget: ${TOKEN_BUDGET}). Set TRICKLE_TOKEN_BUDGET=0 to disable.`);
103
+ budgetWarned = true;
104
+ }
105
+ if (COST_BUDGET > 0 && cumulativeCost > COST_BUDGET) {
106
+ console.warn(`[trickle] ⚠ Cost budget exceeded: $${cumulativeCost.toFixed(4)} spent (budget: $${COST_BUDGET.toFixed(4)}). Set TRICKLE_COST_BUDGET=0 to disable.`);
107
+ budgetWarned = true;
108
+ }
109
+ }
91
110
  try {
92
111
  fs.appendFileSync(getLlmFile(), JSON.stringify(event) + '\n');
93
112
  }
@@ -1572,6 +1572,17 @@ if (enabled) {
1572
1572
  }
1573
1573
  catch { /* not critical */ }
1574
1574
  }
1575
+ // Claude Agent SDK
1576
+ if (request.includes('claude-agent-sdk') && !expressPatched.has('claude-agent-sdk')) {
1577
+ expressPatched.add('claude-agent-sdk');
1578
+ try {
1579
+ // The Claude Agent SDK uses hooks config — we can't easily patch
1580
+ // from Module._load since it's ESM-only. Log detection for now.
1581
+ if (debug)
1582
+ console.log('[trickle] Claude Agent SDK detected — use hooks for tracing');
1583
+ }
1584
+ catch { /* not critical */ }
1585
+ }
1575
1586
  // Google Gemini SDK
1576
1587
  if (request === '@google/genai' && !expressPatched.has('@google/genai')) {
1577
1588
  expressPatched.add('@google/genai');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trickle-observe",
3
- "version": "0.2.121",
4
- "description": "Runtime type observability for JavaScript applications",
3
+ "version": "0.2.123",
4
+ "description": "Zero-code runtime observability for JavaScript/TypeScript. Auto-instruments Express, OpenAI, Anthropic, Gemini, MCP. Captures functions, variables, LLM calls, agent workflows.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -18,6 +18,13 @@ let eventCount = 0;
18
18
  const MAX_LLM_EVENTS = 500;
19
19
  const TRUNCATE_LEN = 500;
20
20
 
21
+ // Token budget enforcement
22
+ let cumulativeTokens = 0;
23
+ let cumulativeCost = 0;
24
+ let budgetWarned = false;
25
+ const TOKEN_BUDGET = parseInt(process.env.TRICKLE_TOKEN_BUDGET || '0', 10);
26
+ const COST_BUDGET = parseFloat(process.env.TRICKLE_COST_BUDGET || '0');
27
+
21
28
  // Approximate pricing per 1M tokens (USD) — used for cost estimation
22
29
  const PRICING: Record<string, { input: number; output: number }> = {
23
30
  'gpt-4o': { input: 2.5, output: 10 },
@@ -71,6 +78,21 @@ interface LlmEvent {
71
78
  function writeLlmEvent(event: LlmEvent): void {
72
79
  if (eventCount >= MAX_LLM_EVENTS) return;
73
80
  eventCount++;
81
+
82
+ // Track cumulative usage for budget enforcement
83
+ cumulativeTokens += event.totalTokens || 0;
84
+ cumulativeCost += event.estimatedCostUsd || 0;
85
+
86
+ if (!budgetWarned) {
87
+ if (TOKEN_BUDGET > 0 && cumulativeTokens > TOKEN_BUDGET) {
88
+ console.warn(`[trickle] ⚠ Token budget exceeded: ${cumulativeTokens} tokens used (budget: ${TOKEN_BUDGET}). Set TRICKLE_TOKEN_BUDGET=0 to disable.`);
89
+ budgetWarned = true;
90
+ }
91
+ if (COST_BUDGET > 0 && cumulativeCost > COST_BUDGET) {
92
+ console.warn(`[trickle] ⚠ Cost budget exceeded: $${cumulativeCost.toFixed(4)} spent (budget: $${COST_BUDGET.toFixed(4)}). Set TRICKLE_COST_BUDGET=0 to disable.`);
93
+ budgetWarned = true;
94
+ }
95
+ }
74
96
  try {
75
97
  fs.appendFileSync(getLlmFile(), JSON.stringify(event) + '\n');
76
98
  } catch {}
@@ -1557,6 +1557,16 @@ if (enabled) {
1557
1557
  } catch { /* not critical */ }
1558
1558
  }
1559
1559
 
1560
+ // Claude Agent SDK
1561
+ if (request.includes('claude-agent-sdk') && !expressPatched.has('claude-agent-sdk')) {
1562
+ expressPatched.add('claude-agent-sdk');
1563
+ try {
1564
+ // The Claude Agent SDK uses hooks config — we can't easily patch
1565
+ // from Module._load since it's ESM-only. Log detection for now.
1566
+ if (debug) console.log('[trickle] Claude Agent SDK detected — use hooks for tracing');
1567
+ } catch { /* not critical */ }
1568
+ }
1569
+
1560
1570
  // Google Gemini SDK
1561
1571
  if (request === '@google/genai' && !expressPatched.has('@google/genai')) {
1562
1572
  expressPatched.add('@google/genai');