@probelabs/probe 0.6.0-rc224 → 0.6.0-rc225

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.
@@ -242,6 +242,183 @@ var SimpleAppTracer = class {
242
242
  console.log("[Attributes]", attributes);
243
243
  }
244
244
  }
245
+ /**
246
+ * Hash content for deduplication/comparison purposes
247
+ * @param {string} content - The content to hash
248
+ * @returns {string} - Hex string hash
249
+ */
250
+ hashContent(content) {
251
+ let hash = 0;
252
+ const len = Math.min(content.length, 1e3);
253
+ for (let i = 0; i < len; i++) {
254
+ hash = (hash << 5) - hash + content.charCodeAt(i);
255
+ hash |= 0;
256
+ }
257
+ return hash.toString(16);
258
+ }
259
+ /**
260
+ * Record a conversation turn (assistant response or tool result)
261
+ * @param {string} role - The role (assistant, tool_result)
262
+ * @param {string} content - The turn content
263
+ * @param {Object} metadata - Additional metadata
264
+ */
265
+ recordConversationTurn(role, content, metadata = {}) {
266
+ if (!this.isEnabled()) return;
267
+ this.addEvent(`conversation.turn.${role}`, {
268
+ "session.id": this.sessionId,
269
+ "conversation.role": role,
270
+ "conversation.content": content.substring(0, 1e4),
271
+ "conversation.content.length": content.length,
272
+ "conversation.content.hash": this.hashContent(content),
273
+ ...metadata
274
+ });
275
+ }
276
+ /**
277
+ * Record error events with classification
278
+ * @param {string} errorType - The type of error (wrapped_tool, unrecognized_tool, no_tool_call, circuit_breaker, etc.)
279
+ * @param {Object} errorDetails - Error details including message, stack, context
280
+ */
281
+ recordErrorEvent(errorType, errorDetails = {}) {
282
+ if (!this.isEnabled()) return;
283
+ this.addEvent(`error.${errorType}`, {
284
+ "session.id": this.sessionId,
285
+ "error.type": errorType,
286
+ "error.message": errorDetails.message?.substring(0, 1e3) || null,
287
+ "error.stack": errorDetails.stack?.substring(0, 2e3) || null,
288
+ "error.recoverable": errorDetails.recoverable ?? true,
289
+ "error.context": JSON.stringify(errorDetails.context || {}).substring(0, 1e3),
290
+ ...Object.fromEntries(
291
+ Object.entries(errorDetails).filter(([k]) => !["message", "stack", "context", "recoverable"].includes(k)).map(([k, v]) => [`error.${k}`, v])
292
+ )
293
+ });
294
+ }
295
+ /**
296
+ * Record AI thinking/reasoning content
297
+ * @param {string} thinkingContent - The thinking content from AI response
298
+ * @param {Object} metadata - Additional metadata
299
+ */
300
+ recordThinkingContent(thinkingContent, metadata = {}) {
301
+ if (!this.isEnabled() || !thinkingContent) return;
302
+ this.addEvent("ai.thinking", {
303
+ "session.id": this.sessionId,
304
+ "ai.thinking.content": thinkingContent.substring(0, 5e4),
305
+ "ai.thinking.length": thinkingContent.length,
306
+ "ai.thinking.hash": this.hashContent(thinkingContent),
307
+ ...metadata
308
+ });
309
+ }
310
+ /**
311
+ * Record AI tool call decision
312
+ * @param {string} toolName - The tool name AI decided to call
313
+ * @param {Object} params - The parameters AI provided
314
+ * @param {Object} metadata - Additional metadata
315
+ */
316
+ recordToolDecision(toolName, params, metadata = {}) {
317
+ if (!this.isEnabled()) return;
318
+ this.addEvent("ai.tool_decision", {
319
+ "session.id": this.sessionId,
320
+ "ai.tool_decision.name": toolName,
321
+ "ai.tool_decision.params": JSON.stringify(params || {}).substring(0, 2e3),
322
+ ...metadata
323
+ });
324
+ }
325
+ /**
326
+ * Record tool result after execution
327
+ * @param {string} toolName - The tool that was executed
328
+ * @param {string|Object} result - The tool result
329
+ * @param {boolean} success - Whether the tool succeeded
330
+ * @param {number} durationMs - Execution duration in milliseconds
331
+ * @param {Object} metadata - Additional metadata
332
+ */
333
+ recordToolResult(toolName, result, success, durationMs, metadata = {}) {
334
+ if (!this.isEnabled()) return;
335
+ const resultStr = typeof result === "string" ? result : JSON.stringify(result);
336
+ this.addEvent("tool.result", {
337
+ "session.id": this.sessionId,
338
+ "tool.name": toolName,
339
+ "tool.result": resultStr.substring(0, 1e4),
340
+ "tool.result.length": resultStr.length,
341
+ "tool.result.hash": this.hashContent(resultStr),
342
+ "tool.duration_ms": durationMs,
343
+ "tool.success": success,
344
+ ...metadata
345
+ });
346
+ }
347
+ /**
348
+ * Record MCP tool execution start
349
+ * @param {string} toolName - MCP tool name
350
+ * @param {string} serverName - MCP server name
351
+ * @param {Object} params - Tool parameters
352
+ * @param {Object} metadata - Additional metadata
353
+ */
354
+ recordMcpToolStart(toolName, serverName, params, metadata = {}) {
355
+ if (!this.isEnabled()) return;
356
+ this.addEvent("mcp.tool.start", {
357
+ "session.id": this.sessionId,
358
+ "mcp.tool.name": toolName,
359
+ "mcp.tool.server": serverName || "unknown",
360
+ "mcp.tool.params": JSON.stringify(params || {}).substring(0, 2e3),
361
+ ...metadata
362
+ });
363
+ }
364
+ /**
365
+ * Record MCP tool execution end
366
+ * @param {string} toolName - MCP tool name
367
+ * @param {string} serverName - MCP server name
368
+ * @param {string|Object} result - Tool result
369
+ * @param {boolean} success - Whether succeeded
370
+ * @param {number} durationMs - Execution duration
371
+ * @param {string} errorMessage - Error message if failed
372
+ * @param {Object} metadata - Additional metadata
373
+ */
374
+ recordMcpToolEnd(toolName, serverName, result, success, durationMs, errorMessage = null, metadata = {}) {
375
+ if (!this.isEnabled()) return;
376
+ const resultStr = typeof result === "string" ? result : JSON.stringify(result || "");
377
+ this.addEvent("mcp.tool.end", {
378
+ "session.id": this.sessionId,
379
+ "mcp.tool.name": toolName,
380
+ "mcp.tool.server": serverName || "unknown",
381
+ "mcp.tool.result": resultStr.substring(0, 1e4),
382
+ "mcp.tool.result.length": resultStr.length,
383
+ "mcp.tool.duration_ms": durationMs,
384
+ "mcp.tool.success": success,
385
+ "mcp.tool.error": errorMessage,
386
+ ...metadata
387
+ });
388
+ }
389
+ /**
390
+ * Record iteration lifecycle event
391
+ * @param {string} eventType - start or end
392
+ * @param {number} iteration - Iteration number
393
+ * @param {Object} data - Additional data
394
+ */
395
+ recordIterationEvent(eventType, iteration, data = {}) {
396
+ if (!this.isEnabled()) return;
397
+ this.addEvent(`iteration.${eventType}`, {
398
+ "session.id": this.sessionId,
399
+ "iteration": iteration,
400
+ ...data
401
+ });
402
+ }
403
+ /**
404
+ * Record per-turn token breakdown
405
+ * @param {number} iteration - Iteration number
406
+ * @param {Object} tokenData - Token metrics
407
+ */
408
+ recordTokenTurn(iteration, tokenData = {}) {
409
+ if (!this.isEnabled()) return;
410
+ this.addEvent("tokens.turn", {
411
+ "session.id": this.sessionId,
412
+ "iteration": iteration,
413
+ "tokens.input": tokenData.inputTokens || 0,
414
+ "tokens.output": tokenData.outputTokens || 0,
415
+ "tokens.total": (tokenData.inputTokens || 0) + (tokenData.outputTokens || 0),
416
+ "tokens.cache_read": tokenData.cacheReadTokens || 0,
417
+ "tokens.cache_write": tokenData.cacheWriteTokens || 0,
418
+ "tokens.context_used": tokenData.contextTokens || 0,
419
+ "tokens.context_remaining": tokenData.maxContextTokens ? tokenData.maxContextTokens - (tokenData.contextTokens || 0) : null
420
+ });
421
+ }
245
422
  async withSpan(spanName, fn, attributes = {}) {
246
423
  if (!this.isEnabled()) {
247
424
  return fn();