@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
@@ -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
 
@@ -381,16 +381,51 @@ export default defineAction({
381
381
  run: async (args) => {
382
382
  const trimmedQuery = args.query.trim();
383
383
  const gaps: string[] = [];
384
- const [dealResult, pipelines, owners] = await Promise.all([
385
- searchHubSpotObjects({
384
+
385
+ const enrichmentLookups = Promise.allSettled([
386
+ getDealPipelines(),
387
+ getDealOwners(),
388
+ ]);
389
+ let dealResult;
390
+ try {
391
+ dealResult = await searchHubSpotObjects({
386
392
  objectType: "deals",
387
393
  query: trimmedQuery,
388
394
  properties: DEAL_DEEP_DIVE_PROPERTIES,
389
395
  limit: args.dealLimit,
390
- }),
391
- getDealPipelines(),
392
- getDealOwners(),
393
- ]);
396
+ });
397
+ } catch (err) {
398
+ throw new Error(
399
+ `HubSpot deal search failed for "${trimmedQuery}": ${
400
+ err instanceof Error ? err.message : String(err)
401
+ }`,
402
+ );
403
+ }
404
+ const [pipelinesSettled, ownersSettled] = await enrichmentLookups;
405
+
406
+ let pipelines: Pipeline[] = [];
407
+ if (pipelinesSettled.status === "fulfilled") {
408
+ pipelines = pipelinesSettled.value;
409
+ } else {
410
+ const err = pipelinesSettled.reason;
411
+ gaps.push(
412
+ `HubSpot deal pipelines: ${
413
+ err instanceof Error ? err.message : String(err)
414
+ }`,
415
+ );
416
+ }
417
+
418
+ let owners: Record<string, string> = {};
419
+ if (ownersSettled.status === "fulfilled") {
420
+ owners = ownersSettled.value;
421
+ } else {
422
+ const err = ownersSettled.reason;
423
+ gaps.push(
424
+ `HubSpot deal owners: ${
425
+ err instanceof Error ? err.message : String(err)
426
+ }`,
427
+ );
428
+ }
394
429
 
395
430
  const lookups = stageLookups(getVisiblePipelines(pipelines));
396
431
  const deals = dealResult.records.map((deal) =>
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-20
4
+ ---
5
+
6
+ Account deep dives now finish with partial data when HubSpot pipeline or owner lookups fail, and failed deal searches report a clear error.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-20
4
+ ---
5
+
6
+ Dashboard email reports now include an image when a single panel is still loading.
@@ -361,7 +361,7 @@ function positiveIntEnv(name: string): number | null {
361
361
  async function waitForDashboardReportReady(
362
362
  page: any,
363
363
  timeout: number,
364
- ): Promise<void> {
364
+ ): Promise<boolean> {
365
365
  try {
366
366
  await page.waitForFunction(
367
367
  `(() => {
@@ -379,6 +379,7 @@ async function waitForDashboardReportReady(
379
379
  await document.fonts?.ready;
380
380
  })()`);
381
381
  await page.waitForTimeout(750);
382
+ return true;
382
383
  } catch (err: any) {
383
384
  const detail = await page
384
385
  .evaluate(`(() => {
@@ -391,6 +392,12 @@ async function waitForDashboardReportReady(
391
392
  };
392
393
  })()`)
393
394
  .catch(() => null);
395
+ if (detail?.ready === "true") {
396
+ console.warn(
397
+ "[dashboard-report] Dashboard surface stayed partially loaded; capturing the available panels.",
398
+ );
399
+ return false;
400
+ }
394
401
  const message = detail
395
402
  ? `${err?.message ?? String(err)}; dashboard state: ${JSON.stringify(detail)}`
396
403
  : `${err?.message ?? String(err)}; dashboard page was not inspectable`;
@@ -788,6 +795,7 @@ async function captureDashboardPngWithFallback(
788
795
  captureScale: 0.85,
789
796
  ...(serverless
790
797
  ? {
798
+ readyTimeout: 45_000,
791
799
  secondReadyTimeout: 25_000,
792
800
  totalTimeout: SERVERLESS_FULL_ATTEMPT_TIMEOUT_MS,
793
801
  }
@@ -799,7 +807,7 @@ async function captureDashboardPngWithFallback(
799
807
  captureScale: 0.7,
800
808
  ...(serverless
801
809
  ? {
802
- readyTimeout: 55_000,
810
+ readyTimeout: 35_000,
803
811
  secondReadyTimeout: 15_000,
804
812
  totalTimeout: SERVERLESS_LIGHTWEIGHT_ATTEMPT_TIMEOUT_MS,
805
813
  }
@@ -818,7 +826,7 @@ async function captureDashboardPngWithFallback(
818
826
  reportPanelLimit: 8,
819
827
  ...(serverless
820
828
  ? {
821
- readyTimeout: 40_000,
829
+ readyTimeout: 25_000,
822
830
  secondReadyTimeout: 10_000,
823
831
  totalTimeout: 45_000,
824
832
  }
@@ -69,6 +69,10 @@ export default defineAction({
69
69
  colorId: googleColorIdInput.describe(
70
70
  "Google Calendar event color id, 1 through 11.",
71
71
  ),
72
+ recurrence: z
73
+ .array(z.string())
74
+ .optional()
75
+ .describe("Google recurrence rules such as RRULE:FREQ=WEEKLY;BYDAY=MO."),
72
76
  reminderMinutes: reminderMinutesInput.describe(
73
77
  "Convenience field for a single reminder in minutes before the event.",
74
78
  ),
@@ -168,6 +172,7 @@ export default defineAction({
168
172
  attendees,
169
173
  attachments: args.attachments,
170
174
  colorId: args.colorId,
175
+ recurrence: args.recurrence,
171
176
  ...reminderFields,
172
177
  ...statusEventFields,
173
178
  createdAt: new Date().toISOString(),
@@ -1,6 +1,7 @@
1
1
  import { useT } from "@agent-native/core/client/i18n";
2
2
  import { IconSun, IconMoon } from "@tabler/icons-react";
3
3
  import { useTheme } from "next-themes";
4
+ import { useEffect, useState } from "react";
4
5
 
5
6
  import { Button } from "@/components/ui/button";
6
7
  import {
@@ -12,7 +13,9 @@ import { cn } from "@/lib/utils";
12
13
 
13
14
  export function ThemeToggle({ className }: { className?: string }) {
14
15
  const { resolvedTheme, setTheme } = useTheme();
15
- const isDark = resolvedTheme === "dark";
16
+ const [mounted, setMounted] = useState(false);
17
+ useEffect(() => setMounted(true), []);
18
+ const isDark = mounted && resolvedTheme === "dark";
16
19
  const t = useT();
17
20
 
18
21
  return (
@@ -539,7 +539,6 @@ export function EventDetailPanel({
539
539
  <ExtensionSlot
540
540
  id="calendar.event-detail.bottom"
541
541
  context={eventDetailSlotContext}
542
- showEmptyAffordance
543
542
  />
544
543
  )}
545
544
  </div>