@agent-native/core 0.194.0 → 0.195.0-nightly-20260927130129

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 (95) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/brain/actions/check-builder-embeddings.ts +71 -0
  3. package/corpus/templates/brain/app/i18n-data.ts +90 -0
  4. package/corpus/templates/brain/app/routes/sources.tsx +95 -0
  5. package/corpus/templates/calendar/actions/create-event.ts +264 -32
  6. package/corpus/templates/calendar/app/i18n/en-US.ts +3 -6
  7. package/corpus/templates/calendar/app/root.tsx +0 -1
  8. package/corpus/templates/calendar/changelog/2026-09-27-agent-created-events-show-details-and-open-links.md +6 -0
  9. package/corpus/templates/calendar/changelog/2026-09-27-calendar-event-cards-retain-meet-and-zoom-links-show-confere.md +6 -0
  10. package/corpus/templates/calendar/changelog/2026-09-27-calendar-event-cards-show-times-in-the-supplied-offset-or-ca.md +6 -0
  11. package/corpus/templates/calendar/shared/zoom-add-failed-messages.ts +13 -0
  12. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +144 -13
  13. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +226 -12
  14. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +191 -18
  15. package/corpus/templates/design/app/pages/DesignEditor.tsx +24 -4
  16. package/corpus/templates/design/changelog/2026-09-26-live-previews-keep-canvas-keyboard-shortcuts-available-when-.md +6 -0
  17. package/corpus/templates/design/changelog/2026-09-27-canvas-shortcuts-keep-working-when-a-connected-app-focuses-a.md +6 -0
  18. package/corpus/templates/design/changelog/2026-09-27-drops-into-plain-frames-now-stack-above-existing-content-whi.md +6 -0
  19. package/corpus/templates/design/changelog/2026-09-27-layers-dragged-out-of-a-frame-now-stay-above-the-frame.md +6 -0
  20. package/corpus/templates/design/changelog/2026-09-27-live-previews-keep-canvas-shortcuts-available-after-autofocu.md +6 -0
  21. package/corpus/templates/mail/actions/apply-ai-filter.ts +8 -20
  22. package/corpus/templates/mail/actions/create-scheduled-send.ts +16 -3
  23. package/corpus/templates/mail/actions/manage-automations.ts +54 -3
  24. package/corpus/templates/mail/actions/manage-draft.ts +11 -23
  25. package/corpus/templates/mail/actions/manage-gmail-filters.ts +25 -42
  26. package/corpus/templates/mail/actions/send-email.ts +52 -2
  27. package/corpus/templates/mail/app/root.tsx +0 -3
  28. package/corpus/templates/mail/changelog/2026-09-27-scheduled-sends-reject-timestamps-outside-the-supported-date.md +6 -0
  29. package/corpus/templates/mail/changelog/2026-09-27-show-successful-mail-changes-in-chat.md +6 -0
  30. package/dist/action-ui.d.ts +19 -0
  31. package/dist/action-ui.js +68 -0
  32. package/dist/agent/production-agent.js +9 -1
  33. package/dist/client/agentkit-chat/action-widget.d.ts +1 -1
  34. package/dist/client/agentkit-chat/action-widget.js +25 -0
  35. package/dist/client/agentkit-chat/approval-card.d.ts +7 -0
  36. package/dist/client/agentkit-chat/approval-card.js +56 -0
  37. package/dist/client/agentkit-chat/root.js +2 -0
  38. package/dist/client/chat/action-chat-ui-surface.js +5 -2
  39. package/dist/client/chat/agent-approval-card.js +4 -3
  40. package/dist/client/chat/index.d.ts +2 -1
  41. package/dist/client/chat/index.js +2 -1
  42. package/dist/client/chat/tool-call-display.js +3 -0
  43. package/dist/client/chat/tool-render-registry.d.ts +5 -0
  44. package/dist/client/chat/widgets/ActionCard.d.ts +9 -0
  45. package/dist/client/chat/widgets/ActionCard.js +5 -0
  46. package/dist/client/chat/widgets/RecordChangeWidget.d.ts +10 -0
  47. package/dist/client/chat/widgets/RecordChangeWidget.js +126 -0
  48. package/dist/client/chat/widgets/builtin-tool-renderers.d.ts +1 -0
  49. package/dist/client/chat/widgets/builtin-tool-renderers.js +160 -2
  50. package/dist/client/components/ui/button-classes.d.ts +1 -0
  51. package/dist/client/components/ui/button-classes.js +1 -0
  52. package/dist/client/observability/ObservabilityDashboard.js +113 -12
  53. package/dist/client/observability/ObservabilityReviewSummaryButton.d.ts +1 -1
  54. package/dist/client/observability/ObservabilityReviewSummaryButton.js +13 -8
  55. package/dist/client/sse-event-processor.d.ts +1 -0
  56. package/dist/client/sse-event-processor.js +3 -0
  57. package/dist/collab/routes.d.ts +2 -2
  58. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  59. package/dist/index.browser.d.ts +1 -1
  60. package/dist/index.browser.js +1 -1
  61. package/dist/index.d.ts +1 -1
  62. package/dist/index.js +1 -1
  63. package/dist/localization/core-messages/ar-SA.js +34 -0
  64. package/dist/localization/core-messages/de-DE.js +30 -0
  65. package/dist/localization/core-messages/en-US.d.ts +30 -0
  66. package/dist/localization/core-messages/en-US.js +30 -0
  67. package/dist/localization/core-messages/es-ES.js +31 -0
  68. package/dist/localization/core-messages/fr-FR.js +31 -0
  69. package/dist/localization/core-messages/hi-IN.js +30 -0
  70. package/dist/localization/core-messages/ja-JP.js +30 -0
  71. package/dist/localization/core-messages/ko-KR.js +30 -0
  72. package/dist/localization/core-messages/pt-BR.js +31 -0
  73. package/dist/localization/core-messages/zh-CN.js +30 -0
  74. package/dist/localization/core-messages/zh-TW.js +30 -0
  75. package/dist/localization/core-messages.d.ts +30 -0
  76. package/dist/localization/core-messages.js +14 -0
  77. package/dist/localization/default-messages.d.ts +4 -1
  78. package/dist/localization/default-messages.js +6 -3
  79. package/dist/notifications/routes.d.ts +2 -2
  80. package/dist/observability/reviews.js +26 -14
  81. package/dist/observability/routes.d.ts +8 -8
  82. package/dist/observability/store.d.ts +4 -1
  83. package/dist/observability/store.js +27 -6
  84. package/dist/observability/types.d.ts +2 -0
  85. package/dist/progress/routes.d.ts +1 -1
  86. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  87. package/dist/server/prompts/framework-core-compact.js +1 -1
  88. package/dist/server/prompts/framework-core.js +1 -1
  89. package/dist/server/transcribe-voice.d.ts +1 -1
  90. package/dist/triggers/actions/manage-automation.d.ts +2 -2
  91. package/package.json +1 -1
  92. package/corpus/templates/calendar/app/lib/register-chat-renderers.tsx +0 -295
  93. package/corpus/templates/mail/app/lib/mail-gmail-filter-confirmation.tsx +0 -77
  94. package/corpus/templates/mail/app/lib/register-chat-renderers.tsx +0 -54
  95. package/corpus/templates/mail/app/lib/register-mail-draft-card.tsx +0 -91
