@agent-native/core 0.114.8 → 0.114.10

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 (128) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +31 -3
  5. package/corpus/core/src/agent/engine/anthropic-engine.ts +20 -3
  6. package/corpus/core/src/agent/engine/builder-engine.ts +56 -9
  7. package/corpus/core/src/agent/engine/first-event-timeout.ts +64 -0
  8. package/corpus/core/src/client/AssistantChat.tsx +7 -3
  9. package/corpus/core/src/client/resources/ResourcesPanel.tsx +1 -1
  10. package/corpus/core/src/integrations/computer-supervision-store.ts +4 -4
  11. package/corpus/core/src/integrations/pending-tasks-store.ts +1 -1
  12. package/corpus/core/src/integrations/remote-commands-store.ts +5 -5
  13. package/corpus/core/src/integrations/remote-devices-store.ts +3 -3
  14. package/corpus/core/src/integrations/remote-push-store.ts +3 -3
  15. package/corpus/core/src/observability/traces.ts +38 -1
  16. package/corpus/core/src/server/action-routes.ts +23 -1
  17. package/corpus/core/src/server/http-response-telemetry.ts +6 -1
  18. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +1 -1
  19. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  20. package/corpus/templates/analytics/actions/account-deep-dive.ts +41 -6
  21. package/corpus/templates/analytics/changelog/2026-07-20-account-deep-dives-finish-with-partial-data-when-hubspot-lo.md +6 -0
  22. package/corpus/templates/analytics/changelog/2026-07-20-dashboard-email-reports-now-include-an-image-when-a-single-p.md +6 -0
  23. package/corpus/templates/analytics/server/lib/dashboard-report.ts +11 -3
  24. package/corpus/templates/calendar/actions/create-event.ts +5 -0
  25. package/corpus/templates/calendar/app/components/ThemeToggle.tsx +4 -1
  26. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +0 -1
  27. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +309 -421
  28. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +349 -0
  29. package/corpus/templates/calendar/app/i18n-data.ts +110 -0
  30. package/corpus/templates/calendar/app/lib/event-form-utils.ts +6 -0
  31. package/corpus/templates/calendar/app/pages/CalendarView.tsx +3 -0
  32. package/corpus/templates/calendar/app/root.tsx +4 -2
  33. package/corpus/templates/calendar/changelog/2026-07-20-events-can-be-updated-inline-with-date-time-timezone-and-rep.md +6 -0
  34. package/corpus/templates/calendar/changelog/2026-07-20-public-booking-pages-no-longer-hydrate-with-a-theme-mismatch.md +6 -0
  35. package/corpus/templates/calendar/shared/api.ts +1 -0
  36. package/corpus/templates/clips/AGENTS.md +7 -0
  37. package/corpus/templates/clips/actions/create-recording.ts +51 -10
  38. package/corpus/templates/clips/actions/get-recording-player-data.ts +34 -5
  39. package/corpus/templates/clips/actions/lib/transcript-preview.ts +48 -0
  40. package/corpus/templates/clips/actions/list-recordings.ts +15 -4
  41. package/corpus/templates/clips/actions/regenerate-summary.ts +32 -0
  42. package/corpus/templates/clips/actions/search-recordings.ts +28 -6
  43. package/corpus/templates/clips/actions/view-screen.ts +54 -47
  44. package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -5
  45. package/corpus/templates/clips/app/components/library/recording-card.tsx +29 -32
  46. package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +13 -0
  47. package/corpus/templates/clips/changelog/2026-07-20-agent-summaries-use-bounded-transcript-context.md +6 -0
  48. package/corpus/templates/clips/changelog/2026-07-20-clip-summaries-now-finish-without-sending-a-long-transcript-.md +6 -0
  49. package/corpus/templates/clips/changelog/2026-07-20-clips-agents-only-discover-recordings-you-own-or-have-alread.md +6 -0
  50. package/corpus/templates/clips/changelog/2026-07-20-hosted-recordings-no-longer-start-with-an-impossible-buffered-upload.md +6 -0
  51. package/corpus/templates/clips/changelog/2026-07-20-meeting-recordings-now-offer-a-cleaner-transcript-view-with-.md +6 -0
  52. package/corpus/templates/clips/changelog/2026-07-20-shared-clips-can-be-shared-with-limited-access-and-cards-sho.md +6 -0
  53. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +12 -8
  54. package/corpus/templates/clips/desktop/src/overlays/pill-logo.tsx +2 -15
  55. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +107 -340
  56. package/corpus/templates/clips/desktop/src/styles.css +27 -145
  57. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +6 -7
  58. package/corpus/templates/clips/server/lib/agent-recording-access.ts +73 -0
  59. package/corpus/templates/clips/server/plugins/agent-chat.ts +5 -2
  60. package/corpus/templates/plan/app/lib/plan-local-bridge.ts +18 -0
  61. package/corpus/templates/plan/app/pages/PlansPage.tsx +10 -11
  62. package/corpus/templates/plan/changelog/2026-07-20-bridged-local-plans-now-load-comments-from-the-local-workspace.md +6 -0
  63. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  64. package/dist/agent/engine/ai-sdk-engine.js +27 -4
  65. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  66. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  67. package/dist/agent/engine/anthropic-engine.js +19 -4
  68. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  69. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  70. package/dist/agent/engine/builder-engine.js +40 -7
  71. package/dist/agent/engine/builder-engine.js.map +1 -1
  72. package/dist/agent/engine/first-event-timeout.d.ts +25 -0
  73. package/dist/agent/engine/first-event-timeout.d.ts.map +1 -0
  74. package/dist/agent/engine/first-event-timeout.js +49 -0
  75. package/dist/agent/engine/first-event-timeout.js.map +1 -0
  76. package/dist/client/AssistantChat.d.ts.map +1 -1
  77. package/dist/client/AssistantChat.js +7 -3
  78. package/dist/client/AssistantChat.js.map +1 -1
  79. package/dist/client/resources/ResourcesPanel.js +1 -1
  80. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  81. package/dist/collab/routes.d.ts +1 -1
  82. package/dist/collab/struct-routes.d.ts +1 -1
  83. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  84. package/dist/integrations/computer-supervision-store.js +4 -4
  85. package/dist/integrations/computer-supervision-store.js.map +1 -1
  86. package/dist/integrations/pending-tasks-store.js +1 -1
  87. package/dist/integrations/pending-tasks-store.js.map +1 -1
  88. package/dist/integrations/remote-commands-store.js +5 -5
  89. package/dist/integrations/remote-commands-store.js.map +1 -1
  90. package/dist/integrations/remote-devices-store.js +3 -3
  91. package/dist/integrations/remote-devices-store.js.map +1 -1
  92. package/dist/integrations/remote-push-store.js +3 -3
  93. package/dist/integrations/remote-push-store.js.map +1 -1
  94. package/dist/notifications/routes.d.ts +1 -1
  95. package/dist/observability/routes.d.ts +3 -3
  96. package/dist/observability/traces.d.ts.map +1 -1
  97. package/dist/observability/traces.js +23 -1
  98. package/dist/observability/traces.js.map +1 -1
  99. package/dist/progress/routes.d.ts +1 -1
  100. package/dist/resources/handlers.d.ts +1 -1
  101. package/dist/server/action-routes.d.ts.map +1 -1
  102. package/dist/server/action-routes.js +23 -1
  103. package/dist/server/action-routes.js.map +1 -1
  104. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  105. package/dist/server/http-response-telemetry.d.ts +2 -0
  106. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  107. package/dist/server/http-response-telemetry.js +5 -1
  108. package/dist/server/http-response-telemetry.js.map +1 -1
  109. package/dist/server/transcribe-voice.d.ts +1 -1
  110. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +1 -1
  111. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
  112. package/package.json +2 -2
  113. package/src/agent/engine/ai-sdk-engine.ts +31 -3
  114. package/src/agent/engine/anthropic-engine.ts +20 -3
  115. package/src/agent/engine/builder-engine.ts +56 -9
  116. package/src/agent/engine/first-event-timeout.ts +64 -0
  117. package/src/client/AssistantChat.tsx +7 -3
  118. package/src/client/resources/ResourcesPanel.tsx +1 -1
  119. package/src/integrations/computer-supervision-store.ts +4 -4
  120. package/src/integrations/pending-tasks-store.ts +1 -1
  121. package/src/integrations/remote-commands-store.ts +5 -5
  122. package/src/integrations/remote-devices-store.ts +3 -3
  123. package/src/integrations/remote-push-store.ts +3 -3
  124. package/src/observability/traces.ts +38 -1
  125. package/src/server/action-routes.ts +23 -1
  126. package/src/server/http-response-telemetry.ts +6 -1
  127. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +1 -1
  128. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -1
