@fayz-ai/admin 0.61.0 → 0.63.0

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 (172) hide show
  1. package/dist/{CommandPalette-B5PMQFDG.js → CommandPalette-XDJJ5E3O.js} +3 -3
  2. package/dist/{CommandPalette-B5PMQFDG.js.map → CommandPalette-XDJJ5E3O.js.map} +1 -1
  3. package/dist/ConnectedBrandingSettings-43ZM3HCI.js +680 -0
  4. package/dist/ConnectedBrandingSettings-43ZM3HCI.js.map +1 -0
  5. package/dist/ConnectedCompanySettings-I4MALI2Q.js +197 -0
  6. package/dist/ConnectedCompanySettings-I4MALI2Q.js.map +1 -0
  7. package/dist/ConnectedModulesSettings-A2VJ5BMJ.js +563 -0
  8. package/dist/ConnectedModulesSettings-A2VJ5BMJ.js.map +1 -0
  9. package/dist/ConnectedSecuritySettings-25AHA4HJ.js +189 -0
  10. package/dist/ConnectedSecuritySettings-25AHA4HJ.js.map +1 -0
  11. package/dist/ConnectedUserProfile-E7USJRUE.js +424 -0
  12. package/dist/ConnectedUserProfile-E7USJRUE.js.map +1 -0
  13. package/dist/FieldRulesEditor-YGIPKI5T.js +129 -0
  14. package/dist/FieldRulesEditor-YGIPKI5T.js.map +1 -0
  15. package/dist/GettingStartedWidget-HMIJ3Y24.js +12 -0
  16. package/dist/GettingStartedWidget-HMIJ3Y24.js.map +1 -0
  17. package/dist/PermissionProfilesTab-3ZPRCHMZ.js +548 -0
  18. package/dist/PermissionProfilesTab-3ZPRCHMZ.js.map +1 -0
  19. package/dist/PersonTimeline-HQZT527S.js +3 -0
  20. package/dist/{PersonTimeline-X7JTPUWJ.js.map → PersonTimeline-HQZT527S.js.map} +1 -1
  21. package/dist/ProjectsSettings-7O2F27MD.js +5 -0
  22. package/dist/ProjectsSettings-7O2F27MD.js.map +1 -0
  23. package/dist/ScheduleEditor-54ELWR45.js +8 -0
  24. package/dist/{ScheduleEditor-L2UJXKMY.js.map → ScheduleEditor-54ELWR45.js.map} +1 -1
  25. package/dist/SeuSiteWidget-QLSUVC63.js +6 -0
  26. package/dist/SeuSiteWidget-QLSUVC63.js.map +1 -0
  27. package/dist/SubscriptionPage-5GE5HFJK.js +17 -0
  28. package/dist/{SubscriptionPage-IDVEFLZ5.js.map → SubscriptionPage-5GE5HFJK.js.map} +1 -1
  29. package/dist/TeamTab-6RAULFLW.js +502 -0
  30. package/dist/TeamTab-6RAULFLW.js.map +1 -0
  31. package/dist/TrialWidget-Z6CLUCU3.js +7 -0
  32. package/dist/TrialWidget-Z6CLUCU3.js.map +1 -0
  33. package/dist/app/AdminShell.d.ts.map +1 -1
  34. package/dist/app/admin-app.d.ts.map +1 -1
  35. package/dist/app/config.d.ts +14 -0
  36. package/dist/app/config.d.ts.map +1 -1
  37. package/dist/app/routing.d.ts +6 -0
  38. package/dist/app/routing.d.ts.map +1 -1
  39. package/dist/app/scaffold.d.ts.map +1 -1
  40. package/dist/billing/index.js +9 -4
  41. package/dist/chunk-2H46WDG5.js +53 -0
  42. package/dist/chunk-2H46WDG5.js.map +1 -0
  43. package/dist/chunk-3HLX7YB2.js +94 -0
  44. package/dist/chunk-3HLX7YB2.js.map +1 -0
  45. package/dist/chunk-3OUD4XBK.js +3 -0
  46. package/dist/chunk-3OUD4XBK.js.map +1 -0
  47. package/dist/{chunk-IXSY4GPK.js → chunk-5D5QLMOQ.js} +5 -3
  48. package/dist/chunk-5D5QLMOQ.js.map +1 -0
  49. package/dist/chunk-5WR62X2R.js +1081 -0
  50. package/dist/chunk-5WR62X2R.js.map +1 -0
  51. package/dist/{chunk-KPYRTOCK.js → chunk-6CQFGMEO.js} +4 -140
  52. package/dist/chunk-6CQFGMEO.js.map +1 -0
  53. package/dist/chunk-6MMSYC2I.js +116 -0
  54. package/dist/chunk-6MMSYC2I.js.map +1 -0
  55. package/dist/chunk-6QFOE3UD.js +1466 -0
  56. package/dist/chunk-6QFOE3UD.js.map +1 -0
  57. package/dist/chunk-6UUFVQ2E.js +283 -0
  58. package/dist/chunk-6UUFVQ2E.js.map +1 -0
  59. package/dist/chunk-7WNLL3F6.js +7889 -0
  60. package/dist/chunk-7WNLL3F6.js.map +1 -0
  61. package/dist/chunk-A74IHAQE.js +439 -0
  62. package/dist/chunk-A74IHAQE.js.map +1 -0
  63. package/dist/{chunk-JOBRLBIQ.js → chunk-AFA6IO23.js} +4 -3
  64. package/dist/chunk-AFA6IO23.js.map +1 -0
  65. package/dist/{chunk-P5UIGQFY.js → chunk-ALCSIN3Z.js} +5 -5
  66. package/dist/chunk-ALCSIN3Z.js.map +1 -0
  67. package/dist/chunk-AWM4AMBS.js +39 -0
  68. package/dist/chunk-AWM4AMBS.js.map +1 -0
  69. package/dist/{chunk-OQARLKZN.js → chunk-BG5Z6KLN.js} +6 -18
  70. package/dist/chunk-BG5Z6KLN.js.map +1 -0
  71. package/dist/chunk-DPNFZONC.js +19 -0
  72. package/dist/chunk-DPNFZONC.js.map +1 -0
  73. package/dist/chunk-DRCV643L.js +193 -0
  74. package/dist/chunk-DRCV643L.js.map +1 -0
  75. package/dist/chunk-E6DF3VR6.js +206 -0
  76. package/dist/chunk-E6DF3VR6.js.map +1 -0
  77. package/dist/chunk-ENHCVGXZ.js +120 -0
  78. package/dist/chunk-ENHCVGXZ.js.map +1 -0
  79. package/dist/chunk-FK6RHGI7.js +56 -0
  80. package/dist/chunk-FK6RHGI7.js.map +1 -0
  81. package/dist/chunk-G5HNA5QK.js +233 -0
  82. package/dist/chunk-G5HNA5QK.js.map +1 -0
  83. package/dist/chunk-HCFO4Z6A.js +53 -0
  84. package/dist/chunk-HCFO4Z6A.js.map +1 -0
  85. package/dist/chunk-JFIU6NQP.js +51 -0
  86. package/dist/chunk-JFIU6NQP.js.map +1 -0
  87. package/dist/chunk-JRZJBMOY.js +3 -0
  88. package/dist/chunk-JRZJBMOY.js.map +1 -0
  89. package/dist/{chunk-3YP7KW47.js → chunk-JVVOL4BB.js} +41 -512
  90. package/dist/chunk-JVVOL4BB.js.map +1 -0
  91. package/dist/chunk-KAQ3UIAA.js +415 -0
  92. package/dist/chunk-KAQ3UIAA.js.map +1 -0
  93. package/dist/{chunk-P6XUDT2P.js → chunk-KJELMULA.js} +4 -51
  94. package/dist/chunk-KJELMULA.js.map +1 -0
  95. package/dist/chunk-KLO7DKXX.js +1651 -0
  96. package/dist/chunk-KLO7DKXX.js.map +1 -0
  97. package/dist/chunk-M2CMDWUI.js +75 -0
  98. package/dist/chunk-M2CMDWUI.js.map +1 -0
  99. package/dist/chunk-PQ47MLTH.js +255 -0
  100. package/dist/chunk-PQ47MLTH.js.map +1 -0
  101. package/dist/{chunk-VX3WJLKK.js → chunk-QD7BMUDF.js} +17 -8
  102. package/dist/chunk-QD7BMUDF.js.map +1 -0
  103. package/dist/{chunk-E4MESMNR.js → chunk-QTSKCPSW.js} +7 -10
  104. package/dist/chunk-QTSKCPSW.js.map +1 -0
  105. package/dist/chunk-S56FQKPL.js +186 -0
  106. package/dist/chunk-S56FQKPL.js.map +1 -0
  107. package/dist/chunk-SGAFPNMA.js +75 -0
  108. package/dist/chunk-SGAFPNMA.js.map +1 -0
  109. package/dist/{chunk-OD7P4L3D.js → chunk-SOKCLVM4.js} +3 -3
  110. package/dist/{chunk-OD7P4L3D.js.map → chunk-SOKCLVM4.js.map} +1 -1
  111. package/dist/chunk-TL42NKTH.js +3 -0
  112. package/dist/chunk-TL42NKTH.js.map +1 -0
  113. package/dist/chunk-U6ZCO2PS.js +2964 -0
  114. package/dist/chunk-U6ZCO2PS.js.map +1 -0
  115. package/dist/chunk-VSXNROYH.js +16 -0
  116. package/dist/chunk-VSXNROYH.js.map +1 -0
  117. package/dist/chunk-WPFZCYZL.js +619 -0
  118. package/dist/chunk-WPFZCYZL.js.map +1 -0
  119. package/dist/chunk-XFTNIBDW.js +23 -0
  120. package/dist/chunk-XFTNIBDW.js.map +1 -0
  121. package/dist/chunk-Y66JDL6I.js +1020 -0
  122. package/dist/chunk-Y66JDL6I.js.map +1 -0
  123. package/dist/chunk-YEHIBPIX.js +137 -0
  124. package/dist/chunk-YEHIBPIX.js.map +1 -0
  125. package/dist/chunk-YKPPCV2Z.js +53 -0
  126. package/dist/chunk-YKPPCV2Z.js.map +1 -0
  127. package/dist/components/chat/markdown.d.ts.map +1 -1
  128. package/dist/components/plugins/PluginSettingsPanel.d.ts.map +1 -1
  129. package/dist/components/settings/SettingsPage.d.ts.map +1 -1
  130. package/dist/components/shared/ConnectionIndicator.d.ts.map +1 -1
  131. package/dist/connect-XKQJOWR7.js +18 -0
  132. package/dist/connect-XKQJOWR7.js.map +1 -0
  133. package/dist/crud/CrudDetailPage.d.ts.map +1 -1
  134. package/dist/crud/CrudListView.d.ts.map +1 -1
  135. package/dist/crud/CrudPage.d.ts.map +1 -1
  136. package/dist/crud/RelatedListTab.d.ts.map +1 -1
  137. package/dist/crud/archetypes/EntityLink.d.ts +1 -1
  138. package/dist/crud/archetypes/EntityLink.d.ts.map +1 -1
  139. package/dist/crud/record-chrome.d.ts.map +1 -1
  140. package/dist/entity-routes-PGU7EHAD.js +4 -0
  141. package/dist/{entity-routes-LXOBW5IB.js.map → entity-routes-PGU7EHAD.js.map} +1 -1
  142. package/dist/hooks/useModuleNavigation.d.ts.map +1 -1
  143. package/dist/impersonation/ImpersonateDialog.d.ts.map +1 -1
  144. package/dist/impersonation/session.d.ts.map +1 -1
  145. package/dist/index.d.ts +2 -2
  146. package/dist/index.d.ts.map +1 -1
  147. package/dist/index.js +11922 -33564
  148. package/dist/index.js.map +1 -1
  149. package/dist/lib/connection.d.ts +14 -0
  150. package/dist/lib/connection.d.ts.map +1 -1
  151. package/dist/lib/entity-routes.d.ts.map +1 -1
  152. package/dist/org/index.js +4 -2
  153. package/dist/plugins/PluginRegistryManager.d.ts.map +1 -1
  154. package/dist/settings/MessageTemplateRow.d.ts.map +1 -1
  155. package/dist/timeline/PersonTimeline.d.ts.map +1 -1
  156. package/dist/timeline/TimelineList.d.ts.map +1 -1
  157. package/dist/units/UnitRailPage.d.ts.map +1 -1
  158. package/dist/units/useUnitFilter.d.ts.map +1 -1
  159. package/package.json +5 -5
  160. package/dist/PersonTimeline-X7JTPUWJ.js +0 -3
  161. package/dist/ScheduleEditor-L2UJXKMY.js +0 -6
  162. package/dist/SubscriptionPage-IDVEFLZ5.js +0 -8
  163. package/dist/chunk-3YP7KW47.js.map +0 -1
  164. package/dist/chunk-E4MESMNR.js.map +0 -1
  165. package/dist/chunk-IXSY4GPK.js.map +0 -1
  166. package/dist/chunk-JOBRLBIQ.js.map +0 -1
  167. package/dist/chunk-KPYRTOCK.js.map +0 -1
  168. package/dist/chunk-OQARLKZN.js.map +0 -1
  169. package/dist/chunk-P5UIGQFY.js.map +0 -1
  170. package/dist/chunk-P6XUDT2P.js.map +0 -1
  171. package/dist/chunk-VX3WJLKK.js.map +0 -1
  172. package/dist/entity-routes-LXOBW5IB.js +0 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/assistant-invite.ts","../src/lib/reveal-page.ts","../src/lib/agent-surface.ts","../src/lib/ai-tool-handlers.ts","../src/hooks/useAgentSurface.ts","../src/components/AskAI.tsx","../src/crud/DeleteConfirmDialog.tsx"],"names":["resolved","useTranslation","jsx","jsxs","Button"],"mappings":"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","file":"chunk-6QFOE3UD.js","sourcesContent":["import { create } from 'zustand'\nimport type { AgentRole } from '@fayz-ai/core'\nimport { loadArea } from './tool-search'\n\n/**\n * Assistant Invite — how a screen ASKS to be helped.\n *\n * `useAgentSurface` publishes what the screen knows (state + tools). This is the\n * other half: what the screen OFFERS the user, in their words. A page declares a\n * persona, a headline and a few prompts worth asking, and the shell renders that\n * one declaration on three surfaces:\n *\n * hero — the page opens on the conversation, above its own content\n * dock — dismissed, it shrinks to a floating composer at the bottom\n * rail — expanded, the same persona heads the companion column\n *\n * One invite is active at a time: it belongs to the screen the user is on.\n */\n/**\n * The id a screen's handoff borrows the invite under (\"Criar com IA\").\n *\n * Lives here, not in the button: whoever asks \"is the assistant in the middle\n * of a delegated task?\" is asking about the INVITE. The rail reads it to fall\n * quiet — see RightRail.\n */\nexport const ASK_AI_HANDOFF_ID = 'ask-ai.handoff'\n\nexport interface AssistantInviteSuggestion {\n label: string\n /** Sent instead of `label` when the chip is picked. */\n prompt?: string\n}\n\nexport interface AssistantInviteDef {\n /** Stable id — also the session key that remembers a dismissal. */\n id: string\n /**\n * Which colleague this screen's help belongs to. With a cast, opening the\n * assistant here puts them on duty — the deterministic half of the routing,\n * for the cases the model should never have to guess.\n */\n role?: AgentRole\n /**\n * What the help IS, in the user's words (\"Montador de formulários\"). Names\n * the assistant on an app with no cast; with one, the colleague supplies the\n * name and this stays as the subject beside it.\n */\n persona?: string\n /** Hero headline. `{{name}}` resolves to the signed-in user's first name. */\n headline: string\n /** Rail headline. Falls back to `headline` — the rail has no name to greet. */\n pitch?: string\n /** One paragraph under the pitch: what this assistant is good for here. */\n description?: string\n placeholder?: string\n suggestions?: AssistantInviteSuggestion[]\n /** `false` opens docked. Default: hero on the session's first visit. */\n auto?: boolean\n}\n\ntype Stage = 'hero' | 'dock'\n\nconst KEY_DISMISSED = 'fayz.assistant.invite.dismissed'\n\nfunction session(): Storage | null {\n try {\n return typeof sessionStorage === 'undefined' ? null : sessionStorage\n } catch {\n return null\n }\n}\n\nfunction dismissedIds(): string[] {\n try {\n return JSON.parse(session()?.getItem(KEY_DISMISSED) ?? '[]') as string[]\n } catch {\n return []\n }\n}\n\n/** A dismissal lasts the session, not forever: the hero is how the screen opens,\n * and a permanent \"no\" would silence it on a machine the user never revisits. */\nfunction rememberDismissal(id: string): void {\n const store = session()\n if (!store) return\n store.setItem(KEY_DISMISSED, JSON.stringify([...new Set([...dismissedIds(), id])]))\n}\n\n/** Where the docked composer is drawn: `left` is its CENTRE x, in viewport px. */\nexport interface DockBox {\n left: number\n width: number\n}\n\ninterface AssistantInviteState {\n invite: AssistantInviteDef | null\n stage: Stage\n /** Published by the mounted invite while its composer is actually on screen\n * (null on phones, with the rail open, or during the hero). The FAB reads it\n * to know what shape it grew into. */\n dockBox: DockBox | null\n /** The composer whose page just unmounted, kept alive for the morph back into\n * the FAB. The page is already gone — this is what still has to be drawn. */\n leaving: { invite: AssistantInviteDef; box: DockBox } | null\n /** Mount/unmount. Passing null clears only if `id` still owns the slot. */\n setInvite: (invite: AssistantInviteDef | null, id?: string) => void\n setDockBox: (box: DockBox | null) => void\n dismiss: () => void\n /** The morph back finished; the FAB owns the corner again. */\n endLeave: () => void\n}\n\nexport const useAssistantInviteStore = create<AssistantInviteState>((set, get) => ({\n invite: null,\n stage: 'dock',\n dockBox: null,\n leaving: null,\n\n setInvite: (invite, id) => {\n if (!invite) {\n // A page unmounting after the next one registered must not clear its slot.\n if (id && get().invite?.id !== id) return\n const { invite: going, dockBox } = get()\n set({\n invite: null,\n stage: 'dock',\n dockBox: null,\n leaving: going && dockBox ? { invite: going, box: dockBox } : null,\n })\n return\n }\n // The screen already knows what this work is, so the agent does not have to\n // search for it: opening Marketing hands over the growth tools before the\n // first message is typed.\n if (invite.role) loadArea(invite.role)\n const hero = invite.auto !== false && !dismissedIds().includes(invite.id)\n // A new screen's invite outranks the old one's exit: morphing back into a\n // FAB that is about to become a composer again would be motion for nothing.\n set({ invite, stage: hero ? 'hero' : 'dock', leaving: null })\n },\n\n setDockBox: (box) => {\n const current = get().dockBox\n if (current?.left === box?.left && current?.width === box?.width) return\n set({ dockBox: box })\n },\n\n endLeave: () => set({ leaving: null }),\n\n dismiss: () => {\n const { invite } = get()\n if (invite) rememberDismissal(invite.id)\n set({ stage: 'dock' })\n },\n}))\n","import { useChatStore } from '../stores/chat.store'\nimport { useRightRailStore } from '../components/right-rail'\n\n/**\n * Sai da frente da página.\n *\n * Uma ferramenta que NAVEGA deixa a pessoa num beco no celular: a coluna do\n * assistente é uma folha de tela inteira, então o formulário que ela acabou de\n * pedir abre atrás dele e o que se vê é a frase dizendo que abriu. No desktop a\n * coluna fica ao LADO do conteúdo — ali não há nada de que sair.\n *\n * Mora aqui e não na store do chat porque quem cobre a tela é o RAIL, e a store\n * da conversa não conhece a coluna que a hospeda: `setOpen(false)` desmarca a\n * aba e deixa a folha aberta do mesmo jeito. Foi exatamente o que aconteceu na\n * primeira versão.\n *\n * Espera o turno terminar antes de fechar: fechar no meio some com a resposta\n * enquanto ela ainda está sendo escrita, e a pessoa fica sem o formulário e sem\n * a frase. Fechar não aborta nada — o turno não vive no componente.\n */\nexport function revealPage(delayMs = 1200): void {\n // Numa tela larga a coluna divide o espaço com a página; não cobre nada.\n if (typeof window === 'undefined' || window.matchMedia('(min-width: 768px)').matches) return\n\n const close = () => {\n // A ORDEM importa, e custou uma corrida: o app tem um efeito que reabre a\n // coluna sempre que `chat.isOpen` é verdadeiro. Fechando a coluna primeiro,\n // esse efeito acordava com a conversa ainda marcada como aberta e a trazia\n // de volta — às vezes. A conversa se marca fechada ANTES, e aí não há o que\n // reabrir.\n useChatStore.getState().setOpen(false)\n if (useRightRailStore.getState().open) useRightRailStore.getState().close()\n }\n\n if (!useChatStore.getState().isStreaming) {\n window.setTimeout(close, delayMs)\n return\n }\n const stop = useChatStore.subscribe((state, prev) => {\n if (prev.isStreaming && !state.isStreaming) {\n stop()\n window.setTimeout(close, delayMs)\n }\n })\n}\n","import type { AgentRole } from '@fayz-ai/core'\nimport type { PluginAITool } from '../types/plugins'\n\n/**\n * Agent Surface Contract — how the screen the user is looking at RIGHT NOW\n * contributes to the assistant.\n *\n * The FAB's base capabilities (data primitives, navigation) are global. But a\n * live, interactive surface — the form builder, a calendar, a reconciliation\n * ledger — has TWO things the global catalog can't express:\n *\n * 1. State that only exists on screen (an unsaved form draft), which the model\n * must SEE to help with, and\n * 2. Tools that act on that live state (add a field to the draft the user is\n * watching), which only make sense while the surface is mounted.\n *\n * A surface publishes both by calling `useAgentSurface(...)` on mount and\n * withdrawing them on unmount. This module is the registry the shell reads:\n * `useAITools` merges the tools, `useChat` folds the snapshot + instructions\n * into the request, and the executors ride the normal client-plane handler map.\n *\n * This is the scalable seam: forms is the first consumer; agenda, financial and\n * marketing adopt the same contract without touching the shell again.\n */\nexport interface AgentSurfaceSnapshot {\n /** One line naming what's on screen, e.g. 'Form builder — \"Anamnese\"'. */\n title?: string\n /** Structured state the model should reason over (the form draft, filters…). */\n state?: Record<string, unknown>\n /** The record this surface is centered on, when it is a detail page. */\n record?: { entity: string; id: string; label?: string; summary?: Record<string, unknown> }\n}\n\nexport interface AgentSurfaceTool {\n /** Declared tool shape (name, description, params) — same as a plugin aiTool. */\n tool: PluginAITool\n /** Client-plane executor that mutates the live surface. Read fresh each call. */\n execute: (args: Record<string, unknown>) => unknown | Promise<unknown>\n}\n\nexport interface AgentSurfaceContribution {\n /** Stable id for this surface instance, e.g. 'custom_forms.builder'. */\n id: string\n /** Plugin that owns the surface, used for tool ranking. */\n pluginId?: string\n /** Colleague this surface's tools belong to, inherited by any tool that does\n * not name its own. Omit to leave them shared by everyone. */\n role?: AgentRole\n /** Snapshot of what's on screen. Called fresh at send time — never cached. */\n describe?: () => AgentSurfaceSnapshot\n /** Guidance appended to the request ONLY while this surface is mounted. */\n instructions?: string\n /** Tools available only while this surface is mounted. */\n tools?: AgentSurfaceTool[]\n}\n\n/** Registry entry keeps a getter, not the value, so closures stay fresh across\n * re-renders without re-registering on every render. */\ninterface SurfaceEntry {\n id: string\n get: () => AgentSurfaceContribution\n}\n\nlet entries: SurfaceEntry[] = []\nlet version = 0\nconst listeners = new Set<() => void>()\n\nfunction emit(): void {\n version++\n for (const l of listeners) l()\n}\n\n/** Add or replace a surface (by id). Called on mount. */\nexport function registerSurface(entry: SurfaceEntry): void {\n entries = [...entries.filter((e) => e.id !== entry.id), entry]\n emit()\n}\n\n/** Remove a surface. Called on unmount. */\nexport function unregisterSurface(id: string): void {\n const next = entries.filter((e) => e.id !== id)\n if (next.length === entries.length) return\n entries = next\n emit()\n}\n\n/** useSyncExternalStore subscription — fires only on mount/unmount, not on the\n * per-render state changes inside a surface. */\nexport function subscribeSurfaces(cb: () => void): () => void {\n listeners.add(cb)\n return () => listeners.delete(cb)\n}\n\n/** Version counter for useSyncExternalStore; bumps when the set of surfaces\n * changes so `useAITools` recomputes its catalog. */\nexport function getSurfaceVersion(): number {\n return version\n}\n\n/** Flat list of tool declarations across every mounted surface (for the catalog).\n *\n * Most recently mounted surface FIRST. The shell's standing surfaces (setup,\n * handbook) register at boot; the screen the user is looking at registers when\n * its route mounts — last. The toolset cap keeps the head of the catalog, and\n * the one surface that must never be the one cut is the screen in front of the\n * user: this ordering is why \"importa esse cardápio\" gets the menu's own tools\n * instead of a truncated catalog that ends right before them. */\nexport function getSurfaceTools(): PluginAITool[] {\n return [...entries].reverse().flatMap((e) => {\n const c = e.get()\n // Same inheritance a plugin's tools get from `defaultAgentRole`.\n return c.tools?.map(({ tool }) => (tool.role || !c.role ? tool : { ...tool, role: c.role })) ?? []\n })\n}\n\n/** Snapshot + instructions from every mounted surface, read at send time. */\nexport function getActiveSurfaceContext(): {\n snapshot: AgentSurfaceSnapshot[]\n instructions: string[]\n} {\n const snapshot: AgentSurfaceSnapshot[] = []\n const instructions: string[] = []\n for (const e of entries) {\n const c = e.get()\n if (c.describe) {\n try {\n snapshot.push(c.describe())\n } catch {\n // A surface mid-transition must never break a turn.\n }\n }\n if (c.instructions) instructions.push(c.instructions)\n }\n return { snapshot, instructions }\n}\n","import {\n resolveDataProvider,\n getSupabaseClientOptional,\n getActiveTenantId,\n emitDataChanged,\n bulkCreate,\n parseRangeFilter,\n isFilterObject,\n matchesRange,\n type RangeFilter,\n} from '@fayz-ai/core'\nimport { profileHasSystemPermission } from '@fayz-ai/core/access'\nimport { checkAccess, guardLimit } from '../access/headless'\n// The store itself, not the permissions barrel — the executor has no business\n// pulling the React context in behind it.\nimport { usePermissionsStore } from '../permissions/store'\nimport { PROFILE_ACTIONS } from './core-ai-tools'\nimport { getSurfaceTools } from './agent-surface'\nimport { ALWAYS_ON_TOOLS, resolveToolSearch } from './tool-search'\nimport { lookupRecordRef } from './record-refs'\nimport { openEntity, resolveEntityRoute } from './entity-routes'\nimport { invalidateLimit } from '../access/limits-registry'\nimport { deriveEntityKey } from '@fayz-ai/core'\nimport { CORE_QUERY_ENTITIES } from '../app/core-entities'\nimport {\n resolveAttachmentDigest,\n listAttachmentNames,\n nonTabularAttachmentNames,\n readAllRows,\n} from './attachments'\nimport { revealPage } from './reveal-page'\nimport {\n useChatStore,\n type PendingAgentAction,\n type PendingActionField,\n type PendingActionResult,\n} from '../stores/chat.store'\n\n/** Chat-store confirmation gate, callable from any handler. */\nfunction requestChatConfirmation(action: PendingAgentAction): Promise<PendingActionResult> {\n return useChatStore.getState().requestConfirmation(action)\n}\n\n/** Columns the database owns. Offering them as inputs invites someone to\n * hand-type a `created_at`. */\nconst SYSTEM_FIELD_KEYS = new Set([\n 'id', 'tenant_id', 'tenantId', 'created_at', 'createdAt', 'updated_at', 'updatedAt',\n 'deleted_at', 'deletedAt', 'created_by', 'createdBy',\n])\n\nfunction normaliseOptions(raw: unknown): Array<{ value: string; label?: string }> | undefined {\n if (!Array.isArray(raw)) return undefined\n const out: Array<{ value: string; label?: string }> = []\n for (const o of raw) {\n if (typeof o === 'string') out.push({ value: o })\n else if (o && typeof o === 'object' && typeof (o as { value?: unknown }).value === 'string') {\n const rec = o as { value: string; label?: unknown }\n out.push({ value: rec.value, label: typeof rec.label === 'string' ? rec.label : undefined })\n }\n }\n return out.length ? out : undefined\n}\n\n/** The entity's fields as the card needs them. Anything the app already hides\n * from its own forms (`showInForm: false`) is hidden here too — the assistant\n * is not a back door around the app's own idea of what a person edits. */\nfunction cardFields(entity: { fields?: Array<Record<string, unknown>> }): PendingActionField[] {\n return (entity.fields ?? [])\n .filter((f) => f.showInForm !== false && !SYSTEM_FIELD_KEYS.has(String(f.key)))\n .map((f) => {\n const type = typeof f.type === 'string' ? f.type : undefined\n return {\n key: String(f.key),\n label: typeof f.label === 'string' ? f.label : undefined,\n type,\n required: f.required === true,\n options: normaliseOptions(f.options),\n placeholder: typeof f.placeholder === 'string' ? f.placeholder : undefined,\n hint: typeof f.hint === 'string' ? f.hint : undefined,\n min: typeof f.min === 'number' ? f.min : undefined,\n max: typeof f.max === 'number' ? f.max : undefined,\n default: f.defaultValue,\n // A computed value has no input, and a relation needs its option list\n // loaded from a table — neither is something to type into a chat card.\n readOnly: type === 'computed' || type === 'relation' || !!f.relation,\n }\n })\n}\nimport type { ConnectorIndex } from '../components/connect/connector-sources'\nimport type {\n EntityDef,\n OrgMember,\n Organization,\n PermissionAction,\n PermissionProfile,\n TeamPerson,\n} from '@fayz-ai/core'\nimport type { PluginAITool, PluginRegistryDef } from '../types/plugins'\n\n/**\n * Client-plane execution for the AI tool catalog.\n *\n * `useAITools()` declares *what* the surface can do — it is the catalog the\n * model reasons over. This module is *how*: the browser runs the call against\n * the session that is already open (org store, data providers, router) and\n * hands a serialized result back to the agent.\n *\n * The split matters because Fayz never holds the surface's data credentials.\n * The agent broker forwards the catalog, decides which tool to call, and\n * returns the call for the surface to execute — the same contract a\n * server-side channel (WhatsApp, email) satisfies with a server-side executor.\n *\n * **A capability is only advertised if it can run.** A declared tool with no\n * executor is a promise to the model the surface cannot keep: it burns\n * reasoning rounds retrying, then apologises. `buildAgentToolset` is the gate —\n * everything it returns has a resolvable executor.\n */\n\n/** An entity the executor can read through its own data provider. */\nexport interface DataToolTarget {\n label: string\n entity: EntityDef\n mockData?: Array<{ id: string }>\n /** Read-model (view/ledger): searchable/queryable but never writable. */\n readOnly?: boolean\n}\n\nexport interface AIToolExecutionContext {\n currentOrg: Organization | null\n members: OrgMember[]\n /**\n * Person-first team resolver — the same source the Team screen renders\n * (people of the configured `team.personKinds`, each with an OPTIONAL access\n * overlay). Absent when the app runs in legacy membership-only mode, in\n * which case `members` is the whole team.\n */\n loadTeam?: () => Promise<TeamPerson[]>\n currentPath: string\n /** Pages the surface exposes, used to resolve navigation requests. */\n routes: Array<{ path: string; label?: string }>\n navigate: (path: string) => void\n /**\n * Data-backed tools, keyed by the LLM-facing tool name. These execute\n * generically through the entity's own data provider, so every registry and\n * every CRUD entity the app declares is readable without a hand-written\n * handler — which is what lets a new vertical work on day one.\n */\n dataTools: Map<string, DataToolTarget>\n /**\n * The WRITE tools the agent can actually run this turn — what a refusal is\n * allowed to point at, with the action each performs. Read tools and\n * declared-but-unexecutable ones are excluded on purpose (\"use listLeads\" for\n * an update is worse advice than none), and the action matters just as much:\n * pointed at `updateLead` for a CREATE, the model called it with\n * `lead_id: \"N/A\"`.\n */\n writeTools?: Array<{ name: string; action?: string }>\n /**\n * What this app can be connected to, resolved lazily.\n *\n * A function and not a value: the sources behind it are two network reads,\n * and the assistant is mounted on every screen — paying for them on every\n * turn to answer a question nobody asked is not a trade worth making. Absent\n * when no plugin runtime is mounted, which drops `findConnectors` from the\n * catalog rather than answering it with an empty app.\n */\n loadConnectors?: () => Promise<ConnectorIndex>\n /**\n * The half of the catalog that does NOT ship this turn — what `findTools`\n * searches. Absent when everything already ships, which is also what\n * withdraws the search tool itself.\n */\n searchableTools?: PluginAITool[]\n /**\n * Tool names this turn already carries. `findTools` needs them to answer\n * \"you have it\" instead of \"it does not exist\" — see resolveToolSearch.\n */\n carriedTools?: string[]\n /**\n * Org-management writes the agent can perform — today only access profiles.\n * Narrowed to what is actually called: handing the executor the whole adapter\n * would let a future tool remove members from a chat turn.\n */\n orgAdapter?: {\n createProfile: (\n orgId: string,\n profile: Omit<PermissionProfile, 'id' | 'isSystem'>,\n ) => Promise<PermissionProfile>\n updateProfile?: (\n orgId: string,\n profileId: string,\n data: Partial<PermissionProfile>,\n ) => Promise<PermissionProfile>\n listProfiles?: (orgId: string) => Promise<PermissionProfile[]>\n } | null\n}\n\nexport type AIToolHandler = (\n args: Record<string, unknown>,\n context: AIToolExecutionContext,\n) => unknown | Promise<unknown>\n\nconst handlers = new Map<string, AIToolHandler>()\n\n/**\n * Register an executor for a tool, keyed by the tool's `name` (the identifier\n * the model calls, e.g. `getTeamMembers`). Plugins and apps call this to make\n * their declared `aiTools` actually runnable.\n */\nexport function registerAIToolHandler(name: string, handler: AIToolHandler): void {\n handlers.set(name, handler)\n}\n\nexport function registerAIToolHandlers(map: Record<string, AIToolHandler>): void {\n for (const [name, handler] of Object.entries(map)) registerAIToolHandler(name, handler)\n}\n\n/**\n * Remove an executor. Surface-scoped tools (a form builder's field ops) live\n * only while their screen is mounted; unregistering on unmount stops the model\n * from calling a tool whose live target no longer exists.\n */\nexport function unregisterAIToolHandler(name: string): void {\n handlers.delete(name)\n}\n\nexport function hasAIToolHandler(name: string): boolean {\n return handlers.has(name)\n}\n\n/** Rows returned per data call — enough to answer, cheap in tokens. */\nconst REGISTRY_PAGE_SIZE = 20\n\n/** A narrowed window (date range / filters) is answered from the whole set,\n * not from the first page — \"quantos atendimentos esta semana\" must not\n * depend on where the row happened to land in the default order. */\nconst FILTERED_PAGE_SIZE = 200\n\n/**\n * The agent never reads through the shared TTL cache.\n *\n * That cache is only invalidated by writes that pass through it, so an\n * appointment booked on the agenda screen (its own provider) left the\n * assistant answering from a snapshot up to a minute old — it reported \"nenhum\n * compromisso hoje\" over a booking made seconds earlier.\n */\nconst FRESH = { cache: false } as const\n\n/**\n * Interpret a date bound the way the user meant it.\n *\n * A bare `2026-07-27` means the BUSINESS day, not the UTC day: parsed as\n * \"2026-07-27T00:00:00\" it resolves in the surface's own timezone, which is\n * the business timezone. Sent as `...Z` instead, a 21h appointment in BRT\n * lands on the next UTC day and disappears from \"hoje\".\n */\nfunction localDayBound(value: string, edge: 'start' | 'end'): string {\n const dateOnly = /^\\d{4}-\\d{2}-\\d{2}$/.test(value.trim())\n if (!dateOnly) return value\n const time = edge === 'start' ? '00:00:00.000' : '23:59:59.999'\n const parsed = new Date(`${value.trim()}T${time}`)\n return Number.isNaN(parsed.getTime()) ? value : parsed.toISOString()\n}\n\n/** Build the provider-side range a `from`/`to` pair asks for. */\nfunction dateRangeFilter(args: Record<string, unknown>): { field: string; range: RangeFilter } | null {\n const from = typeof args.from === 'string' && args.from.trim() ? args.from.trim() : undefined\n const to = typeof args.to === 'string' && args.to.trim() ? args.to.trim() : undefined\n if (!from && !to) return null\n const field = typeof args.dateField === 'string' && args.dateField.trim()\n ? args.dateField.trim()\n : 'createdAt'\n const range: RangeFilter = {}\n if (from) range.gte = localDayBound(from, 'start')\n if (to) range.lte = localDayBound(to, 'end')\n return { field, range }\n}\n\n/** Beyond this the catalog costs more in tokens than it buys in capability.\n * A ceiling, not a budget: most turns ship far fewer now that the rest of the\n * catalog is reachable through `findTools` (see lib/tool-search.ts).\n * 36, not 28: with several standing surfaces mounted (setup, handbook, quick\n * actions) plus the open screen's own tools, 28 truncated the pinned band\n * itself — the menu screen's import tools were the ones cut. */\nconst MAX_TOOLS_PER_TURN = 36\n\nexport interface AIToolExecutionResult {\n ok: boolean\n /** JSON-serialized payload handed back to the agent. */\n content: string\n}\n\nfunction errorResult(error: string, message: string): AIToolExecutionResult {\n return { ok: false, content: JSON.stringify({ error, message }) }\n}\n\n/** The documented contract: every returned record carries a semantic ref\n * {id, resource, archetype} the surface can resolve to ITS OWN route — never\n * a URL (agents.md: presentation stays client knowledge). */\nfunction attachRefs(\n entity: EntityDef,\n rows: Array<Record<string, unknown>>,\n): Array<Record<string, unknown>> {\n const archetype = entity.data?.archetype\n if (!archetype) return rows\n const kind = entity.data?.archetypeKind\n const entityKey = deriveEntityKey(entity)\n return rows.map((r) =>\n r.id\n ? {\n ...r,\n ref: {\n id: r.id,\n resource: entity.data?.table,\n archetype: kind ? `${archetype}:${kind}` : archetype,\n entityKey,\n },\n }\n : r,\n )\n}\n\nfunction rowContainsText(row: Record<string, unknown>, needle: string): boolean {\n const n = needle.toLowerCase()\n return Object.values(row).some((v) => typeof v === 'string' && v.toLowerCase().includes(n))\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nasync function executeDataTool(\n target: DataToolTarget,\n args: Record<string, unknown>,\n): Promise<unknown> {\n const provider = resolveDataProvider(\n target.entity as EntityDef<{ id: string }>,\n target.mockData,\n FRESH,\n )\n const search = typeof args.search === 'string' && args.search.trim() ? args.search.trim() : undefined\n\n // A model that just opened a record searches for it by the id it saw. Text\n // search can never match that: the id column is a uuid, and every searchable\n // column is text, so the term matches nothing at best — and on an entity\n // whose search list includes a non-text column, Postgres rejects the whole\n // `ilike` clause and the lookup fails outright. Resolve the id directly.\n // The returned row is verified against the id asked for, so a provider that\n // ignores `filters` cannot pass a recent record off as the match.\n if (search && UUID_RE.test(search)) {\n try {\n const byId = await provider.list({ filters: { id: search }, pageSize: 1 })\n const row = (byId.data as Array<Record<string, unknown>>)[0]\n if (row && String(row.id) === search) {\n return {\n entity: target.label,\n search,\n total: 1,\n truncated: false,\n records: attachRefs(target.entity, [row]),\n }\n }\n } catch {\n // Fall through to the text search: an id lookup that errors is not worse\n // than the behaviour that shipped before it existed.\n }\n }\n\n // A date range goes to the DATABASE. Filtering it in memory only ever saw\n // one page, so \"o que tem hoje\" over a busy agenda answered from whichever\n // rows the default order happened to put first.\n const dateRange = dateRangeFilter(args)\n const result = await provider.list({\n search,\n pageSize: dateRange ? FILTERED_PAGE_SIZE : REGISTRY_PAGE_SIZE,\n ...(dateRange ? { filters: { [dateRange.field]: dateRange.range } } : {}),\n ...(typeof args.orderBy === 'string'\n ? { sortBy: args.orderBy, sortDir: args.direction === 'asc' ? 'asc' : 'desc' }\n : {}),\n })\n // Honesty guard: a provider with no searchable columns quietly IGNORES\n // `search` and returns recent rows — which the model then presents as the\n // thing it looked for (\"REC-00012 vale R$6000\" when no row matched at all).\n // If nothing in the returned rows contains the text, say so explicitly.\n let rows = result.data as Array<Record<string, unknown>>\n let total = result.total\n // Mock/legacy providers ignore `filters`. Re-apply the range here so a\n // provider that cannot narrow never hands back rows OUTSIDE the window the\n // user asked about.\n if (dateRange && rows.length) {\n const key = resolveFieldKey(rows[0], dateRange.field)\n if (!key) {\n return {\n error: 'unknown_field',\n message: `dateField \"${dateRange.field}\" does not exist on ${target.label}. Use one of the available fields and retry.`,\n availableFields: Object.keys(rows[0]),\n }\n }\n const narrowed = rows.filter((r) => matchesRange(r[key], dateRange.range))\n if (narrowed.length !== rows.length) total = narrowed.length\n rows = narrowed\n }\n const unmatched = !!search && rows.length > 0 && !rows.some((r) => rowContainsText(r, search))\n return {\n entity: target.label,\n ...(search ? { search } : {}),\n ...(dateRange ? { dateRange: { field: dateRange.field, ...dateRange.range } } : {}),\n total,\n // Truthful cap: the model is told the list was trimmed so it can say so\n // rather than presenting one page as the whole set.\n truncated: total > rows.length,\n records: attachRefs(target.entity, rows),\n ...(unmatched\n ? {\n warning:\n 'None of these rows contain the search text — they are RECENT records, not matches. Do NOT present them as the searched item; say it was not found or try another entity.',\n }\n : {}),\n }\n}\n\n/**\n * A read-only target is a DEAD END for the generic primitives, and a dead end\n * is where models improvise: asked to move an appointment, one answered the\n * `read_only` refusal by booking a SECOND appointment and leaving the first\n * standing. So the refusal names the dedicated tool for that entity when the\n * turn was offered one, and forbids the substitution outright.\n */\nfunction readOnlyRefusal(\n ctx: AIToolExecutionContext,\n target: DataToolTarget,\n verb: 'created' | 'updated',\n): { error: string; message: string; useInstead?: string[] } {\n const noun = target.entity.name.replace(/\\s+/g, '').toLowerCase()\n const plural = target.label.replace(/\\s+/g, '').toLowerCase()\n const wantedAction = verb === 'created' ? 'create' : 'edit'\n const candidates = (ctx.writeTools ?? [])\n .filter(({ name, action }) => {\n const n = name.toLowerCase()\n if (n === 'createrecord' || n === 'updaterecord') return false\n if (!n.includes(noun) && !n.includes(plural)) return false\n // Declared action wins; fall back to the verb the name starts with, for\n // tools that never declared a permission.\n if (action) return action === wantedAction\n return wantedAction === 'create' ? /^(create|add|new)/.test(n) : /^(update|edit|set|change|move)/.test(n)\n })\n .map((t) => t.name)\n return {\n error: 'read_only',\n message:\n `${target.label} is a read-only view — records cannot be ${verb} through this tool.` +\n (candidates.length\n ? ` Use ${candidates.join(' or ')} instead.`\n : ` This app has no tool that can change a ${target.entity.name.toLowerCase()}. Tell the user plainly that you cannot, and where in the app they can do it themselves.`) +\n ' Do NOT substitute a create: making a new record instead of changing the existing one leaves the original in place and duplicates it.',\n ...(candidates.length ? { useInstead: candidates } : {}),\n }\n}\n\n/** Tolerant field resolution: exact key, then camelCase, then snake_case. */\nfunction resolveFieldKey(row: Record<string, unknown>, name: string): string | null {\n if (name in row) return name\n const camel = name.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n if (camel in row) return camel\n const snake = name.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n if (snake in row) return snake\n return null\n}\n\n/**\n * Resolve ONE filter entry against a sample row.\n *\n * Returns a predicate, or an error the model can act on. The failure mode this\n * replaces was silent: a filter value the grammar did not recognise was\n * stringified and compared for equality, so `{$gte, $lt}` matched zero rows and\n * came back as a confident \"não há compromissos hoje\".\n */\nfunction resolveFilter(\n sample: Record<string, unknown>,\n label: string,\n name: string,\n value: unknown,\n): { key: string; test: (row: Record<string, unknown>) => boolean } | { error: string; message: string; availableFields?: string[] } {\n const key = resolveFieldKey(sample, name)\n if (!key) {\n return {\n error: 'unknown_field',\n message: `Filter field \"${name}\" does not exist on ${label}. Use one of the available fields and retry.`,\n availableFields: Object.keys(sample),\n }\n }\n const range = parseRangeFilter(value)\n if (range) return { key, test: (row) => matchesRange(row[key], range) }\n if (isFilterObject(value)) {\n return {\n error: 'invalid_filter',\n message:\n `Filter \"${name}\" is an object with no recognised bound. For a range use {\"from\":…,\"to\":…} ` +\n '(also accepted: gte/lte/gt/lt). For a date or period, prefer the from/to parameters of this tool instead of filters.',\n }\n }\n return { key, test: (row) => String(row[key] ?? '') === String(value) }\n}\n\nexport async function executeAITool(\n name: string,\n args: Record<string, unknown>,\n context: AIToolExecutionContext,\n): Promise<AIToolExecutionResult> {\n const handler = handlers.get(name)\n const dataTarget = context.dataTools.get(name)\n\n if (!handler && !dataTarget) {\n return errorResult(\n 'not_executable',\n `The tool \"${name}\" is not available here. Do not retry it — tell the user what you cannot do, or use a different tool.`,\n )\n }\n\n try {\n const result = handler\n ? await handler(args, context)\n : await executeDataTool(dataTarget!, args)\n return { ok: true, content: JSON.stringify(result ?? { ok: true }) }\n } catch (error) {\n return errorResult('execution_failed', describeThrown(error))\n }\n}\n\n/**\n * What actually failed, in words the model can act on.\n *\n * PostgREST rejections are plain objects ({code, message, hint, details}), not\n * Errors — so `error instanceof Error ? … : 'Unknown error'` reported every\n * database failure as \"Unknown error\". The model cannot correct a call it is\n * told nothing about, and neither can whoever reads the transcript: an `ilike`\n * against an integer column (42883) looked exactly like a network drop.\n */\nfunction describeThrown(error: unknown): string {\n if (error instanceof Error) return error.message\n if (error && typeof error === 'object') {\n const e = error as { message?: unknown; hint?: unknown; code?: unknown }\n const parts = [\n typeof e.message === 'string' ? e.message : null,\n typeof e.hint === 'string' ? e.hint : null,\n typeof e.code === 'string' ? `(${e.code})` : null,\n ].filter(Boolean)\n if (parts.length) return parts.join(' ')\n }\n return typeof error === 'string' && error ? error : 'Unknown error'\n}\n\n/**\n * Index everything readable by the tool name its generator mints, so the\n * executor can find the entity behind a call. Covers plugin registries and the\n * app's own CRUD entities.\n */\nexport function buildDataToolIndex(input: {\n registries: Map<string, PluginRegistryDef[]>\n entities: Array<{ entityKey: string; labelPlural: string; entityDef?: EntityDef; mockData?: Array<{ id: string }> }>\n registryToolName: (pluginId: string, registryId: string) => string\n entityToolName: (entityKey: string) => string\n queryEntities?: Array<{ key: string; entity: EntityDef; writable?: boolean }>\n}): Map<string, DataToolTarget> {\n const index = new Map<string, DataToolTarget>()\n\n for (const [pluginId, defs] of input.registries) {\n for (const registry of defs) {\n if (registry.readOnly) continue\n const target = {\n label: registry.entity.namePlural ?? registry.entity.name,\n entity: registry.entity as EntityDef,\n mockData: registry.mockData as Array<{ id: string }> | undefined,\n }\n index.set(input.registryToolName(pluginId, registry.id), target)\n // Key-indexed twin: the data primitives (searchRecords/queryData) receive\n // the TARGET as an argument instead of minting one tool per entity.\n index.set(`key:${pluginId}:${registry.id}`, target)\n }\n }\n\n for (const entity of input.entities) {\n if (!entity.entityDef || entity.entityDef.agentHidden) continue\n const target = {\n label: entity.labelPlural,\n entity: entity.entityDef,\n mockData: entity.mockData,\n }\n index.set(input.entityToolName(entity.entityKey), target)\n index.set(`key:${entity.entityKey}`, target)\n }\n\n // CORE_QUERY_ENTITIES merged here — same reason buildDataPrimitiveTools does\n // it: this index and that catalog MUST agree, or the model is offered an\n // entity the executor then rejects as unknown.\n for (const q of [...(input.queryEntities ?? []), ...CORE_QUERY_ENTITIES]) {\n index.set(`key:${q.key}`, {\n label: q.entity.namePlural ?? q.entity.name,\n entity: q.entity,\n readOnly: !q.writable,\n })\n }\n\n return index\n}\n\n// ---------------------------------------------------------------------------\n// Generic data primitives — ONE search + ONE aggregate over ANY entity. The\n// target's own read permission (EntityDef.permission) is checked per call, so\n// consolidating the catalog never widens access: the same role×plan engine\n// that gated the per-entity tools gates the parameterized target.\n// ---------------------------------------------------------------------------\n\n/**\n * The list open on screen, when it can write records the data primitives\n * cannot reach.\n *\n * An entity that lives behind a provider (the shop's coupons, its products)\n * publishes no table, so `createRecord` has nothing to resolve and answers\n * \"unknown entity\" — which read as a nuisance and got summarised as a success\n * story: the coupon was announced, with a code and a validity, and never\n * existed. An error has to say what to do instead, or the model invents an\n * ending.\n */\nfunction openListWriteHint(): string {\n const hasCreateHere = getSurfaceTools().some((t) => t.name === 'createRecordHere')\n return hasCreateHere\n ? ' The list the user has open CAN create this one: call `createRecordHere` with `values`, using the field keys in the screen state.'\n : ''\n}\n\nfunction resolveKeyedTarget(\n ctx: AIToolExecutionContext,\n args: Record<string, unknown>,\n): { target: DataToolTarget } | { error: unknown } {\n const key = typeof args.entity === 'string' ? args.entity : ''\n const target = ctx.dataTools.get(`key:${key}`)\n if (!target) {\n return {\n error: {\n ok: false,\n error: 'unknown_entity',\n // Said as plainly as it can be said: the failure above this one was a\n // reply that described a record nobody had written.\n message: `NOTHING WAS WRITTEN. No entity \"${key}\" is available to these tools — do not tell the user it worked.`\n + ` Use one of the keys listed in the tool description.${openListWriteHint()}`,\n },\n }\n }\n const permission = target.entity.permission\n if (permission) {\n const access = checkAccess(permission.feature, permission.action)\n if (!access.allowed) return { error: access }\n }\n return { target }\n}\n\n/** Field names are equal ignoring case and word separators, so a model sending\n * `postalCode` matches a `postal_code` column and vice versa. */\nfunction sameField(a: string, b: string): boolean {\n const norm = (s: string) => s.replace(/[_-]/g, '').toLowerCase()\n return norm(a) === norm(b)\n}\n\n/**\n * Match a call's `values` against the target entity's declared fields,\n * tolerating a snake_case/camelCase mismatch either way.\n *\n * Deliberately does NOT try to guess which other entity the caller \"meant\".\n * Scoring candidates by how many of the rejected field names they declare was\n * tried and is actively harmful here: for {address, city, postalCode, state,\n * country} the salon app's `location` and `local-de-atendimento` both score 5\n * against `address`'s 4, so \"add an address to this contact\" would be redirected\n * into creating a business LOCATION. Field names alone cannot tell a child\n * record from an unrelated table that happens to describe a place; the guidance\n * that does work is declared up front, in the tool description.\n */\nfunction matchDeclaredFields(\n target: DataToolTarget,\n values: Record<string, unknown>,\n): { clean: Record<string, unknown> } | { error: Record<string, unknown> } {\n const declaredKeys = (target.entity.fields ?? []).map((f) => f.key)\n const clean: Record<string, unknown> = {}\n const unknown: string[] = []\n for (const [k, v] of Object.entries(values)) {\n const match = declaredKeys.find((d) => sameField(d, k)) ?? null\n if (match) clean[match] = v\n else unknown.push(k)\n }\n if (!unknown.length) return { clean }\n\n return {\n error: {\n error: 'unknown_field',\n message: `Unknown field(s) ${unknown.join(', ')} for ${target.label}. Use only the available fields and retry.`,\n availableFields: declaredKeys,\n },\n }\n}\n\n/**\n * For every PERSON matched by a global search, pull the records that hang off\n * it (today: addresses) and return them grouped by entity key. Returns null\n * when nothing is attached, so the payload stays quiet in the common case.\n */\nasync function resolveAttachedRecords(\n ctx: AIToolExecutionContext,\n matches: Array<{ key: string; records: unknown[] }>,\n): Promise<Record<string, unknown[]> | null> {\n const ownerIds = new Set<string>()\n for (const m of matches) {\n const target = ctx.dataTools.get(`key:${m.key}`)\n if (target?.entity.data?.archetype !== 'person') continue\n for (const r of m.records) {\n const id = (r as { id?: unknown }).id\n if (typeof id === 'string') ownerIds.add(id)\n }\n }\n if (!ownerIds.size) return null\n\n const out: Record<string, unknown[]> = {}\n for (const q of CORE_QUERY_ENTITIES) {\n const target = ctx.dataTools.get(`key:${q.key}`)\n if (!target) continue\n const permission = target.entity.permission\n if (permission && !checkAccess(permission.feature, permission.action).allowed) continue\n try {\n const provider = resolveDataProvider(target.entity as EntityDef<{ id: string }>, target.mockData)\n const result = await provider.list({ pageSize: 50 })\n const rows = (result.data as Array<Record<string, unknown>>).filter((row) => {\n const owner = row.ownerId ?? row.owner_id\n return typeof owner === 'string' && ownerIds.has(owner)\n })\n if (rows.length) out[q.key] = rows\n } catch {\n // An attachment lookup must never sink the search it decorates.\n }\n }\n return Object.keys(out).length ? out : null\n}\n\nregisterAIToolHandler('findAnything', async (args, ctx) => {\n const search = typeof args.search === 'string' ? args.search.trim() : ''\n if (!search) return { error: 'missing_search', message: 'Provide the name or text to look up.' }\n\n // Deduped key-indexed targets, permission-filtered PER TARGET (the palette\n // semantics: what you cannot see is not searched), person-archetypes first —\n // \"quem é X?\" is a person question far more often than not.\n const seen = new Set<DataToolTarget>()\n const candidates: Array<{ key: string; target: DataToolTarget }> = []\n for (const [key, target] of ctx.dataTools) {\n if (!key.startsWith('key:') || seen.has(target)) continue\n seen.add(target)\n candidates.push({ key: key.slice(4), target })\n }\n let skippedForPermission = 0\n const allowed = candidates.filter(({ target }) => {\n const permission = target.entity.permission\n if (!permission) return true\n if (checkAccess(permission.feature, permission.action).allowed) return true\n skippedForPermission += 1\n return false\n })\n allowed.sort((a, b) => {\n const ap = a.target.entity.data?.archetype === 'person' ? 0 : 1\n const bp = b.target.entity.data?.archetype === 'person' ? 0 : 1\n return ap - bp || a.key.localeCompare(b.key)\n })\n\n const MAX_TARGETS = 20\n const searched = allowed.slice(0, MAX_TARGETS)\n const settled = await Promise.allSettled(\n searched.map(async ({ key, target }) => {\n const provider = resolveDataProvider(\n target.entity as EntityDef<{ id: string }>,\n target.mockData,\n )\n const result = await provider.list({ search, pageSize: 5 })\n return {\n key,\n label: target.label,\n total: result.total,\n records: attachRefs(target.entity, result.data as Array<Record<string, unknown>>),\n }\n }),\n )\n const matches = settled\n .filter((r) => r.status === 'fulfilled' && r.value.records.length > 0)\n .map((r) => (r as PromiseFulfilledResult<{ key: string; label: string; total: number; records: unknown[] }>).value)\n\n // Attached records travel WITH their owner. A person's address lives in its\n // own table keyed by owner_id, so a text search for \"Doguez\" can never return\n // it — and telling the model to make a second, filtered call is a hope, not a\n // mechanism: it answers \"this contact has no address registered\" instead,\n // which is false. Resolving them here makes the answer correct by\n // construction. One extra query, only when a person actually matched.\n const attached = await resolveAttachedRecords(ctx, matches)\n\n return {\n query: search,\n matches,\n ...(attached ? { attached } : {}),\n searchedEntities: searched.length,\n ...(allowed.length > MAX_TARGETS ? { targetsTruncated: true } : {}),\n ...(skippedForPermission ? { skippedForPermission } : {}),\n ...(matches.length === 0\n ? { hint: 'No records matched anywhere the user can see. Say so — do not retry other search tools with the same text.' }\n : {}),\n }\n})\n\nregisterAIToolHandler('createRecord', async (args, ctx) => {\n const resolved = resolveKeyedTarget(ctx, args)\n if ('error' in resolved) return resolved.error\n const { target } = resolved\n if (target.readOnly) return readOnlyRefusal(ctx, target, 'created')\n\n // Guard chain, in the broker's order: role×plan for CREATE → plan cap →\n // field validation → human confirmation → write → invalidate the count.\n const permission = target.entity.permission\n if (permission) {\n const access = checkAccess(permission.feature, 'create')\n if (!access.allowed) return access\n }\n if (target.entity.limitKey) {\n const limit = await guardLimit(target.entity.limitKey)\n if (!limit.allowed) return limit\n }\n\n const values = (args.values ?? {}) as Record<string, unknown>\n const declared = target.entity.fields ?? []\n const matched = matchDeclaredFields(target, values)\n if ('error' in matched) return matched.error\n const { clean } = matched\n const isEmpty = (v: unknown) => v === undefined || v === null || v === ''\n const missingRequired = declared.filter((f) => f.required && isEmpty(clean[f.key]))\n // A required field the CARD can't collect — a relation/computed the model must\n // resolve to an id first — still bounces back so the model can search for it.\n // But a plain required field the user can just TYPE (name, phone…) is not a\n // reason to interrogate them turn-by-turn: open the form and let them fill it\n // there, alongside everything else.\n const mustResolveFirst = missingRequired.filter(\n (f) => f.type === 'computed' || f.type === 'relation' || !!f.relation || f.showInForm === false,\n )\n if (mustResolveFirst.length) {\n return {\n error: 'missing_required',\n message: `Missing required field(s) that must be resolved to a record first: ${mustResolveFirst\n .map((f) => f.key)\n .join(', ')}. Look them up (search for the referenced record), then retry.`,\n availableFields: declared.map((f) => f.key),\n }\n }\n\n // Duplicate guard: same-name record already existing comes back as a\n // structured warning FIRST — the model confirms intent with the user and\n // retries with allowDuplicate:true only if they really want a second one.\n const dupName = typeof clean.name === 'string' ? clean.name.trim() : ''\n if (dupName && args.allowDuplicate !== true) {\n const provider0 = resolveDataProvider(\n target.entity as EntityDef<{ id: string }>,\n target.mockData,\n )\n const existing = await provider0.list({ search: dupName, pageSize: 3 })\n const dupes = (existing.data as Array<Record<string, unknown>>).filter(\n (r) => String(r.name ?? '').trim().toLowerCase() === dupName.toLowerCase(),\n )\n if (dupes.length) {\n return {\n error: 'possible_duplicate',\n message: `A ${target.entity.name} named \"${dupName}\" already exists. If the user wants to CHANGE that existing record, use updateRecord with its id; only retry createRecord with allowDuplicate:true if they explicitly want a second one.`,\n matches: dupes,\n }\n }\n }\n\n const decision = await requestChatConfirmation({\n id: `create-${Date.now()}`,\n toolName: 'createRecord',\n title: `Criar ${target.entity.name}`,\n params: clean,\n plane: 'client',\n // Scoped grant: \"always create clients\", never \"always create anything\".\n scope: typeof args.entity === 'string' ? args.entity : undefined,\n scopeLabel: `Criar ${target.entity.name}`,\n fields: cardFields(target.entity as never),\n })\n const approved = decision.approved\n // The card is the last word: whatever the user corrected there is what gets\n // written, not what the model guessed.\n if (decision.values) {\n for (const key of Object.keys(clean)) delete clean[key]\n Object.assign(clean, decision.values)\n }\n if (!approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n\n // The card blocks confirm while a required field is empty, so this is only a\n // backstop — never write a record the entity would reject.\n const stillMissing = declared.filter((f) => f.required && isEmpty(clean[f.key])).map((f) => f.key)\n if (stillMissing.length) {\n return {\n error: 'missing_required',\n message: `Still missing required field(s): ${stillMissing.join(', ')}. Ask the user for them, then retry.`,\n availableFields: declared.map((f) => f.key),\n }\n }\n\n const provider = resolveDataProvider(\n target.entity as EntityDef<{ id: string }>,\n target.mockData,\n )\n const record = await provider.create(clean as never)\n if (target.entity.limitKey) invalidateLimit(target.entity.limitKey)\n // The list behind the chat is showing this table right now — tell it.\n emitDataChanged({\n table: target.entity.data?.table,\n entityKey: typeof args.entity === 'string' ? args.entity : undefined,\n archetype: target.entity.data?.archetype,\n op: 'create',\n id: (record as { id?: string }).id,\n source: 'agent',\n })\n return {\n ok: true,\n record,\n ref: {\n id: (record as { id?: string }).id,\n label: String((record as Record<string, unknown>).name ?? target.entity.name),\n resource: target.entity.data?.table,\n archetype: target.entity.data?.archetype\n ? `${target.entity.data.archetype}${target.entity.data.archetypeKind ? ':' + target.entity.data.archetypeKind : ''}`\n : undefined,\n entityKey: deriveEntityKey(target.entity),\n },\n }\n})\n\nregisterAIToolHandler('updateRecord', async (args, ctx) => {\n const resolved = resolveKeyedTarget(ctx, args)\n if ('error' in resolved) return resolved.error\n const { target } = resolved\n if (target.readOnly) return readOnlyRefusal(ctx, target, 'updated')\n const id = typeof args.id === 'string' ? args.id : ''\n if (!id) return { error: 'missing_id', message: 'Provide the id of the record to update (from this conversation or a search).' }\n\n // Same guard chain as createRecord, with the EDIT action; updates never\n // consume plan caps.\n const permission = target.entity.permission\n if (permission) {\n const access = checkAccess(permission.feature, 'edit')\n if (!access.allowed) return access\n }\n\n const values = (args.values ?? {}) as Record<string, unknown>\n const matched = matchDeclaredFields(target, values)\n if ('error' in matched) return matched.error\n const { clean } = matched\n if (!Object.keys(clean).length) {\n return { error: 'empty_update', message: 'No valid fields to change were provided.' }\n }\n\n const decision = await requestChatConfirmation({\n id: `update-${Date.now()}`,\n toolName: 'updateRecord',\n title: `Atualizar ${target.entity.name}`,\n params: { id, ...clean },\n plane: 'client',\n scope: typeof args.entity === 'string' ? args.entity : undefined,\n scopeLabel: `Atualizar ${target.entity.name}`,\n fields: cardFields(target.entity as never),\n partial: true,\n })\n if (!decision.approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n if (decision.values) {\n for (const key of Object.keys(clean)) delete clean[key]\n for (const [k, v] of Object.entries(decision.values)) if (k !== 'id') clean[k] = v\n }\n\n const provider = resolveDataProvider(\n target.entity as EntityDef<{ id: string }>,\n target.mockData,\n )\n const record = await provider.update(id, clean as never)\n emitDataChanged({\n table: target.entity.data?.table,\n entityKey: typeof args.entity === 'string' ? args.entity : undefined,\n archetype: target.entity.data?.archetype,\n op: 'update',\n id,\n source: 'agent',\n })\n return {\n ok: true,\n record,\n ref: {\n id,\n label: String((record as Record<string, unknown>).name ?? target.entity.name),\n resource: target.entity.data?.table,\n archetype: target.entity.data?.archetype\n ? `${target.entity.data.archetype}${target.entity.data.archetypeKind ? ':' + target.entity.data.archetypeKind : ''}`\n : undefined,\n entityKey: deriveEntityKey(target.entity),\n },\n }\n})\n\nregisterAIToolHandler('searchRecords', async (args, ctx) => {\n const resolved = resolveKeyedTarget(ctx, args)\n if ('error' in resolved) return resolved.error\n const base = (await executeDataTool(resolved.target, args)) as {\n records: Array<Record<string, unknown>>\n [k: string]: unknown\n }\n if ('error' in base) return base\n const filters = (args.filters ?? {}) as Record<string, unknown>\n const keys = Object.keys(filters)\n if (!keys.length) return base\n let rows = base.records\n for (const k of keys) {\n const sample = rows[0] ?? base.records[0]\n if (!sample) break\n const f = resolveFilter(sample, resolved.target.label, k, filters[k])\n if ('error' in f) return f\n rows = rows.filter(f.test)\n }\n return {\n ...base,\n records: rows,\n filtered: keys,\n total: rows.length,\n // A filter that empties a non-empty page is ambiguous — \"no record matches\"\n // and \"the filter was wrong\" look identical to the model, and it picks the\n // first. Name the difference so it can retry instead of asserting absence.\n ...(rows.length === 0 && base.records.length > 0\n ? {\n warning:\n `${base.records.length} record(s) were read but the filters ${JSON.stringify(filters)} excluded all of them. ` +\n 'Check the filter values against the fields on those records before telling the user nothing exists.',\n }\n : {}),\n }\n})\n\n/**\n * Turn an attached file's columns into a mapping the user can correct.\n *\n * Written as a TOOL, not as prose, on purpose. Asked to write the mapping out\n * as text, gpt-4o-mini emitted three lines of eighteen (copied from the\n * example), then one, then stopped to \"continue with the next columns\". A\n * mapping is structured data: the schema constrains the model's output, and the\n * confirmation card — which already renders a field list with selects — turns\n * the result into a form instead of a paragraph.\n */\nregisterAIToolHandler('proposeImport', async (args, ctx) => {\n const resolved = resolveKeyedTarget(ctx, args)\n if ('error' in resolved) return resolved.error\n const { target } = resolved\n\n const fileName = typeof args.file === 'string' ? args.file : undefined\n const digest = resolveAttachmentDigest(fileName)\n if (!digest) {\n const names = listAttachmentNames()\n // An honest refusal names what IS attached. This tool only reads files with\n // columns, and the old message said \"attach a CSV\" while a photo the user\n // had just attached sat on screen — the assistant denying a file everyone\n // could see. A photo is not a failed import: it is read by looking at it.\n const other = nonTabularAttachmentNames()\n return {\n error: 'no_file',\n message: names.length\n ? `No readable file called \"${fileName ?? ''}\". Attached right now: ${names.join(', ')}.`\n : other.length\n ? `${other.join(', ')} is attached, but it has no columns — importing is for spreadsheets and CSVs. `\n + 'If it is a photo or a scan, READ IT: it is in front of you, so answer from what is written on it '\n + 'and use the tool that matches what the user asked for. Do not ask for a CSV.'\n : 'There is no file attached to this conversation. Ask the user to attach a CSV or a spreadsheet.',\n }\n }\n\n const headers = (digest.headers ?? []).filter((h) => h.trim())\n const fields = (target.entity.fields ?? []).filter(\n (f) => f.showInForm !== false && !SYSTEM_FIELD_KEYS.has(String(f.key)),\n )\n const fieldKeys = new Set(fields.map((f) => String(f.key)))\n\n // The model's proposal is a suggestion, not an instruction: a column it\n // invented or a field that does not exist would otherwise reach the card as\n // an option nobody can act on.\n const proposed = (args.mapping ?? {}) as Record<string, unknown>\n const accepted: Record<string, unknown> = {}\n const rejected: string[] = []\n for (const [column, field] of Object.entries(proposed)) {\n if (!headers.includes(column)) {\n rejected.push(`column \"${column}\" is not in the file`)\n continue\n }\n if (typeof field !== 'string' || !fieldKeys.has(field)) {\n rejected.push(`\"${column}\" → \"${String(field)}\" is not a field of ${target.label}`)\n continue\n }\n accepted[column] = field\n }\n\n const options = [\n ...fields.map((f) => ({ value: String(f.key), label: (f.label as string) ?? String(f.key) })),\n ]\n const decision = await requestChatConfirmation({\n id: `import-${digest.name}`,\n toolName: 'proposeImport',\n title: `${digest.name} → ${target.label}`,\n params: accepted,\n plane: 'client',\n scope: typeof args.entity === 'string' ? args.entity : undefined,\n scopeLabel: `Importar para ${target.label}`,\n // One row per column of the FILE, so a column the model skipped is visibly\n // unmapped instead of silently absent.\n fields: headers.map((header) => ({\n key: header,\n label: header,\n options,\n hint: digest.columnTypes?.find((c) => c.name === header)?.note,\n })),\n partial: true,\n })\n if (!decision.approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n\n const mapping = (decision.values ?? accepted) as Record<string, string>\n const mapped = Object.keys(mapping).length\n return {\n ok: true,\n file: digest.name,\n entity: target.label,\n rows: digest.rowCount,\n mapping,\n unmapped: headers.filter((h) => !mapping[h]),\n ...(rejected.length ? { ignoredFromYourProposal: rejected } : {}),\n nextStep: 'commitImport',\n message:\n `The user confirmed the mapping: ${mapped} of ${headers.length} columns are mapped for ${digest.rowCount ?? '?'} rows. ` +\n 'NOW CALL commitImport with this exact mapping to write the rows — that is the next and final step, and the user is waiting for it. ' +\n 'Do not announce it, do not ask again, and do not repeat the mapping back line by line.',\n }\n})\n\n/**\n * Write the file's rows. The end of the import path, and the only step that\n * touches the database.\n *\n * Three things it does that a loop over createRecord would not:\n * the plan cap is consulted ONCE for the whole batch (asking 900 times is 900\n * round-trips and 900 chances to half-import); every row carries an\n * `importBatchId` so \"desfaz essa importação\" is one delete instead of a\n * support ticket; and failures come back with their row number rather than\n * aborting the other 898.\n */\nregisterAIToolHandler('commitImport', async (args, ctx) => {\n const resolved = resolveKeyedTarget(ctx, args)\n if ('error' in resolved) return resolved.error\n const { target } = resolved\n\n const digest = resolveAttachmentDigest(typeof args.file === 'string' ? args.file : undefined)\n if (!digest) {\n return {\n error: 'no_file',\n message: 'The file is no longer in this conversation. Ask the user to attach it again.',\n }\n }\n\n const mapping = (args.mapping ?? {}) as Record<string, string>\n const columns = Object.keys(mapping).filter((c) => typeof mapping[c] === 'string' && mapping[c])\n if (!columns.length) {\n return {\n error: 'empty_mapping',\n message: 'No column is mapped. Run proposeImport first and pass the mapping it returns.',\n }\n }\n\n const permission = target.entity.permission\n if (permission) {\n const access = checkAccess(permission.feature, 'create')\n if (!access.allowed) return access\n }\n\n let rows: Array<Record<string, string>>\n try {\n rows = await readAllRows(digest)\n } catch (error) {\n return { error: 'unreadable', message: error instanceof Error ? error.message : 'Could not read the file.' }\n }\n\n const records = rows\n .map((row) => {\n const record: Record<string, unknown> = {}\n for (const column of columns) {\n const value = row[column]\n if (value !== undefined && value !== '') record[mapping[column]] = value\n }\n return record\n })\n .filter((r) => Object.keys(r).length)\n\n if (!records.length) {\n return { error: 'no_rows', message: 'Every row is empty under this mapping. Check the column names.' }\n }\n\n // ONE cap check for the batch. Per-row would be N round-trips and would leave\n // a half-import behind when it trips in the middle.\n if (target.entity.limitKey) {\n const limit = await guardLimit(target.entity.limitKey, records.length)\n if (!limit.allowed) return limit\n }\n\n const decision = await requestChatConfirmation({\n id: `commit-${digest.name}`,\n toolName: 'commitImport',\n title: `Importar ${records.length} × ${target.entity.name}`,\n params: {\n arquivo: digest.name,\n registros: records.length,\n campos: columns.map((c) => `${c} → ${mapping[c]}`).join(', '),\n },\n plane: 'client',\n scope: typeof args.entity === 'string' ? args.entity : undefined,\n scopeLabel: `Importar ${target.label}`,\n })\n if (!decision.approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n\n // Stamped only where there is a column to hold it — an entity without one\n // would reject every row over an unknown column, which is a far worse\n // outcome than not being able to undo.\n const batchId = `imp-${Date.now().toString(36)}`\n const canStamp = (target.entity.fields ?? []).some((f) => String(f.key) === 'importBatchId')\n const provider = resolveDataProvider(target.entity as EntityDef<{ id: string }>, target.mockData, FRESH)\n const result = await bulkCreate(\n provider,\n (canStamp ? records.map((r) => ({ ...r, importBatchId: batchId })) : records) as never,\n { chunkSize: 200 },\n )\n\n emitDataChanged({\n table: target.entity.data?.table,\n entityKey: typeof args.entity === 'string' ? args.entity : undefined,\n archetype: target.entity.data?.archetype,\n op: 'create',\n source: 'agent',\n })\n if (target.entity.limitKey) invalidateLimit(target.entity.limitKey)\n\n return {\n ok: result.created > 0,\n ...(canStamp ? { batchId } : {}),\n created: result.created,\n failed: result.failed.length,\n // Row numbers, not row contents — the model never needs the data, and a\n // failure list of 200 rows would swamp the turn.\n firstErrors: result.failed.slice(0, 5).map((f) => ({ row: f.index + 2, reason: f.message })),\n message:\n `${result.created} of ${records.length} rows were created` +\n (result.failed.length\n ? `. ${result.failed.length} failed — tell the user which rows and why, and offer to fix and retry those.`\n : '. Tell the user it is done.'),\n }\n})\n\nregisterAIToolHandler('queryData', async (args, ctx) => {\n const resolved = resolveKeyedTarget(ctx, args)\n if ('error' in resolved) return resolved.error\n const { target } = resolved\n\n const metric = args.metric === 'sum' || args.metric === 'avg' ? args.metric : 'count'\n let field = typeof args.field === 'string' ? args.field : undefined\n if (metric !== 'count' && !field) {\n return { error: 'missing_field', message: `metric \"${metric}\" needs a \"field\" to aggregate.` }\n }\n\n const provider = resolveDataProvider(\n target.entity as EntityDef<{ id: string }>,\n target.mockData,\n FRESH,\n )\n // The date range is pushed to the provider so the 1000-row window applies to\n // the PERIOD asked about, not to the table as a whole — a sum over \"this\n // week\" must not be capped by rows outside it. `sampled` still reports a\n // window that truncated. The S4 server-plane executor replaces this with SQL.\n const dateRange = dateRangeFilter(args)\n const page = await provider.list({\n pageSize: 1000,\n ...(dateRange ? { filters: { [dateRange.field]: dateRange.range } } : {}),\n })\n let rows = page.data as Array<Record<string, unknown>>\n\n // Field references FAIL LOUD: a typo'd/unknown field must never silently\n // filter everything to zero (\"Não há agendamentos\" over a wrong key). The\n // error carries the row's real keys so the model self-corrects next round.\n const sampleRow = rows[0]\n const availableFields = sampleRow ? Object.keys(sampleRow) : []\n const requireField = (name: string): string | { error: string; message: string; availableFields: string[] } => {\n if (!sampleRow) return name\n const resolved = resolveFieldKey(sampleRow, name)\n if (resolved) return resolved\n return {\n error: 'unknown_field',\n message: `Field \\\"${name}\\\" does not exist on ${target.label}. Use one of the available fields and retry.`,\n availableFields,\n }\n }\n\n // Re-applied here too: a provider that ignored `filters` would otherwise\n // aggregate the whole table under a period label.\n if (dateRange) {\n const resolved = requireField(dateRange.field)\n if (typeof resolved !== 'string') return resolved\n rows = rows.filter((r) => matchesRange(r[resolved], dateRange.range))\n }\n\n const filters = (args.filters ?? {}) as Record<string, unknown>\n for (const [k, v] of Object.entries(filters)) {\n if (!sampleRow) break\n const f = resolveFilter(sampleRow, target.label, k, v)\n if ('error' in f) return f\n rows = rows.filter(f.test)\n }\n\n const aggregate = (subset: Array<Record<string, unknown>>) => {\n if (metric === 'count') return subset.length\n const values = subset\n .map((r) => Number(r[field!]))\n .filter((n) => !Number.isNaN(n))\n const sum = values.reduce((a, b) => a + b, 0)\n if (metric === 'sum') return Math.round(sum * 100) / 100\n return values.length ? Math.round((sum / values.length) * 100) / 100 : 0\n }\n\n if (field && rows[0]) {\n const resolved = resolveFieldKey(rows[0], field)\n if (!resolved) {\n return {\n error: 'unknown_field',\n message: `Field \"${field}\" does not exist on ${target.label}. Use one of the available fields and retry.`,\n availableFields,\n }\n }\n field = resolved\n }\n let groupBy = typeof args.groupBy === 'string' ? args.groupBy : undefined\n if (groupBy && rows[0]) {\n const resolved = resolveFieldKey(rows[0], groupBy)\n if (!resolved) {\n return {\n error: 'unknown_field',\n message: `Field \"${groupBy}\" does not exist on ${target.label}. Use one of the available fields and retry.`,\n availableFields,\n }\n }\n groupBy = resolved\n }\n const sampled = page.total > page.data.length\n if (groupBy) {\n const groups = new Map<string, Array<Record<string, unknown>>>()\n for (const r of rows) {\n const g = String(r[groupBy] ?? '—')\n if (!groups.has(g)) groups.set(g, [])\n groups.get(g)!.push(r)\n }\n // A group key like professionalId is opaque to the user — attach the\n // sibling display field (professionalName) when the rows carry one.\n const labelKey = groupBy.endsWith('Id')\n ? resolveFieldKey(rows[0] ?? {}, groupBy.slice(0, -2) + 'Name')\n : null\n return {\n entity: target.label,\n metric,\n ...(field ? { field } : {}),\n groupBy,\n groups: Array.from(groups.entries())\n .map(([group, subset]) => ({\n group,\n ...(labelKey && subset[0] ? { label: subset[0][labelKey] } : {}),\n value: aggregate(subset),\n rows: subset.length,\n }))\n .sort((a, b) => Number(b.value) - Number(a.value)),\n matchedRows: rows.length,\n sampled,\n }\n }\n return {\n entity: target.label,\n metric,\n ...(field ? { field } : {}),\n value: aggregate(rows),\n matchedRows: rows.length,\n sampled,\n }\n})\n\nexport interface AgentTool {\n name: string\n description: string\n parameters?: Record<string, unknown>\n}\n\nexport interface BuildToolsetOptions {\n dataTools: Map<string, DataToolTarget>\n /** Plugin owning the current route; its tools rank ahead of the rest. */\n activePluginId?: string | null\n /** Tool names this turn carries whatever the question is: the primitives and\n * whatever the open screen published. */\n pinned?: ReadonlySet<string>\n /** Tool names the agent asked for with `findTools`, earlier in this\n * conversation. Ranked above route context — an explicit ask must not lose\n * its place to the screen the user happens to be on. */\n loaded?: ReadonlySet<string>\n maxTools?: number\n}\n\n/**\n * Shape the declared catalog into the toolset sent to the agent THIS round.\n *\n * Three filters, all load-bearing:\n *\n * 1. *Executable only.* An advertised tool with no executor is worse than a\n * missing one — the model spends rounds on it and then apologises.\n * 2. *Carried or asked for.* One agent owns everything the app does, so the\n * catalog is now the whole app (~40 tools, ~55k characters in a mature\n * one). What ships is the primitives, what the open screen published, what\n * `findTools` was asked for, and the current route's plugin — the rest stays\n * reachable rather than resident. Without a `pinned` set this degrades to\n * the old behaviour: everything, ranked by route.\n * 3. *Capped.* A last ceiling, in the order above, so a runaway index cannot\n * silently undo the point of the exercise.\n */\nexport function buildAgentToolset(\n tools: PluginAITool[],\n { dataTools, activePluginId, pinned, loaded, maxTools = MAX_TOOLS_PER_TURN }: BuildToolsetOptions,\n): AgentTool[] {\n const executable = tools.filter(\n (t) =>\n handlers.has(t.name) ||\n dataTools.has(t.name) ||\n (t.execution?.plane === 'server' && t.execution.kind === 'rpc'),\n )\n\n const ofPlugin = (t: PluginAITool) => !!activePluginId && t.id.startsWith(`${activePluginId}.`)\n // Within the pinned band the cap can still bite, so the band itself is\n // ordered by how much the turn needs each tool: the primitives (always-on +\n // findTools) first — losing findTools closes the door to everything else —\n // then the surfaces in catalog order, which getSurfaceTools already sorts\n // open-screen-first. Stable sort keeps the catalog order within each rank.\n const CORE_PINNED = new Set([...ALWAYS_ON_TOOLS, 'findTools'])\n const pinnedBand = executable\n .filter((t) => pinned?.has(t.name))\n .sort((a, b) => (CORE_PINNED.has(a.name) ? 0 : 1) - (CORE_PINNED.has(b.name) ? 0 : 1))\n const ranked = pinned\n ? [\n ...pinnedBand,\n ...executable.filter((t) => !pinned.has(t.name) && loaded?.has(t.name)),\n ...executable.filter((t) => !pinned.has(t.name) && !loaded?.has(t.name) && ofPlugin(t)),\n ]\n : activePluginId\n ? [...executable.filter(ofPlugin), ...executable.filter((t) => !ofPlugin(t))]\n : executable\n\n return ranked.slice(0, maxTools).map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters as Record<string, unknown> | undefined,\n }))\n}\n\n// ---------------------------------------------------------------------------\n// Core handlers — the executable counterpart of `coreAITools`.\n// ---------------------------------------------------------------------------\n\n/**\n * The team, as the Team screen defines it.\n *\n * Person-first apps (`team.personKinds` configured) staff their workspace with\n * PEOPLE — a teacher or stylist is on the team whether or not they ever log in;\n * `tenant_members` is just the access overlay on top. Reading memberships alone\n * answered \"who is on my team?\" with the single owner row while the Team screen\n * listed six, so the tool now resolves the same source the screen renders and\n * only falls back to memberships in legacy mode.\n */\nasync function resolveTeamRows(ctx: AIToolExecutionContext): Promise<\n Array<{ name: string | null; kind?: string; email: string | null; accessRole: string | null; hasLogin: boolean }>\n> {\n if (ctx.loadTeam) {\n const team = await ctx.loadTeam()\n return team.map((p) => ({\n name: p.name ?? null,\n kind: p.kind,\n email: p.email ?? null,\n accessRole: p.membership?.profileName ?? null,\n hasLogin: !!p.membership,\n }))\n }\n // Legacy: every team member IS a membership row. `profileName` is the RBAC\n // role, never the person's name — reporting it as `name` is what made the\n // assistant answer \"one person, with the role of Owner\".\n return ctx.members.map((m) => ({\n name: m.user?.fullName ?? null,\n email: m.user?.email ?? null,\n accessRole: m.profileName ?? null,\n hasLogin: true,\n }))\n}\n\nregisterAIToolHandler('getBusinessSummary', async (_args, ctx) => {\n if (!ctx.currentOrg) return { error: 'no_active_business' }\n const org = ctx.currentOrg as Organization & { plan?: string; verticalId?: string }\n return {\n name: org.name,\n slug: org.slug,\n plan: org.plan ?? null,\n vertical: org.verticalId ?? null,\n teamSize: (await resolveTeamRows(ctx)).length,\n createdAt: org.createdAt ?? null,\n }\n})\n\nregisterAIToolHandler('getTeamMembers', async (args, ctx) => {\n const filter = typeof args.role === 'string' ? args.role.trim().toLowerCase() : undefined\n const rows = await resolveTeamRows(ctx)\n // One filter, two vocabularies: users say \"os professores\" (the person kind)\n // and \"os admins\" (the access role) with the same word shape.\n const members = filter\n ? rows.filter(\n (r) =>\n String(r.kind ?? '').toLowerCase() === filter ||\n String(r.accessRole ?? '').toLowerCase() === filter,\n )\n : rows\n return { total: members.length, members }\n})\n\nregisterAIToolHandler('navigateTo', (args, ctx) => {\n const query = typeof args.page === 'string' ? args.page.trim().toLowerCase() : ''\n if (!query) return { error: 'missing_page' }\n\n // Substring matching sent \"vai pra pagina dela\" to the Painel and then\n // REPORTED SUCCESS. A wrong page announced as done is worse than no page, so\n // a loose match now fails and hands back the list to choose from.\n const match =\n ctx.routes.find((r) => r.path.toLowerCase() === query || r.path.toLowerCase() === `/${query}`) ??\n ctx.routes.find((r) => (r.label ?? '').toLowerCase() === query) ??\n ctx.routes.find((r) => {\n const label = (r.label ?? '').toLowerCase()\n return !!label && (label.startsWith(query) || query.startsWith(label))\n })\n\n if (!match) {\n return {\n error: 'page_not_found',\n message: 'No page matches that. If the user meant a specific record, look it up and call openRecord with its id.',\n availablePages: ctx.routes.map((r) => r.label ?? r.path),\n }\n }\n\n ctx.navigate(match.path)\n // Levar alguém a uma página e continuar cobrindo a página é não ter levado.\n // Ver revealPage: só no celular, e só depois que o turno termina.\n revealPage()\n return { navigatedTo: match.path, label: match.label ?? match.path }\n})\n\nregisterAIToolHandler('openRecord', async (args, ctx) => {\n const id = typeof args.id === 'string' ? args.id.trim() : ''\n if (!id) return { error: 'missing_id', message: 'Provide the record id returned by an earlier tool.' }\n\n // The record is ALREADY on screen — the model read its id off the route it\n // was given. Navigating there is a no-op, and calling it an error made the\n // model spend a round recovering from something that had already succeeded.\n if (ctx.currentPath.includes(id)) {\n return {\n alreadyOpen: true,\n message:\n 'This record is already the page the user is looking at — nothing to navigate. To talk about it, read it with searchRecords filtered by this id.',\n }\n }\n\n const ref = lookupRecordRef(id)\n if (!ref) {\n return {\n error: 'unknown_record',\n message: 'That id was not seen in this conversation. Search for the record first, then call openRecord with the id from the result.',\n }\n }\n if (!resolveEntityRoute(ref.archetype, ref.kind, ref.entityKey)) {\n return { error: 'no_page_for_record', message: `This app has no page for ${ref.label}.` }\n }\n openEntity(id, ref.archetype, ref.kind, undefined, ref.entityKey)\n // Mesma razão de navigateTo: abrir a ficha atrás do painel é não ter aberto.\n revealPage()\n return { opened: ref.label, ref: { id, label: ref.label, archetype: ref.archetype } }\n})\n\n\n/**\n * Access profiles: the agent picks the grants, the human approves the shape.\n *\n * Every other write here targets ONE record; this one decides what a whole\n * group of people can reach from now on, so the guards are tighter — the model\n * cannot grant an area the app never declared, cannot invent an action, and the\n * card never offers \"always allow\": a standing grant on THIS tool would let a\n * later turn mint access unattended.\n */\n/**\n * The grant map the model proposed, reduced to what this app can actually\n * express. Anything invented is dropped and REPORTED, never silently ignored: a\n * profile that quietly grants less than the reply promised is a security\n * statement that turned out to be false.\n */\nfunction validateGrants(\n features: Array<{ id: string }>,\n raw: unknown,\n): { grants: Record<string, PermissionAction[]>; rejected: string[] } {\n const known = new Set(features.map((f) => f.id))\n const grants: Record<string, PermissionAction[]> = {}\n const rejected: string[] = []\n const isAction = (a: string): a is PermissionAction => (PROFILE_ACTIONS as readonly string[]).includes(a)\n\n for (const [featureId, value] of Object.entries((raw ?? {}) as Record<string, unknown>)) {\n if (!known.has(featureId)) {\n rejected.push(`${featureId}: not an area of this app`)\n continue\n }\n const asked = (Array.isArray(value) ? value : [value]).map((a) => String(a).trim().toLowerCase())\n const unknown = asked.filter((a) => !isAction(a))\n if (unknown.length) rejected.push(`${featureId}: unknown action(s) ${unknown.join(', ')}`)\n const actions = asked.filter(isAction)\n if (actions.length) grants[featureId] = actions\n }\n return { grants, rejected }\n}\n\nregisterAIToolHandler('createPermissionProfile', async (args, ctx) => {\n const profile = usePermissionsStore.getState().currentProfile\n if (!profileHasSystemPermission(profile, 'manage_permissions')) {\n return {\n error: 'forbidden',\n message: 'This user cannot manage permissions. Say so — do not try another tool.',\n }\n }\n if (!ctx.orgAdapter?.createProfile || !ctx.currentOrg) {\n return {\n error: 'not_executable',\n message: 'This app has no permission-profile store wired. Tell the user to create the profile in Settings → Permissions.',\n }\n }\n\n const name = typeof args.name === 'string' ? args.name.trim() : ''\n if (!name) return { error: 'missing_name', message: 'Give the profile a name.' }\n\n const features = usePermissionsStore.getState().features\n const byId = new Map(features.map((f) => [f.id, f]))\n const { grants, rejected } = validateGrants(features, args.grants)\n\n if (!Object.keys(grants).length) {\n return {\n error: 'empty_grants',\n message: `No valid area was granted. Use the ids from the tool's area list and the actions ${PROFILE_ACTIONS.join('/')}.`,\n ...(rejected.length ? { rejected } : {}),\n availableAreas: features.map((f) => f.id),\n }\n }\n\n const existing = usePermissionsStore.getState().profiles\n const clash = existing.find((p) => p.name.trim().toLowerCase() === name.toLowerCase())\n if (clash) {\n return {\n error: 'name_taken',\n message: `A profile named \"${clash.name}\" already exists. Ask the user for a different name, or whether they meant to change that one (which happens in Settings → Permissions).`,\n }\n }\n\n // The summary the user actually reads. Labels, never ids — \"Leads\" is what\n // the permission screen calls it; \"crm.leads\" is what the database does.\n const summary = describeGrants(grants, byId)\n\n const decision = await requestChatConfirmation({\n id: `permission-profile-${Date.now()}`,\n toolName: 'createPermissionProfile',\n title: `Criar perfil de acesso: ${name}`,\n params: {\n nome: name,\n ...(typeof args.description === 'string' && args.description.trim()\n ? { descrição: args.description.trim() }\n : {}),\n acessos: summary,\n },\n plane: 'client',\n noAutoApproval: true,\n })\n if (!decision.approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n\n const finalName = typeof decision.values?.nome === 'string' && decision.values.nome.trim()\n ? decision.values.nome.trim()\n : name\n const finalDescription = typeof decision.values?.['descrição'] === 'string'\n ? (decision.values['descrição'] as string).trim() || undefined\n : typeof args.description === 'string' && args.description.trim()\n ? args.description.trim()\n : undefined\n\n let created: { id: string; name: string }\n try {\n created = await ctx.orgAdapter.createProfile(ctx.currentOrg.id, {\n name: finalName,\n description: finalDescription,\n grants,\n })\n } catch (error) {\n return {\n error: 'create_failed',\n message: `The profile could not be saved: ${describeThrown(error)}. Report this to the user — do not retry.`,\n }\n }\n\n // The permissions screen reads from the store, and the user is about to open\n // it from the link in this very reply.\n if (ctx.orgAdapter.listProfiles) {\n try {\n usePermissionsStore.getState().setProfiles(await ctx.orgAdapter.listProfiles(ctx.currentOrg.id))\n } catch {\n // A stale list is a refresh away; the profile itself is already written.\n }\n }\n\n return {\n ok: true,\n profile: { id: created.id, name: created.name },\n grants: summary,\n ...(rejected.length ? { rejectedFromYourProposal: rejected } : {}),\n message:\n 'Profile created. Summarise for the user WHAT IT CAN REACH using the labels in `grants`, then say the profile is assigned to people on the Team screen. The link to review it is already in the reply.',\n ref: { id: created.id, label: created.name, path: PERMISSIONS_PATH },\n }\n})\n\n/**\n * Changing an existing profile.\n *\n * Grants MERGE by area rather than replacing the whole map: asked to \"dá edição\n * em cursos\", the model sends the one area it is changing, and a replace would\n * have stripped every other area the profile had — access silently lost by a\n * request that only meant to add. Losing an area takes naming it in `revoke`,\n * and the card shows every difference either way.\n */\nregisterAIToolHandler('updatePermissionProfile', async (args, ctx) => {\n const actor = usePermissionsStore.getState().currentProfile\n if (!profileHasSystemPermission(actor, 'manage_permissions')) {\n return {\n error: 'forbidden',\n message: 'This user cannot manage permissions. Say so — do not try another tool.',\n }\n }\n if (!ctx.orgAdapter?.updateProfile || !ctx.currentOrg) {\n return {\n error: 'not_executable',\n message: 'This app cannot change profiles from here. Tell the user to edit it in Settings → Permissions.',\n }\n }\n\n const id = typeof args.id === 'string' ? args.id.trim() : ''\n const { features, profiles } = usePermissionsStore.getState()\n const target = profiles.find((p) => p.id === id)\n if (!target) {\n return {\n error: 'unknown_profile',\n message: `No profile with id \"${id}\". Existing: ${profiles.map((p) => `${p.id} (${p.name})`).join(', ')}.`,\n }\n }\n if (target.isSystem) {\n return {\n error: 'system_profile',\n message: `\"${target.name}\" is a built-in role and cannot be changed. Offer to create a new profile based on it instead (createPermissionProfile).`,\n }\n }\n\n const byId = new Map(features.map((f) => [f.id, f]))\n const { grants: setAreas, rejected } = validateGrants(features, args.grants)\n const revoke = (Array.isArray(args.revoke) ? args.revoke : [])\n .map((a) => String(a).trim())\n .filter(Boolean)\n\n const before = target.grants ?? {}\n const next: Record<string, PermissionAction[]> = { ...before, ...setAreas }\n for (const area of revoke) {\n if (!(area in next)) rejected.push(`${area}: was not granted, nothing to revoke`)\n delete next[area]\n }\n\n const rename = typeof args.name === 'string' && args.name.trim() && args.name.trim() !== target.name\n ? args.name.trim()\n : undefined\n const redescribe = typeof args.description === 'string' && args.description.trim() !== (target.description ?? '')\n ? args.description.trim()\n : undefined\n\n const same = (a?: PermissionAction[], b?: PermissionAction[]) =>\n !!a && !!b && a.length === b.length && a.every((x) => b.includes(x))\n const untouched = Object.keys(next).length === Object.keys(before).length &&\n Object.keys(next).every((k) => same(next[k], before[k]))\n if (untouched && !rename && redescribe === undefined) {\n return {\n error: 'no_change',\n message: 'That would leave the profile exactly as it is. Tell the user what it already has instead of writing it again.',\n current: describeGrants(before, byId),\n ...(rejected.length ? { rejectedFromYourProposal: rejected } : {}),\n }\n }\n\n // Every difference on one card: what it gains, what changes, what it loses.\n const rows: Array<{ label: string; type: string }> = []\n for (const area of Object.keys(next)) {\n const label = byId.get(area)?.label ?? area\n const now = (next[area] ?? []).map((a) => ACTION_LABELS[a] ?? a).join(', ')\n if (!(area in before)) rows.push({ label, type: `${now} (novo)` })\n else if (!same(next[area], before[area])) {\n const was = (before[area] ?? []).map((a) => ACTION_LABELS[a] ?? a).join(', ')\n rows.push({ label, type: `${now} (antes: ${was})` })\n } else rows.push({ label, type: now })\n }\n for (const area of Object.keys(before)) {\n if (!(area in next)) rows.push({ label: byId.get(area)?.label ?? area, type: 'REMOVIDO' })\n }\n\n const decision = await requestChatConfirmation({\n id: `permission-profile-update-${Date.now()}`,\n toolName: 'updatePermissionProfile',\n title: `Alterar perfil de acesso: ${rename ?? target.name}`,\n params: {\n perfil: target.name,\n ...(rename ? { 'novo nome': rename } : {}),\n ...(redescribe !== undefined ? { descrição: redescribe } : {}),\n acessos: rows,\n },\n plane: 'client',\n noAutoApproval: true,\n })\n if (!decision.approved) return { ok: false, cancelled: true, reason: 'user_declined' }\n\n const finalName = typeof decision.values?.['novo nome'] === 'string' && decision.values['novo nome']\n ? (decision.values['novo nome'] as string).trim()\n : rename\n\n try {\n await ctx.orgAdapter.updateProfile(ctx.currentOrg.id, target.id, {\n ...(finalName ? { name: finalName } : {}),\n ...(redescribe !== undefined ? { description: redescribe || undefined } : {}),\n grants: next,\n })\n } catch (error) {\n return {\n error: 'update_failed',\n message: `The profile could not be saved: ${describeThrown(error)}. Report this to the user — do not retry.`,\n }\n }\n\n if (ctx.orgAdapter.listProfiles) {\n try {\n usePermissionsStore.getState().setProfiles(await ctx.orgAdapter.listProfiles(ctx.currentOrg.id))\n } catch {\n // A stale list is a refresh away; the change itself is already written.\n }\n }\n\n return {\n ok: true,\n profile: { id: target.id, name: finalName ?? target.name },\n grants: describeGrants(next, byId),\n ...(rejected.length ? { rejectedFromYourProposal: rejected } : {}),\n message:\n 'Profile updated. Tell the user WHAT CHANGED and what the profile can reach now, using the labels in `grants` — not the ids. The link to review it is already in the reply.',\n ref: { id: target.id, label: finalName ?? target.name, path: PERMISSIONS_PATH },\n }\n})\n\n/** A grant map in the reader's language: labels and verbs, never ids. */\nfunction describeGrants(\n grants: Record<string, PermissionAction[]>,\n byId: Map<string, { label: string }>,\n): Array<{ label: string; type: string }> {\n return Object.entries(grants).map(([featureId, actions]) => ({\n label: byId.get(featureId)?.label ?? featureId,\n type: actions.map((a) => ACTION_LABELS[a] ?? a).join(', '),\n }))\n}\n\n/** Where the profile can be reviewed and fine-tuned (AdminShell settings tab). */\nconst PERMISSIONS_PATH = '/settings/permissions'\n\n/** The four grants, in the reader's language. */\nconst ACTION_LABELS: Record<string, string> = {\n read: 'ver',\n create: 'criar',\n edit: 'editar',\n delete: 'excluir',\n}\n\n/**\n * Client-plane execution of an RPC-bound tool (`execution: {kind:'rpc'}`):\n * calls the pool function as the signed-in user. The actor is the SESSION\n * user — spine 016 makes the RPC reject any other p_actor for JWT callers, so\n * this path cannot borrow someone else's role. Structured denials pass through\n * to the model (conversational paywall); S4 moves this server-side untouched.\n */\nexport async function executeRpcTool(\n rpcName: string,\n args: Record<string, unknown>,\n userId: string | undefined,\n): Promise<AIToolExecutionResult> {\n const supabase = getSupabaseClientOptional() as {\n rpc?: (fn: string, params: Record<string, unknown>) => Promise<{ data: unknown; error: { message: string } | null }>\n } | null\n const tenantId = getActiveTenantId()\n if (!supabase?.rpc || !tenantId || !userId) {\n return errorResult('not_executable', 'No authenticated session/tenant available for this action.')\n }\n const { data, error } = await supabase.rpc(rpcName, {\n p_tenant_id: tenantId,\n p_actor_user_id: userId,\n p_payload: args,\n })\n if (error) return errorResult('execution_failed', error.message)\n return { ok: true, content: JSON.stringify(data ?? { ok: true }) }\n}\n\n// The one tool that reaches the other ones. Its index lives in tool-search.ts;\n// what it searches is handed over per turn (`ctx.searchableTools`), because the\n// catalog is a property of the screen, not of this module.\nregisterAIToolHandler('findTools', (args, ctx) =>\n resolveToolSearch(args, ctx.searchableTools ?? [], new Set(ctx.carriedTools ?? [])),\n)\n","import * as React from 'react'\nimport {\n registerSurface,\n unregisterSurface,\n type AgentSurfaceContribution,\n} from '../lib/agent-surface'\nimport { registerAIToolHandler, unregisterAIToolHandler } from '../lib/ai-tool-handlers'\n\n/**\n * Publish the current screen to the assistant. Call it from an interactive\n * surface (a form builder, a calendar) with a description of what's on screen,\n * plus the tools that act on it. The contribution is live while the component\n * is mounted and gone when it unmounts.\n *\n * Freshness without churn: register once (by `id`), but read the contribution\n * through a ref so `describe()` and every `execute()` always see the latest\n * state and closures — even though the effect runs a single time. Pass a\n * `contribution` with a STABLE identity (memoize it) whose functions read\n * current state via refs; do not rebuild it every render.\n */\nexport function useAgentSurface(contribution: AgentSurfaceContribution): void {\n const ref = React.useRef(contribution)\n ref.current = contribution\n\n const id = contribution.id\n\n React.useEffect(() => {\n registerSurface({ id, get: () => ref.current })\n\n // Executors ride the normal client-plane handler map so `executeAITool`\n // finds and serializes them with zero special-casing. Each looks its own\n // executor up by name at call time, through the ref, so it never goes stale.\n const names = (ref.current.tools ?? []).map((t) => t.tool.name)\n for (const name of names) {\n registerAIToolHandler(name, (args) => {\n const entry = ref.current.tools?.find((t) => t.tool.name === name)\n if (!entry) return { error: 'tool_unmounted', message: 'That surface is no longer open.' }\n return entry.execute(args)\n })\n }\n\n return () => {\n unregisterSurface(id)\n for (const name of names) unregisterAIToolHandler(name)\n }\n }, [id])\n}\n","import * as React from 'react'\nimport { WandSparkles } from 'lucide-react'\nimport { Button, DropdownItem } from '@fayz-ai/ui'\nimport { useTranslation, type AgentRole } from '@fayz-ai/core'\nimport { useChatStore, type ComposerMedia } from '../stores/chat.store'\nimport {\n ASK_AI_HANDOFF_ID,\n useAssistantInviteStore,\n type AssistantInviteDef,\n type AssistantInviteSuggestion,\n} from '../lib/assistant-invite'\n\n// ---------------------------------------------------------------------------\n// \"Criar com IA\" — a screen handing its task to the assistant.\n//\n// The pattern repeats all over the product: a screen can build a thing through\n// a form, and the same thing is faster to describe than to fill in. Rather than\n// each screen growing its own textarea and its own send button (and its own\n// idea of what the assistant is called), the screen states the SUBJECT and this\n// hands it over.\n//\n// What it does NOT do is write the request. The screen knows the subject; only\n// the user knows the ask. So the handoff opens the assistant ALREADY ABOUT the\n// action — its own headline, its own examples, the composer hinting at the\n// subject and holding the cursor — and the user types where the answer will\n// arrive anyway. A `prompt` is available for the case where the screen already\n// has the whole request (a row's \"resolve this\"), and then it sends.\n//\n// The intro is BORROWED, not replaced: whatever the screen was offering is put\n// back the moment the panel closes, so a handoff never leaves the assistant\n// permanently talking about a report the user has stopped creating.\n//\n// The screen still has to publish the TOOL that does the work — see\n// `useAgentSurface`. This is the door; the tool is what is behind it.\n// ---------------------------------------------------------------------------\n\nconst HANDOFF_ID = ASK_AI_HANDOFF_ID\n\nexport interface AskAIIntro {\n /** Whose work this task is. With a cast, hands it to that colleague. */\n role?: AgentRole\n /** What the task IS (\"Analista de relatórios\"). Names the assistant on an app\n * with no cast; with one, it is the subject beside the colleague's name. */\n persona?: string\n /** The one line it opens with — what it is about to help with. */\n pitch: string\n /** A sentence on what it can actually do here. */\n description?: string\n /** Two or three asks worth offering FOR THIS ACTION. */\n suggestions?: AssistantInviteSuggestion[]\n}\n\nexport interface AskAIOptions {\n /** Composer placeholder while the user writes — the subject, by example. */\n hint?: string\n /** Send this immediately instead of waiting for the user to write. */\n prompt?: string\n /**\n * Write this into the composer and stop. The opposite of `prompt`: the screen\n * knows the usual ask well enough to type it, but sending is still the user's\n * — they may want to say \"e deixa o fundo branco\" first.\n */\n draft?: string\n /**\n * A file the app already stores, attached by URL. The model fetches the\n * original; nothing is read, encoded or re-uploaded on the way.\n */\n media?: ComposerMedia\n /** Copy the assistant opens with. Restored to the screen's own on close. */\n intro?: AskAIIntro\n}\n\nlet releaseIntro: (() => void) | null = null\n\nfunction borrowIntro(intro: AskAIIntro, placeholder?: string): void {\n const store = useAssistantInviteStore.getState()\n // A second handoff must not save the first handoff as \"what to go back to\".\n const previous = store.invite?.id === HANDOFF_ID ? null : store.invite ?? null\n if (previous || !releaseIntro) {\n releaseIntro = () => {\n if (useAssistantInviteStore.getState().invite?.id === HANDOFF_ID) {\n useAssistantInviteStore.getState().setInvite(previous)\n }\n releaseIntro = null\n }\n }\n\n const def: AssistantInviteDef = {\n id: HANDOFF_ID,\n ...(intro.role ? { role: intro.role } : {}),\n persona: intro.persona,\n headline: intro.pitch,\n pitch: intro.pitch,\n description: intro.description,\n placeholder,\n suggestions: intro.suggestions,\n // Never the hero takeover: the user asked for the assistant from a screen\n // they are still looking at, and covering it would be answering a question\n // they did not ask.\n auto: false,\n }\n store.setInvite(def)\n}\n\n/** One subscription, armed only while a handoff is on loan. */\nfunction releaseOnClose(): void {\n const stop = useChatStore.subscribe((state, previous) => {\n if (previous.isOpen && !state.isOpen) {\n releaseIntro?.()\n stop()\n }\n })\n}\n\n/** Open the assistant on a subject. Usable outside React (a menu item, a\n * keyboard shortcut) — the button below is the ordinary way in. */\nexport function askAI({ hint, prompt, draft, media, intro }: AskAIOptions = {}): void {\n const chat = useChatStore.getState()\n chat.setComposerHint(hint ?? null)\n chat.requestComposerFocus()\n if (media) chat.attachMedia(media)\n if (draft) chat.setDraft(draft)\n if (intro) {\n borrowIntro(intro, hint)\n releaseOnClose()\n }\n if (prompt) chat.queuePrompt(prompt)\n else chat.setOpen(true)\n}\n\nexport interface AskAIButtonProps extends AskAIOptions {\n /** Defaults to \"Criar com IA\". Say what is being created when it helps. */\n label?: string\n /** Ran after the handoff — usually closing the panel the button sat in. */\n onHandoff?: () => void\n size?: React.ComponentProps<typeof Button>['size']\n variant?: React.ComponentProps<typeof Button>['variant']\n className?: string\n disabled?: boolean\n}\n\nexport interface AskAIMenuItemProps extends AskAIOptions {\n label?: string\n /** One line under the label — what describing it gets you. */\n description?: string\n onHandoff?: () => void\n}\n\n/**\n * The same handoff as a menu entry, for screens whose \"create\" is a dropdown.\n *\n * Highlighted on purpose, and it is not decoration: a menu lists options as\n * equals, and these two are not equals — one is a sentence and the other is a\n * form. The tint is the menu saying which one to try first.\n *\n * Give the hosting `DropdownContent` an\n * `onCloseAutoFocus={(e) => e.preventDefault()}`: this entry moves the cursor\n * to the assistant's field, and Radix restores focus to the trigger AFTER the\n * menu closes — arriving last, it undoes exactly that.\n */\nexport function AskAIMenuItem({\n hint, prompt, draft, media, intro, label, description, onHandoff,\n}: AskAIMenuItemProps) {\n const t = useTranslation()\n return (\n <DropdownItem\n onSelect={() => { askAI({ hint, prompt, draft, media, intro }); onHandoff?.() }}\n className=\"fz-ai-action items-start gap-2 py-2\"\n >\n <WandSparkles className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block font-medium\">{label ?? t('assistant.askAI')}</span>\n {description ? (\n <span className=\"block text-xs font-normal opacity-70\">{description}</span>\n ) : null}\n </span>\n </DropdownItem>\n )\n}\n\nexport function AskAIButton({\n hint, prompt, draft, media, intro, label, onHandoff, size = 'sm', variant = 'default', className, disabled,\n}: AskAIButtonProps) {\n const t = useTranslation()\n return (\n <Button\n type=\"button\"\n size={size}\n variant={variant}\n className={className}\n disabled={disabled}\n onClick={() => { askAI({ hint, prompt, draft, media, intro }); onHandoff?.() }}\n >\n <WandSparkles className=\"mr-1.5 h-3.5 w-3.5\" />\n {label ?? t('assistant.askAI')}\n </Button>\n )\n}\n","import React from 'react'\nimport {\n Modal,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalFooter,\n} from '@fayz-ai/ui'\nimport { Button } from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\n\ninterface DeleteConfirmDialogProps {\n open: boolean\n onClose: () => void\n onConfirm: () => void\n entityName: string\n displayValue?: string\n /**\n * `deactivate` é o que a lixeira de um CADASTRO faz. A palavra importa: o\n * diálogo de excluir promete que «não pode ser desfeita», e desligar pode —\n * prometer o pior assusta quem só queria tirar da lista, e ensina a não\n * confiar no aviso quando ele for verdade.\n */\n mode?: 'delete' | 'deactivate'\n}\n\nexport function DeleteConfirmDialog({ open, onClose, onConfirm, entityName, displayValue, mode = 'delete' }: DeleteConfirmDialogProps) {\n const t = useTranslation()\n const soft = mode === 'deactivate'\n const key = (suffix: string) => (soft ? `crud.deactivate.${suffix}` : `crud.delete.${suffix}`)\n return (\n <Modal open={open} onOpenChange={(isOpen) => { if (!isOpen) onClose() }}>\n <ModalContent>\n <ModalHeader>\n <ModalTitle>{t(key('title'), { entity: entityName })}</ModalTitle>\n <ModalDescription>\n {displayValue\n ? t(key('confirmNamed'), { displayValue })\n : t(key('confirmGeneric'), { entity: entityName.toLowerCase() })}\n </ModalDescription>\n </ModalHeader>\n <ModalFooter>\n <Button variant=\"outline\" onClick={onClose}>{t('common.cancel')}</Button>\n <Button variant={soft ? 'default' : 'destructive'} onClick={onConfirm}>\n {soft ? t('crud.deactivate.action') : t('common.delete')}\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n )\n}\n"]}