package/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 10319
34
+ - template files: 10327
@@ -0,0 +1,71 @@
1
+ import { defineAction } from "@agent-native/core/action";
2
+ import { readEmbeddingFamilyAvailability } from "@agent-native/core/embeddings";
3
+ import { runWithRequestContext } from "@agent-native/core/server/request-context";
4
+ import { assertAccess } from "@agent-native/core/sharing";
5
+ import { eq } from "drizzle-orm";
6
+ import { z } from "zod";
7
+
8
+ import { getDb, schema } from "../server/db/index.js";
9
+
10
+ export const checkBuilderEmbeddingsSchema = z.object({
11
+ sourceId: z.string().min(1),
12
+ confirmProviderCost: z.literal(true),
13
+ });
14
+
15
+ export default defineAction({
16
+ description:
17
+ "Check Builder embeddings for one Brain source with a single synthetic query; does not index or store data.",
18
+ schema: checkBuilderEmbeddingsSchema,
19
+ toolCallable: false,
20
+ needsApproval: true,
21
+ run: async ({ sourceId }) => {
22
+ await assertAccess("brain-source", sourceId, "admin");
23
+ const [source] = await getDb()
24
+ .select({
25
+ ownerEmail: schema.brainSources.ownerEmail,
26
+ orgId: schema.brainSources.orgId,
27
+ })
28
+ .from(schema.brainSources)
29
+ .where(eq(schema.brainSources.id, sourceId))
30
+ .limit(1);
31
+ if (!source) throw new Error("Brain source was not found.");
32
+
33
+ return runWithRequestContext(
34
+ {
35
+ userEmail: source.ownerEmail,
36
+ orgId: source.orgId ?? undefined,
37
+ },
38
+ async () => {
39
+ const availability = await readEmbeddingFamilyAvailability();
40
+ if (availability.unavailableProviders.includes("builder")) {
41
+ throw new Error(
42
+ "Builder embedding credential lookup is unavailable.",
43
+ );
44
+ }
45
+ const family = availability.families.find(
46
+ (candidate) => candidate.provider === "builder",
47
+ );
48
+ if (!family) throw new Error("Builder embeddings are not configured.");
49
+ const vectors = await family.embed(
50
+ [{ text: "Builder embedding connectivity check." }],
51
+ "query",
52
+ );
53
+ const [vector] = vectors;
54
+ if (
55
+ vectors.length !== 1 ||
56
+ !vector ||
57
+ vector.length !== family.dimensions ||
58
+ !vector.every(Number.isFinite)
59
+ ) {
60
+ throw new Error("Builder returned an invalid embedding.");
61
+ }
62
+ return {
63
+ provider: family.provider,
64
+ model: family.model,
65
+ dimensions: family.dimensions,
66
+ success: true,
67
+ };
68
+ },
69
+ );
70
+ },
71
+ });
@@ -493,6 +493,15 @@ const enUS = {
493
493
  reviewRequired: "Review required",
494
494
  reviewRequiredDescription: "Queue extracted knowledge before approval",
495
495
  cancel: "Cancel",
496
+ close: "Close",
497
+ checkBuilder: "Check Builder embeddings",
498
+ checkBuilderDescription:
499
+ "Verify Builder with one synthetic request. No source content is sent or indexed.",
500
+ checkBuilderConfirm:
501
+ "Run one synthetic Builder embedding request for {{source}}? This may incur provider usage. No source content is sent, and the vector is not stored.",
502
+ runBuilderCheck: "Run one check",
503
+ checkBuilderSuccess:
504
+ "Builder check passed: {{provider}} / {{model}}, {{dimensions}} dimensions. No vector was stored.",
496
505
  saveSource: "Save source",
497
506
  createSource: "Create source",
498
507
  retryAfter: "Retry after {{date}}",
@@ -1006,6 +1015,15 @@ const baseMessagesByLocale = {
1006
1015
  provider: "提供方",
1007
1016
  notRequired: "不需要",
1008
1017
  cancel: "取消",
1018
+ close: "关闭",
1019
+ checkBuilder: "检查 Builder 嵌入服务",
1020
+ checkBuilderDescription:
1021
+ "发送一次模拟请求以验证 Builder。不会发送或索引来源内容。",
1022
+ checkBuilderConfirm:
1023
+ "要为 {{source}} 发送一次模拟的 Builder 嵌入请求吗?这可能产生服务费用。不会发送来源内容,也不会保存向量。",
1024
+ runBuilderCheck: "运行一次检查",
1025
+ checkBuilderSuccess:
1026
+ "Builder 检查通过:{{provider}} / {{model}},{{dimensions}} 维。未保存向量。",
1009
1027
  saveSource: "保存来源",
1010
1028
  createSource: "创建来源",
1011
1029
  retryAfter: "{{date}} 后重试",
@@ -1212,6 +1230,15 @@ const baseMessagesByLocale = {
1212
1230
  provider: "Proveedor",
1213
1231
  notRequired: "No requerido",
1214
1232
  cancel: "Cancelar",
1233
+ close: "Cerrar",
1234
+ checkBuilder: "Comprobar embeddings de Builder",
1235
+ checkBuilderDescription:
1236
+ "Verifica Builder con una solicitud de prueba. No se envía ni indexa contenido de la fuente.",
1237
+ checkBuilderConfirm:
1238
+ "¿Enviar una solicitud de prueba de embeddings de Builder para {{source}}? Puede generar costes del proveedor. No se envía contenido de la fuente ni se guarda el vector.",
1239
+ runBuilderCheck: "Realizar una comprobación",
1240
+ checkBuilderSuccess:
1241
+ "Comprobación de Builder correcta: {{provider}} / {{model}}, {{dimensions}} dimensiones. No se guardó ningún vector.",
1215
1242
  saveSource: "Guardar fuente",
1216
1243
  createSource: "Crear fuente",
1217
1244
  retryAfter: "Reintentar después de {{date}}",
@@ -1428,6 +1455,15 @@ const baseMessagesByLocale = {
1428
1455
  provider: "Fournisseur",
1429
1456
  notRequired: "Non requis",
1430
1457
  cancel: "Annuler",
1458
+ close: "Fermer",
1459
+ checkBuilder: "Vérifier les embeddings Builder",
1460
+ checkBuilderDescription:
1461
+ "Vérifiez Builder avec une seule requête de test. Aucun contenu de la source n'est envoyé ni indexé.",
1462
+ checkBuilderConfirm:
1463
+ "Envoyer une requête de test d'embedding Builder pour {{source}} ? Cela peut entraîner des frais du fournisseur. Aucun contenu de la source n'est envoyé et le vecteur n'est pas stocké.",
1464
+ runBuilderCheck: "Lancer une vérification",
1465
+ checkBuilderSuccess:
1466
+ "Vérification Builder réussie : {{provider}} / {{model}}, {{dimensions}} dimensions. Aucun vecteur n'a été stocké.",
1431
1467
  saveSource: "Enregistrer la source",
1432
1468
  createSource: "Créer une source",
1433
1469
  retryAfter: "Réessayer après {{date}}",
@@ -1643,6 +1679,15 @@ const baseMessagesByLocale = {
1643
1679
  provider: "Anbieter",
1644
1680
  notRequired: "Nicht erforderlich",
1645
1681
  cancel: "Abbrechen",
1682
+ close: "Schließen",
1683
+ checkBuilder: "Builder-Embeddings prüfen",
1684
+ checkBuilderDescription:
1685
+ "Builder mit einer Testanfrage prüfen. Quellinhalte werden weder gesendet noch indexiert.",
1686
+ checkBuilderConfirm:
1687
+ "Eine Testanfrage für Builder-Embeddings zu {{source}} senden? Dabei können Anbietergebühren anfallen. Quellinhalte werden nicht gesendet und der Vektor wird nicht gespeichert.",
1688
+ runBuilderCheck: "Einmal prüfen",
1689
+ checkBuilderSuccess:
1690
+ "Builder-Prüfung erfolgreich: {{provider}} / {{model}}, {{dimensions}} Dimensionen. Kein Vektor wurde gespeichert.",
1646
1691
  saveSource: "Quelle speichern",
1647
1692
  createSource: "Quelle erstellen",
1648
1693
  retryAfter: "Erneut versuchen nach {{date}}",
@@ -1853,6 +1898,15 @@ const baseMessagesByLocale = {
1853
1898
  provider: "プロバイダー",
1854
1899
  notRequired: "不要",
1855
1900
  cancel: "キャンセル",
1901
+ close: "閉じる",
1902
+ checkBuilder: "Builder の埋め込みを確認",
1903
+ checkBuilderDescription:
1904
+ "テスト用のリクエストを 1 回送信して Builder を確認します。ソースの内容は送信もインデックス登録もされません。",
1905
+ checkBuilderConfirm:
1906
+ "{{source}} に対して Builder の埋め込みテストリクエストを 1 回送信しますか?プロバイダーの利用料金が発生する場合があります。ソースの内容は送信されず、ベクトルも保存されません。",
1907
+ runBuilderCheck: "1 回確認する",
1908
+ checkBuilderSuccess:
1909
+ "Builder の確認に成功しました: {{provider}} / {{model}}、{{dimensions}} 次元。ベクトルは保存されていません。",
1856
1910
  saveSource: "ソースを保存",
1857
1911
  createSource: "ソースを作成",
1858
1912
  retryAfter: "{{date}} 後に再試行",
@@ -2063,6 +2117,15 @@ const baseMessagesByLocale = {
2063
2117
  provider: "제공자",
2064
2118
  notRequired: "필요 없음",
2065
2119
  cancel: "취소",
2120
+ close: "닫기",
2121
+ checkBuilder: "Builder 임베딩 확인",
2122
+ checkBuilderDescription:
2123
+ "테스트 요청 한 번으로 Builder를 확인합니다. 소스 내용은 전송하거나 인덱싱하지 않습니다.",
2124
+ checkBuilderConfirm:
2125
+ "{{source}}에 대해 Builder 임베딩 테스트 요청을 한 번 보내시겠습니까? 제공업체 사용 요금이 발생할 수 있습니다. 소스 내용은 전송하지 않으며 벡터도 저장하지 않습니다.",
2126
+ runBuilderCheck: "한 번 확인하기",
2127
+ checkBuilderSuccess:
2128
+ "Builder 확인 성공: {{provider}} / {{model}}, {{dimensions}}차원. 벡터는 저장되지 않았습니다.",
2066
2129
  saveSource: "소스 저장",
2067
2130
  createSource: "소스 만들기",
2068
2131
  retryAfter: "{{date}} 후 다시 시도",
@@ -2273,6 +2336,15 @@ const baseMessagesByLocale = {
2273
2336
  provider: "Provedor",
2274
2337
  notRequired: "Não obrigatório",
2275
2338
  cancel: "Cancelar",
2339
+ close: "Fechar",
2340
+ checkBuilder: "Verificar embeddings do Builder",
2341
+ checkBuilderDescription:
2342
+ "Verifique o Builder com uma solicitação de teste. O conteúdo da fonte não é enviado nem indexado.",
2343
+ checkBuilderConfirm:
2344
+ "Enviar uma solicitação de teste de embeddings do Builder para {{source}}? Isso pode gerar custos do provedor. O conteúdo da fonte não é enviado e o vetor não é armazenado.",
2345
+ runBuilderCheck: "Executar uma verificação",
2346
+ checkBuilderSuccess:
2347
+ "Verificação do Builder concluída: {{provider}} / {{model}}, {{dimensions}} dimensões. Nenhum vetor foi armazenado.",
2276
2348
  saveSource: "Salvar fonte",
2277
2349
  createSource: "Criar fonte",
2278
2350
  retryAfter: "Tentar novamente após {{date}}",
@@ -2487,6 +2559,15 @@ const baseMessagesByLocale = {
2487
2559
  provider: "प्रदाता",
2488
2560
  notRequired: "आवश्यक नहीं",
2489
2561
  cancel: "रद्द करें",
2562
+ close: "बंद करें",
2563
+ checkBuilder: "Builder एम्बेडिंग जाँचें",
2564
+ checkBuilderDescription:
2565
+ "एक परीक्षण अनुरोध से Builder की जाँच करें। स्रोत की सामग्री भेजी या इंडेक्स नहीं की जाती।",
2566
+ checkBuilderConfirm:
2567
+ "{{source}} के लिए Builder एम्बेडिंग का एक परीक्षण अनुरोध भेजें? प्रदाता का शुल्क लग सकता है। स्रोत की सामग्री नहीं भेजी जाएगी और वेक्टर सहेजा नहीं जाएगा।",
2568
+ runBuilderCheck: "एक बार जाँचें",
2569
+ checkBuilderSuccess:
2570
+ "Builder जाँच सफल: {{provider}} / {{model}}, {{dimensions}} आयाम। कोई वेक्टर सहेजा नहीं गया।",
2490
2571
  saveSource: "स्रोत सहेजें",
2491
2572
  createSource: "स्रोत बनाएं",
2492
2573
  retryAfter: "{{date}} के बाद फिर कोशिश करें",
@@ -2695,6 +2776,15 @@ const baseMessagesByLocale = {
2695
2776
  provider: "المزوّد",
2696
2777
  notRequired: "غير مطلوب",
2697
2778
  cancel: "إلغاء",
2779
+ close: "إغلاق",
2780
+ checkBuilder: "التحقق من تضمينات Builder",
2781
+ checkBuilderDescription:
2782
+ "تحقّق من Builder بطلب اختباري واحد. لن يُرسل محتوى المصدر أو يُفهرس.",
2783
+ checkBuilderConfirm:
2784
+ "هل تريد إرسال طلب اختباري واحد لتضمينات Builder من أجل {{source}}؟ قد تترتب رسوم من المزوّد. لن يُرسل محتوى المصدر ولن يُحفظ المتجه.",
2785
+ runBuilderCheck: "إجراء تحقق واحد",
2786
+ checkBuilderSuccess:
2787
+ "نجح التحقق من Builder: {{provider}} / {{model}}، {{dimensions}} بُعدًا. لم يُحفظ أي متجه.",
2698
2788
  saveSource: "حفظ المصدر",
2699
2789
  createSource: "إنشاء مصدر",
2700
2790
  retryAfter: "إعادة المحاولة بعد {{date}}",
@@ -10,6 +10,7 @@ import {
10
10
  IconArchive,
11
11
  IconBrandGithub,
12
12
  IconBrandSlack,
13
+ IconBolt,
13
14
  IconChecks,
14
15
  IconChevronDown,
15
16
  IconCircleCheck,
@@ -1803,6 +1804,21 @@ function SourceListItem({
1803
1804
  }) {
1804
1805
  const t = useT();
1805
1806
  const [expanded, setExpanded] = useState(false);
1807
+ const [builderCheckOpen, setBuilderCheckOpen] = useState(false);
1808
+ const sourceAccess = useActionQuery<{ accessRole?: string }>(
1809
+ "get-source" as any,
1810
+ { id: source.id } as any,
1811
+ { enabled: expanded, retry: false },
1812
+ );
1813
+ const checkBuilder = useActionMutation<
1814
+ { provider: string; model: string; dimensions: number; success: boolean },
1815
+ { sourceId: string; confirmProviderCost: true }
1816
+ >("check-builder-embeddings" as any, {
1817
+ skipActionQueryInvalidation: true,
1818
+ });
1819
+ const canCheckBuilder =
1820
+ sourceAccess.data?.accessRole === "admin" ||
1821
+ sourceAccess.data?.accessRole === "owner";
1806
1822
  const Icon = sourceProviderIcon(source.provider);
1807
1823
  const retry = sourceRetryAfter(source);
1808
1824
  const hasSyncNotice = Boolean(
@@ -1979,6 +1995,25 @@ function SourceListItem({
1979
1995
  </Button>
1980
1996
  </div>
1981
1997
  ) : null}
1998
+ {canCheckBuilder ? (
1999
+ <div className="mt-3 flex flex-col gap-3 rounded-md border border-border bg-muted/25 p-3 sm:flex-row sm:items-center sm:justify-between">
2000
+ <p className="text-sm leading-6 text-muted-foreground">
2001
+ {t("sources.checkBuilderDescription")}
2002
+ </p>
2003
+ <Button
2004
+ size="sm"
2005
+ variant="outline"
2006
+ className="shrink-0"
2007
+ onClick={() => {
2008
+ checkBuilder.reset();
2009
+ setBuilderCheckOpen(true);
2010
+ }}
2011
+ >
2012
+ <IconBolt className="size-4" />
2013
+ {t("sources.checkBuilder")}
2014
+ </Button>
2015
+ </div>
2016
+ ) : null}
1982
2017
  {hasSyncNotice ? (
1983
2018
  <div className="mt-3 flex gap-2 rounded-md border border-destructive/20 bg-destructive/5 px-3 py-2 text-sm">
1984
2019
  <IconAlertTriangle className="mt-0.5 size-4 shrink-0 text-destructive" />
@@ -2017,6 +2052,66 @@ function SourceListItem({
2017
2052
  ) : null}
2018
2053
  </div>
2019
2054
  ) : null}
2055
+
2056
+ <Dialog
2057
+ open={builderCheckOpen}
2058
+ onOpenChange={(open) => {
2059
+ if (!open && checkBuilder.isPending) return;
2060
+ setBuilderCheckOpen(open);
2061
+ }}
2062
+ >
2063
+ <DialogContent className="max-w-md gap-5">
2064
+ <DialogHeader>
2065
+ <DialogTitle>{t("sources.checkBuilder")}</DialogTitle>
2066
+ <DialogDescription>
2067
+ {t("sources.checkBuilderConfirm", { source: sourceName(source) })}
2068
+ </DialogDescription>
2069
+ </DialogHeader>
2070
+ {checkBuilder.data ? (
2071
+ <p role="status" className="text-sm text-foreground">
2072
+ {t("sources.checkBuilderSuccess", {
2073
+ provider: checkBuilder.data.provider,
2074
+ model: checkBuilder.data.model,
2075
+ dimensions: checkBuilder.data.dimensions.toLocaleString(),
2076
+ })}
2077
+ </p>
2078
+ ) : null}
2079
+ {checkBuilder.isError ? (
2080
+ <p role="alert" className="text-sm text-destructive">
2081
+ {checkBuilder.error.message}
2082
+ </p>
2083
+ ) : null}
2084
+ <DialogFooter>
2085
+ <Button
2086
+ type="button"
2087
+ variant="outline"
2088
+ disabled={checkBuilder.isPending}
2089
+ onClick={() => setBuilderCheckOpen(false)}
2090
+ >
2091
+ {checkBuilder.data ? t("sources.close") : t("sources.cancel")}
2092
+ </Button>
2093
+ {!checkBuilder.data ? (
2094
+ <Button
2095
+ type="button"
2096
+ disabled={checkBuilder.isPending}
2097
+ onClick={() =>
2098
+ checkBuilder.mutate({
2099
+ sourceId: source.id,
2100
+ confirmProviderCost: true,
2101
+ })
2102
+ }
2103
+ >
2104
+ {checkBuilder.isPending ? (
2105
+ <IconLoader2 className="size-4 animate-spin" />
2106
+ ) : (
2107
+ <IconBolt className="size-4" />
2108
+ )}
2109
+ {t("sources.runBuilderCheck")}
2110
+ </Button>
2111
+ ) : null}
2112
+ </DialogFooter>
2113
+ </DialogContent>
2114
+ </Dialog>
2020
2115
  </div>
2021
2116
  );
2022
2117
  }