@@ -368,7 +368,7 @@ export async function listRemoteCommandsForOwner(input: {
368
368
  const { rows } = await getDbExec().execute({
369
369
  sql: `SELECT * FROM integration_remote_commands
370
370
  WHERE owner_email = ?
371
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
371
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
372
372
  ORDER BY updated_at DESC
373
373
  LIMIT ?`,
374
374
  args: [input.ownerEmail, input.orgId ?? null, input.orgId ?? null, limit],
@@ -435,7 +435,7 @@ export async function claimNextComputerCommand(input: {
435
435
  const { rows } = await client.execute({
436
436
  sql: `SELECT * FROM integration_remote_commands
437
437
  WHERE device_id = ? AND owner_email = ?
438
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
438
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
439
439
  AND kind = 'computer-operation' AND status = 'pending'
440
440
  AND next_check_at <= ?${operationClassClause}
441
441
  ORDER BY computer_sequence ASC, created_at ASC
@@ -477,7 +477,7 @@ export async function claimNextComputerCommand(input: {
477
477
  sql: `UPDATE integration_remote_commands
478
478
  SET status = 'failed', error_message = ?, completed_at = ?, updated_at = ?
479
479
  WHERE id = ? AND device_id = ? AND owner_email = ?
480
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
480
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
481
481
  AND status = 'pending'`,
482
482
  args: [
483
483
  error instanceof Error
@@ -500,13 +500,13 @@ export async function claimNextComputerCommand(input: {
500
500
  ? `UPDATE integration_remote_commands
501
501
  SET status = 'claimed', attempts = attempts + 1, claimed_at = ?, updated_at = ?
502
502
  WHERE id = ? AND device_id = ? AND owner_email = ?
503
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
503
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
504
504
  AND status = 'pending' AND lease_expires_at > ?
505
505
  RETURNING *`
506
506
  : `UPDATE integration_remote_commands
507
507
  SET status = 'claimed', attempts = attempts + 1, claimed_at = ?, updated_at = ?
508
508
  WHERE id = ? AND device_id = ? AND owner_email = ?
509
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
509
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
510
510
  AND status = 'pending' AND lease_expires_at > ?`,
511
511
  args: [
512
512
  now,
@@ -243,7 +243,7 @@ export async function getRemoteDeviceForOwner(input: {
243
243
  sql: `SELECT * FROM integration_remote_devices
244
244
  WHERE id = ?
245
245
  AND owner_email = ?
246
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
246
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
247
247
  LIMIT 1`,
248
248
  args: [
249
249
  input.id,
@@ -287,7 +287,7 @@ export async function listRemoteDevicesForOwner(input: {
287
287
  const { rows } = await getDbExec().execute({
288
288
  sql: `SELECT * FROM integration_remote_devices
289
289
  WHERE owner_email = ?
290
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}
290
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)${statusClause}
291
291
  ORDER BY COALESCE(last_seen_at, updated_at) DESC
292
292
  LIMIT ?`,
293
293
  args,
@@ -379,7 +379,7 @@ export async function revokeRemoteDeviceForOwner(input: {
379
379
  updated_at = ?
380
380
  WHERE id = ?
381
381
  AND owner_email = ?
382
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)`,
382
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)`,
383
383
  args: [
384
384
  now,
385
385
  now,
@@ -330,7 +330,7 @@ export async function listRemotePushRegistrationsForOwner(input: {
330
330
  const { rows } = await getDbExec().execute({
331
331
  sql: `SELECT * FROM integration_remote_push_registrations
332
332
  WHERE owner_email = ?
333
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}
333
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)${statusClause}
334
334
  ORDER BY COALESCE(last_seen_at, updated_at) DESC
335
335
  LIMIT ?`,
336
336
  args: [input.ownerEmail, input.orgId ?? null, input.orgId ?? null, limit],
@@ -352,7 +352,7 @@ export async function unregisterRemotePushRegistrationForOwner(input: {
352
352
  sql: `UPDATE integration_remote_push_registrations
353
353
  SET status = 'inactive', updated_at = ?
354
354
  WHERE owner_email = ?
355
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
355
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)
356
356
  AND (${input.id ? "id = ?" : "0 = 1"} OR ${
357
357
  tokenHash ? "token_hash = ?" : "0 = 1"
358
358
  })`,
@@ -432,7 +432,7 @@ export async function listRemotePushNotificationsForOwner(input: {
432
432
  const { rows } = await getDbExec().execute({
433
433
  sql: `SELECT * FROM integration_remote_push_notifications
434
434
  WHERE owner_email = ?
435
- AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}
435
+ AND ((org_id IS NULL AND CAST(? AS TEXT) IS NULL) OR org_id = ?)${statusClause}
436
436
  ORDER BY created_at DESC
437
437
  LIMIT ?`,
438
438
  args,
@@ -27,6 +27,9 @@ function costUsdFromCenticents(value: number): number {
27
27
  }
28
28
 
29
29
  const MAX_TRACKED_GENERATION_TOOL_CALLS = 50;
30
+ const MAX_TOOL_ERROR_MESSAGE_LENGTH = 500;
31
+ const STANDALONE_API_KEY_PATTERN =
32
+ /\b(?:sk-(?:proj-|ant-)?[A-Za-z0-9_-]{8,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{8,}|AIza[A-Za-z0-9_-]{16,}|gh[pousr]_[A-Za-z0-9]{16,})\b/g;
30
33
 
31
34
  type GenerationToolCall = {
32
35
  name: string;
@@ -34,8 +37,35 @@ type GenerationToolCall = {
34
37
  duration_ms: number;
35
38
  status: "success" | "error";
36
39
  error_class: "tool_error" | "legacy_inferred_error" | "interrupted" | null;
40
+ error_message?: string;
37
41
  };
38
42
 
43
+ function truncateToolErrorMessage(value: string): string {
44
+ return value.length > MAX_TOOL_ERROR_MESSAGE_LENGTH
45
+ ? `${value.slice(0, MAX_TOOL_ERROR_MESSAGE_LENGTH)}…`
46
+ : value;
47
+ }
48
+
49
+ function redactToolErrorMessage(value: string): string {
50
+ const credentialName =
51
+ "authorization|cookie|api[_ -]?key|password|secret|token|access[_ -]?token|refresh[_ -]?token";
52
+ const labeledCredential = `(["']?\\b(?:${credentialName})\\b["']?\\s*[:=]\\s*["']?)`;
53
+ return value
54
+ .replace(
55
+ new RegExp(
56
+ `${labeledCredential}(?:Bearer|Basic)\\s+[^"'\\s,;)}\\]]+`,
57
+ "gi",
58
+ ),
59
+ "$1[REDACTED]",
60
+ )
61
+ .replace(
62
+ new RegExp(`${labeledCredential}[^"'\\s,;)}\\[\\]]+`, "gi"),
63
+ "$1[REDACTED]",
64
+ )
65
+ .replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, "[REDACTED]")
66
+ .replace(STANDALONE_API_KEY_PATTERN, "[REDACTED]");
67
+ }
68
+
39
69
  function emitLlmGenerationTrackingEvent(args: {
40
70
  runId: string;
41
71
  threadId: string | null;
@@ -439,6 +469,10 @@ export async function instrumentAgentLoop(opts: {
439
469
  : explicitError
440
470
  ? "tool_error"
441
471
  : "legacy_inferred_error",
472
+ error_message:
473
+ isError && config.captureToolResults
474
+ ? truncateToolErrorMessage(redactToolErrorMessage(event.result))
475
+ : undefined,
442
476
  });
443
477
  }
444
478
 
@@ -532,6 +566,7 @@ export async function instrumentAgentLoop(opts: {
532
566
  for (const [counter, pending] of pendingTools) {
533
567
  toolCallCount += 1;
534
568
  failedTools += 1;
569
+ const interruptedMessage = "Tool call interrupted before completion";
535
570
  if (counter < MAX_TRACKED_GENERATION_TOOL_CALLS) {
536
571
  generationToolCalls.set(counter, {
537
572
  name: pending.toolName,
@@ -539,9 +574,11 @@ export async function instrumentAgentLoop(opts: {
539
574
  duration_ms: Math.max(0, runEnd - pending.startMs),
540
575
  status: "error",
541
576
  error_class: "interrupted",
577
+ error_message: config.captureToolResults
578
+ ? interruptedMessage
579
+ : undefined,
542
580
  });
543
581
  }
544
- const interruptedMessage = "Tool call interrupted before completion";
545
582
  if (pending.otelSpan) {
546
583
  openOtelToolSpans.delete(pending.otelSpan);
547
584
  endAgentSpan(pending.otelSpan, {
@@ -26,10 +26,12 @@ import {
26
26
  seedAgentRunOwnerContext,
27
27
  type AgentRunOwnerContext,
28
28
  } from "./agent-run-context.js";
29
+ import { captureError } from "./capture-error.js";
29
30
  import {
30
31
  getAllowedCorsOrigin as resolveAllowedCorsOrigin,
31
32
  readCorsAllowedOrigins,
32
33
  } from "./cors-origins.js";
34
+ import { getHttpRequestTelemetryId } from "./http-response-telemetry.js";
33
35
 
34
36
  declare const __AGENT_NATIVE_BUILD_ID__: string | undefined;
35
37
  declare const __AGENT_NATIVE_CLIENT_COMPATIBILITY_VERSION__: string | undefined;
@@ -640,7 +642,27 @@ export function mountActionRoutes(
640
642
  if (isUserFacing) {
641
643
  return { error: msg };
642
644
  }
643
- console.error(`[agent-native] action '${name}' failed:`, err);
645
+ const requestId = getHttpRequestTelemetryId(event);
646
+ const captureId = captureError(err, {
647
+ route: routePath,
648
+ method: reqMethod,
649
+ tags: {
650
+ action: name,
651
+ caller: resolvedCaller
652
+ ? "a2a"
653
+ : isFrontendActionRequest(event)
654
+ ? "frontend"
655
+ : "http",
656
+ status_code: String(status),
657
+ },
658
+ ...(requestId ? { extra: { request_id: requestId } } : {}),
659
+ });
660
+ console.error(`[agent-native] action '${name}' failed:`, {
661
+ action: name,
662
+ ...(requestId ? { requestId } : {}),
663
+ ...(captureId ? { captureId } : {}),
664
+ error: err?.stack ?? String(err),
665
+ });
644
666
  return { error: "Internal server error" };
645
667
  }
646
668
  },
@@ -284,11 +284,16 @@ function emitTelemetry(
284
284
  function requestTelemetryState(
285
285
  event: H3Event,
286
286
  ): HttpRequestTelemetryState | undefined {
287
- return (event.context as Record<PropertyKey, unknown>)[
287
+ return (event.context as Record<PropertyKey, unknown> | undefined)?.[
288
288
  REQUEST_TELEMETRY_KEY
289
289
  ] as HttpRequestTelemetryState | undefined;
290
290
  }
291
291
 
292
+ /** Return the durable request id while a request is still being handled. */
293
+ export function getHttpRequestTelemetryId(event: H3Event): string | undefined {
294
+ return requestTelemetryState(event)?.requestId;
295
+ }
296
+
292
297
  function appendServerTiming(
293
298
  response: Response,
294
299
  event: H3Event,
@@ -32,7 +32,7 @@ await putSetting("observability-config", {
32
32
  enabled: true,
33
33
  capturePrompts: false,
34
34
  captureToolArgs: true, // capture action input args
35
- captureToolResults: false,
35
+ captureToolResults: false, // include failed tool error text on tracked $ai_generation tool call entries
36
36
  evalSampleRate: 0.05, // 5% of runs get LLM-as-judge eval
37
37
  inferredSentimentEnabled: false,
38
38
  inferredSentimentSampleRate: 0,
@@ -160,7 +160,7 @@ Other framework-level baseline events:
160
160
  - `signup` from Better Auth user creation, with `auth_provider`, `auth_user_id`, and first-touch referral attribution (`referral_source`, `referrer_user`, `referral_medium`, `referral_campaign`, `utm_*`, `first_touch_path`, `landing_referrer` — see "Referral / viral attribution" above)
161
161
  - `builder connect clicked` and `builder connect popup blocked` from browser Connect Builder CTAs
162
162
  - `builder connect started`, `builder connect succeeded`, `builder connect failed`, `builder disconnect succeeded`, and `builder disconnect failed` from the Builder connection routes, with LLM connection context when resolvable
163
- - `$ai_generation` from instrumented agent loops, with PostHog AI Observability fields such as `$ai_trace_id`, `$ai_session_id`, `$ai_model`, `$ai_provider`, `$ai_input_tokens`, `$ai_output_tokens`, `$ai_latency`, `$ai_total_cost_usd`, and mirrored Agent Native query fields such as `run_id`, `thread_id`, `cost_cents_x100`, `duration_ms`, `tool_calls`, and `status`. A bounded `tools` array contains names, start offsets, durations, statuses, and coarse error classes only; interrupted tools and failed runs remain visible, and delegated runs include protocol/task/parent-run/parent-turn correlation. Prompt, tool argument, result, and output content is excluded.
163
+ - `$ai_generation` from instrumented agent loops, with PostHog AI Observability fields such as `$ai_trace_id`, `$ai_session_id`, `$ai_model`, `$ai_provider`, `$ai_input_tokens`, `$ai_output_tokens`, `$ai_latency`, `$ai_total_cost_usd`, and mirrored Agent Native query fields such as `run_id`, `thread_id`, `cost_cents_x100`, `duration_ms`, `tool_calls`, and `status`. A bounded `tools` array contains names, start offsets, durations, statuses, and coarse error classes only; interrupted tools and failed runs remain visible, and delegated runs include protocol/task/parent-run/parent-turn correlation. Prompt, tool argument, result, and output content is excluded unless `captureToolResults` is opted in (see the `observability` skill), in which case each failed tool call also carries a `error_message` string truncated to 500 characters and already scrubbed of bearer tokens, API keys, and key/value secret patterns.
164
164
 
165
165
  For new lifecycle events, call `track()` server-side when the server is the source of truth, and `trackEvent()` client-side only for browser interactions.
166
166