@bytexbyte/nxtlinq-ai-agent-ui-react-development 0.4.0 → 2.0.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 (136) hide show
  1. package/dist/context/ChatBotContext.d.ts.map +1 -1
  2. package/dist/context/ChatBotContext.js +179 -156
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/permissionState.d.ts +53 -0
  6. package/dist/permissionState.d.ts.map +1 -0
  7. package/dist/permissionState.js +217 -0
  8. package/dist/types/ChatBotTypes.d.ts +6 -5
  9. package/dist/types/ChatBotTypes.d.ts.map +1 -1
  10. package/dist/ui/ModelSelector.js +2 -2
  11. package/dist/ui/PermissionForm.d.ts.map +1 -1
  12. package/dist/ui/PermissionForm.js +14 -28
  13. package/package.json +3 -3
  14. package/src/context/ChatBotContext.tsx +252 -191
  15. package/src/index.ts +0 -1
  16. package/src/permissionState.ts +313 -0
  17. package/src/types/ChatBotTypes.ts +7 -7
  18. package/src/ui/ModelSelector.tsx +5 -5
  19. package/src/ui/PermissionForm.tsx +20 -31
  20. package/dist/NxtlinqAgentChat.d.ts +0 -26
  21. package/dist/NxtlinqAgentChat.d.ts.map +0 -1
  22. package/dist/NxtlinqAgentChat.js +0 -28
  23. package/dist/components/AgentAssistantShell.d.ts +0 -5
  24. package/dist/components/AgentAssistantShell.d.ts.map +0 -1
  25. package/dist/components/AgentAssistantShell.js +0 -52
  26. package/dist/components/AgentComposer.d.ts +0 -3
  27. package/dist/components/AgentComposer.d.ts.map +0 -1
  28. package/dist/components/AgentComposer.js +0 -60
  29. package/dist/components/AgentMessageList.d.ts +0 -3
  30. package/dist/components/AgentMessageList.d.ts.map +0 -1
  31. package/dist/components/AgentMessageList.js +0 -37
  32. package/dist/components/AgentRemoteAudio.d.ts +0 -4
  33. package/dist/components/AgentRemoteAudio.d.ts.map +0 -1
  34. package/dist/components/AgentRemoteAudio.js +0 -34
  35. package/dist/components/AgentVoiceBar.d.ts +0 -3
  36. package/dist/components/AgentVoiceBar.d.ts.map +0 -1
  37. package/dist/components/AgentVoiceBar.js +0 -91
  38. package/dist/components/PresetMessageChips.d.ts +0 -3
  39. package/dist/components/PresetMessageChips.d.ts.map +0 -1
  40. package/dist/components/PresetMessageChips.js +0 -23
  41. package/dist/context/AgentAssistantContext.d.ts +0 -32
  42. package/dist/context/AgentAssistantContext.d.ts.map +0 -1
  43. package/dist/context/AgentAssistantContext.js +0 -179
  44. package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts +0 -2
  45. package/dist/legacy/assets/images/adiSideItalicDataUri.d.ts.map +0 -1
  46. package/dist/legacy/assets/images/adiSideItalicDataUri.js +0 -1
  47. package/dist/legacy/chatbot/ChatBot.d.ts +0 -5
  48. package/dist/legacy/chatbot/ChatBot.d.ts.map +0 -1
  49. package/dist/legacy/chatbot/ChatBot.js +0 -35
  50. package/dist/legacy/chatbot/context/ChatBotContext.d.ts +0 -5
  51. package/dist/legacy/chatbot/context/ChatBotContext.d.ts.map +0 -1
  52. package/dist/legacy/chatbot/context/ChatBotContext.js +0 -2922
  53. package/dist/legacy/chatbot/types/ChatBotTypes.d.ts +0 -166
  54. package/dist/legacy/chatbot/types/ChatBotTypes.d.ts.map +0 -1
  55. package/dist/legacy/chatbot/types/ChatBotTypes.js +0 -1
  56. package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts +0 -17
  57. package/dist/legacy/chatbot/ui/BerifyMeModal.d.ts.map +0 -1
  58. package/dist/legacy/chatbot/ui/BerifyMeModal.js +0 -110
  59. package/dist/legacy/chatbot/ui/ChatBotHeader.d.ts +0 -15
  60. package/dist/legacy/chatbot/ui/ChatBotHeader.d.ts.map +0 -1
  61. package/dist/legacy/chatbot/ui/ChatBotHeader.js +0 -62
  62. package/dist/legacy/chatbot/ui/ChatBotUI.d.ts +0 -3
  63. package/dist/legacy/chatbot/ui/ChatBotUI.d.ts.map +0 -1
  64. package/dist/legacy/chatbot/ui/ChatBotUI.js +0 -557
  65. package/dist/legacy/chatbot/ui/MessageInput.d.ts +0 -3
  66. package/dist/legacy/chatbot/ui/MessageInput.d.ts.map +0 -1
  67. package/dist/legacy/chatbot/ui/MessageInput.js +0 -321
  68. package/dist/legacy/chatbot/ui/MessageList.d.ts +0 -4
  69. package/dist/legacy/chatbot/ui/MessageList.d.ts.map +0 -1
  70. package/dist/legacy/chatbot/ui/MessageList.js +0 -455
  71. package/dist/legacy/chatbot/ui/ModelSelector.d.ts +0 -4
  72. package/dist/legacy/chatbot/ui/ModelSelector.d.ts.map +0 -1
  73. package/dist/legacy/chatbot/ui/ModelSelector.js +0 -122
  74. package/dist/legacy/chatbot/ui/NotificationModal.d.ts +0 -15
  75. package/dist/legacy/chatbot/ui/NotificationModal.d.ts.map +0 -1
  76. package/dist/legacy/chatbot/ui/NotificationModal.js +0 -53
  77. package/dist/legacy/chatbot/ui/PermissionForm.d.ts +0 -8
  78. package/dist/legacy/chatbot/ui/PermissionForm.d.ts.map +0 -1
  79. package/dist/legacy/chatbot/ui/PermissionForm.js +0 -465
  80. package/dist/legacy/chatbot/ui/PresetMessages.d.ts +0 -4
  81. package/dist/legacy/chatbot/ui/PresetMessages.d.ts.map +0 -1
  82. package/dist/legacy/chatbot/ui/PresetMessages.js +0 -33
  83. package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts +0 -3
  84. package/dist/legacy/chatbot/ui/VoiceModePanel.d.ts.map +0 -1
  85. package/dist/legacy/chatbot/ui/VoiceModePanel.js +0 -95
  86. package/dist/legacy/chatbot/ui/chatBotHeaderParts.d.ts +0 -15
  87. package/dist/legacy/chatbot/ui/chatBotHeaderParts.d.ts.map +0 -1
  88. package/dist/legacy/chatbot/ui/chatBotHeaderParts.js +0 -50
  89. package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts +0 -73
  90. package/dist/legacy/chatbot/ui/styles/isolatedStyles.d.ts.map +0 -1
  91. package/dist/legacy/chatbot/ui/styles/isolatedStyles.js +0 -985
  92. package/dist/legacy/index.d.ts +0 -14
  93. package/dist/legacy/index.d.ts.map +0 -1
  94. package/dist/legacy/index.js +0 -12
  95. package/dist/theme/defaultTheme.d.ts +0 -3
  96. package/dist/theme/defaultTheme.d.ts.map +0 -1
  97. package/dist/theme/defaultTheme.js +0 -20
  98. package/dist/types.d.ts +0 -62
  99. package/dist/types.d.ts.map +0 -1
  100. package/dist/types.js +0 -1
  101. package/dist/voice/useVoiceConnectOrchestration.d.ts +0 -21
  102. package/dist/voice/useVoiceConnectOrchestration.d.ts.map +0 -1
  103. package/dist/voice/useVoiceConnectOrchestration.js +0 -86
  104. package/dist/voice/useVoiceMicState.d.ts +0 -15
  105. package/dist/voice/useVoiceMicState.d.ts.map +0 -1
  106. package/dist/voice/useVoiceMicState.js +0 -94
  107. package/dist/voice/useVoiceSilenceCommit.d.ts +0 -10
  108. package/dist/voice/useVoiceSilenceCommit.d.ts.map +0 -1
  109. package/dist/voice/useVoiceSilenceCommit.js +0 -67
  110. package/dist/voice/useVoiceTranscriptMessages.d.ts +0 -18
  111. package/dist/voice/useVoiceTranscriptMessages.d.ts.map +0 -1
  112. package/dist/voice/useVoiceTranscriptMessages.js +0 -132
  113. package/dist/voice/useWsRealtimeAudio.d.ts +0 -18
  114. package/dist/voice/useWsRealtimeAudio.d.ts.map +0 -1
  115. package/dist/voice/useWsRealtimeAudio.js +0 -102
  116. package/dist/voice/voiceMicConstants.d.ts +0 -4
  117. package/dist/voice/voiceMicConstants.d.ts.map +0 -1
  118. package/dist/voice/voiceMicConstants.js +0 -10
  119. package/dist/voice/voiceUserBubble.d.ts +0 -10
  120. package/dist/voice/voiceUserBubble.d.ts.map +0 -1
  121. package/dist/voice/voiceUserBubble.js +0 -52
  122. package/dist/voice/ws/BrowserWsPcmPlayer.d.ts +0 -23
  123. package/dist/voice/ws/BrowserWsPcmPlayer.d.ts.map +0 -1
  124. package/dist/voice/ws/BrowserWsPcmPlayer.js +0 -137
  125. package/dist/voice/ws/BrowserWsPcmRecorder.d.ts +0 -17
  126. package/dist/voice/ws/BrowserWsPcmRecorder.d.ts.map +0 -1
  127. package/dist/voice/ws/BrowserWsPcmRecorder.js +0 -71
  128. package/dist/voice/ws/float32ToPcm16.d.ts +0 -2
  129. package/dist/voice/ws/float32ToPcm16.d.ts.map +0 -1
  130. package/dist/voice/ws/float32ToPcm16.js +0 -8
  131. package/dist/voice/ws/voiceSilenceConstants.d.ts +0 -5
  132. package/dist/voice/ws/voiceSilenceConstants.d.ts.map +0 -1
  133. package/dist/voice/ws/voiceSilenceConstants.js +0 -4
  134. package/dist/voice/ws/wsRealtimeConstants.d.ts +0 -2
  135. package/dist/voice/ws/wsRealtimeConstants.d.ts.map +0 -1
  136. package/dist/voice/ws/wsRealtimeConstants.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAyB/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAM/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAwvGlD,CAAC"}
1
+ {"version":3,"file":"ChatBotContext.d.ts","sourceRoot":"","sources":["../../src/context/ChatBotContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA0B/B,OAAO,EAEL,kBAAkB,EAClB,YAAY,EAEb,MAAM,uBAAuB,CAAC;AAsB/B,eAAO,MAAM,UAAU,0BAMtB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAoyGlD,CAAC"}
@@ -5,6 +5,7 @@ import * as React from 'react';
5
5
  import { flushSync } from 'react-dom';
6
6
  import { v4 as uuidv4 } from 'uuid';
7
7
  import { createNxtlinqApi, setApiHosts, synthesizeSpeechToBuffer, streamSpeechToAudioContext, useLocalStorage, useSessionStorage, useSpeechToTextFromMic, useVoiceMode, metakeepClient, getEthers, sleep, walletTextUtils, } from '@bytexbyte/nxtlinq-ai-agent-web-development';
8
+ import { dispatchRuntimeAITCompleteReplacement, removeOneDeniedPermission, replaceCurrentMaximumDenyList, RuntimeAITMutationQueue, RuntimeAITRecomputeCoordinator, StaleRuntimeAITResponseError, runtimeAITContextKey, runtimeAITSubjectKey, runtimeAuthorizationMatchesContext, runtimeAuthorizationState, unavailableRuntimeAuthorization, useProviderRuntimeCommit, useRuntimeAITContextCommit, } from '../permissionState';
8
9
  const MIC_ENABLED_SESSION_KEY = 'chatbot-mic-enabled';
9
10
  const ChatBotContext = React.createContext(undefined);
10
11
  export const useChatBot = () => {
@@ -14,7 +15,7 @@ export const useChatBot = () => {
14
15
  }
15
16
  return context;
16
17
  };
17
- export const ChatBotProvider = ({ onMessage, onError, onToolUse, presetMessages = [], placeholder = 'Type a message...', className = '', maxRetries = 3, retryDelay = 2000, serviceId, apiKey, apiSecret, serviceToken, getAuthToken, environment = 'production', onVerifyWallet, permissionGroup, children,
18
+ export const ChatBotProvider = ({ onMessage, onError, onToolUse, presetMessages = [], placeholder = 'Type a message...', className = '', maxRetries = 3, retryDelay = 2000, serviceId, apiKey, apiSecret, serviceToken, getAuthToken, environment = 'production', onVerifyWallet, permissionGroup, roles, children,
18
19
  // AI Model related attributes
19
20
  onModelChange,
20
21
  // Storage mode configuration
@@ -33,8 +34,6 @@ isStopRecordingOnSend = false,
33
34
  customError,
34
35
  // PII display mode
35
36
  piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary, }) => {
36
- // Set API hosts immediately based on environment (before any API calls)
37
- setApiHosts(environment);
38
37
  const nxtlinqApi = React.useMemo(() => (serviceToken || getAuthToken
39
38
  ? createNxtlinqApi({ apiKey, apiSecret, serviceToken, getAuthToken })
40
39
  : createNxtlinqApi(apiKey ?? '', apiSecret ?? '')), [apiKey, apiSecret, serviceToken, getAuthToken]);
@@ -86,7 +85,17 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
86
85
  const [hitAddress, setHitAddress] = React.useState(null);
87
86
  const [ait, setAit] = React.useState(null);
88
87
  const [permissions, setPermissions] = React.useState([]);
89
- const [availablePermissions, setAvailablePermissions] = React.useState([]);
88
+ const [maximumPermissions, setMaximumPermissions] = React.useState([]);
89
+ const [deniedPermissions, setDeniedPermissions] = React.useState([]);
90
+ const [runtimePermissionsUnavailable, setRuntimePermissionsUnavailable] = React.useState(false);
91
+ const [runtimeAuthorizationContextKey, setRuntimeAuthorizationContextKey] = React.useState(null);
92
+ const [servicePermissionCatalog, setServicePermissionCatalog] = React.useState([]);
93
+ const availablePermissions = React.useMemo(() => maximumPermissions.map((label) => servicePermissionCatalog.find((permission) => permission.label === label) ?? {
94
+ id: label,
95
+ label,
96
+ description: '',
97
+ groups: [],
98
+ }), [maximumPermissions, servicePermissionCatalog]);
90
99
  const [showPermissionForm, setShowPermissionForm] = React.useState(false);
91
100
  const [isPermissionFormOpen, setIsPermissionFormOpen] = React.useState(false);
92
101
  const [isAITLoading, setIsAITLoading] = React.useState(false);
@@ -95,6 +104,7 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
95
104
  const [walletInfo, setWalletInfo] = React.useState(null);
96
105
  const [isWalletLoading, setIsWalletLoading] = React.useState(false);
97
106
  const [isAutoConnecting, setIsAutoConnecting] = React.useState(false);
107
+ const runtimeRolesKey = JSON.stringify(roles ?? null);
98
108
  // Persistent data (always use localStorage)
99
109
  const [nxtlinqAITServiceAccessToken, setNxtlinqAITServiceAccessToken] = useLocalStorage('nxtlinqAITServiceAccessToken', '');
100
110
  const [pseudoId, setPseudoId] = useLocalStorage('pseudoId', uuidv4());
@@ -143,8 +153,12 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
143
153
  const hitAddressRef = React.useRef(hitAddress);
144
154
  const aitRef = React.useRef(ait);
145
155
  const permissionsRef = React.useRef(permissions);
156
+ const deniedPermissionsRef = React.useRef(deniedPermissions);
146
157
  const nxtlinqAITServiceAccessTokenRef = React.useRef(nxtlinqAITServiceAccessToken);
147
158
  const signerRef = React.useRef(signer);
159
+ const runtimeRecomputeCoordinatorRef = React.useRef(new RuntimeAITRecomputeCoordinator());
160
+ const runtimeMutationQueueRef = React.useRef(new RuntimeAITMutationQueue());
161
+ useProviderRuntimeCommit(hitAddressRef, hitAddress, environment, setApiHosts);
148
162
  // Helper function to combine customUsername with Adilas customUserInfo
149
163
  const getFinalCustomUsername = React.useCallback((username) => {
150
164
  if (!username)
@@ -463,15 +477,15 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
463
477
  }
464
478
  }, []);
465
479
  // Update refs when state changes
466
- React.useEffect(() => {
467
- hitAddressRef.current = hitAddress;
468
- }, [hitAddress]);
469
480
  React.useEffect(() => {
470
481
  aitRef.current = ait;
471
482
  }, [ait]);
472
483
  React.useEffect(() => {
473
484
  permissionsRef.current = permissions;
474
485
  }, [permissions]);
486
+ React.useEffect(() => {
487
+ deniedPermissionsRef.current = deniedPermissions;
488
+ }, [deniedPermissions]);
475
489
  React.useEffect(() => {
476
490
  nxtlinqAITServiceAccessTokenRef.current = nxtlinqAITServiceAccessToken;
477
491
  }, [nxtlinqAITServiceAccessToken]);
@@ -843,7 +857,7 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
843
857
  console.error('Failed to fetch permissions:', result.error);
844
858
  return undefined;
845
859
  }
846
- setAvailablePermissions(result.permissions);
860
+ setServicePermissionCatalog(result.permissions);
847
861
  return result.permissions;
848
862
  }
849
863
  catch (error) {
@@ -851,12 +865,81 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
851
865
  return undefined;
852
866
  }
853
867
  };
854
- // Refresh AIT
868
+ const clearRuntimeAuthorization = React.useCallback(() => {
869
+ const cleared = unavailableRuntimeAuthorization(deniedPermissionsRef.current);
870
+ const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
871
+ aitRef.current = null;
872
+ permissionsRef.current = [];
873
+ setAit(cleared.ait);
874
+ setPermissions(cleared.effectivePermissions);
875
+ setMaximumPermissions(cleared.maximumPermissions);
876
+ setRuntimePermissionsUnavailable(cleared.unavailable);
877
+ setRuntimeAuthorizationContextKey(activeContext ? runtimeAITContextKey(activeContext) : null);
878
+ }, []);
879
+ const applyRuntimeResult = React.useCallback((result, context) => {
880
+ const next = runtimeAuthorizationState(result, context.controller, context.serviceId);
881
+ aitRef.current = next.ait;
882
+ permissionsRef.current = next.effectivePermissions;
883
+ setAit(next.ait);
884
+ setPermissions(next.effectivePermissions);
885
+ setMaximumPermissions(next.maximumPermissions);
886
+ setDeniedPermissions(next.deniedPermissions);
887
+ deniedPermissionsRef.current = next.deniedPermissions;
888
+ setRuntimePermissionsUnavailable(false);
889
+ setRuntimeAuthorizationContextKey(runtimeAITContextKey(context));
890
+ return result;
891
+ }, []);
892
+ const runtimeContext = React.useMemo(() => hitAddress ? {
893
+ controller: hitAddress,
894
+ serviceId,
895
+ ...(roles !== undefined ? { roles: [...roles] } : {}),
896
+ ...(permissionGroup !== undefined ? { permissionGroup } : {}),
897
+ } : null, [hitAddress, permissionGroup, runtimeRolesKey, serviceId]);
898
+ const invalidateCommittedRuntimeContext = React.useCallback(() => {
899
+ const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
900
+ aitRef.current = null;
901
+ permissionsRef.current = [];
902
+ deniedPermissionsRef.current = [];
903
+ setAit(null);
904
+ setPermissions([]);
905
+ setMaximumPermissions([]);
906
+ setDeniedPermissions([]);
907
+ setRuntimePermissionsUnavailable(activeContext !== null);
908
+ setRuntimeAuthorizationContextKey(activeContext ? runtimeAITContextKey(activeContext) : null);
909
+ }, []);
910
+ useRuntimeAITContextCommit(runtimeRecomputeCoordinatorRef.current, runtimeContext, invalidateCommittedRuntimeContext);
911
+ const recomputeRuntimeAIT = React.useCallback(async (context) => {
912
+ const capturedContext = {
913
+ controller: context.controller,
914
+ serviceId: context.serviceId,
915
+ ...(context.roles !== undefined ? { roles: [...context.roles] } : {}),
916
+ ...(context.permissionGroup !== undefined ? { permissionGroup: context.permissionGroup } : {}),
917
+ };
918
+ return runtimeRecomputeCoordinatorRef.current.run(capturedContext, () => nxtlinqApi.ait.recomputeAIT(capturedContext), applyRuntimeResult, clearRuntimeAuthorization);
919
+ }, [applyRuntimeResult, clearRuntimeAuthorization, nxtlinqApi]);
920
+ const queueRuntimeAITRefresh = React.useCallback((context) => runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
921
+ runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
922
+ return recomputeRuntimeAIT(context);
923
+ }), [recomputeRuntimeAIT]);
924
+ const convergeRuntimeAITSubject = React.useCallback(async (subjectKey) => {
925
+ const activeContext = runtimeRecomputeCoordinatorRef.current.getActiveContext();
926
+ if (!activeContext || runtimeAITSubjectKey(activeContext) !== subjectKey) {
927
+ return;
928
+ }
929
+ await recomputeRuntimeAIT(activeContext);
930
+ }, [recomputeRuntimeAIT]);
931
+ const dispatchRuntimeDenyListReplacement = React.useCallback(async (context, nextDeniedPermissions) => dispatchRuntimeAITCompleteReplacement(runtimeRecomputeCoordinatorRef.current, context, () => nxtlinqApi.ait.updatePermissionDenyList({
932
+ ...context,
933
+ deniedPermissions: nextDeniedPermissions,
934
+ }), convergeRuntimeAITSubject, clearRuntimeAuthorization), [clearRuntimeAuthorization, convergeRuntimeAITSubject, nxtlinqApi]);
935
+ // Refresh the authoritative runtime AIT state.
855
936
  const refreshAIT = async (forceUpdatePermissions = false) => {
856
937
  if (!hitAddress) {
857
938
  setAit(null);
858
939
  setPermissions([]);
940
+ setMaximumPermissions([]);
859
941
  setWalletInfo(null);
942
+ setRuntimePermissionsUnavailable(false);
860
943
  setIsAITLoading(false);
861
944
  return;
862
945
  }
@@ -881,35 +964,20 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
881
964
  console.error('Failed to fetch wallet info:', error);
882
965
  }
883
966
  }
884
- // Only try to fetch AIT if we have a token
967
+ // Recompute is the sole mint/reuse path and the only permission authority.
885
968
  if (nxtlinqAITServiceAccessToken) {
886
- const response = await nxtlinqApi.ait.getAITByServiceIdAndController({
887
- serviceId,
888
- controller: hitAddress,
889
- customUsername: (!requireWalletIDVVerification && customUsername) ? getFinalCustomUsername(customUsername) : undefined
890
- }, nxtlinqAITServiceAccessToken);
891
- if ('error' in response) {
892
- console.error('Failed to fetch AIT:', response.error);
893
- setAit(null);
894
- setPermissions([]);
895
- return;
896
- }
897
- setAit(response);
898
- if (!isPermissionFormOpen || forceUpdatePermissions) {
899
- const newPermissions = response.metadata?.permissions || [];
900
- setPermissions(newPermissions);
969
+ if (runtimeContext) {
970
+ await queueRuntimeAITRefresh(runtimeContext);
901
971
  }
902
972
  }
903
973
  else {
904
- // No token available, clear AIT data
905
- setAit(null);
906
- setPermissions([]);
974
+ clearRuntimeAuthorization();
907
975
  }
908
976
  }
909
977
  catch (error) {
910
- console.error('Failed to fetch AIT:', error);
911
- setAit(null);
912
- setPermissions([]);
978
+ if (!(error instanceof StaleRuntimeAITResponseError)) {
979
+ console.error('Failed to recompute AIT:', error);
980
+ }
913
981
  }
914
982
  finally {
915
983
  setIsAITLoading(false);
@@ -1097,9 +1165,13 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
1097
1165
  }
1098
1166
  const { accessToken } = response;
1099
1167
  setNxtlinqAITServiceAccessToken(accessToken);
1100
- // Wait for state to update before refreshing AIT
1101
- await new Promise(resolve => setTimeout(resolve, 100));
1102
- await refreshAIT();
1168
+ localStorage.setItem('nxtlinqAITServiceAccessToken', JSON.stringify(accessToken));
1169
+ await queueRuntimeAITRefresh({
1170
+ controller: addressToUse,
1171
+ serviceId,
1172
+ ...(roles !== undefined ? { roles: [...roles] } : {}),
1173
+ ...(permissionGroup !== undefined ? { permissionGroup } : {}),
1174
+ });
1103
1175
  if (autoShowSuccessMessage) {
1104
1176
  showSuccess(walletTextUtils.getWalletText('Successfully signed in with your HIT wallet. You can now use the AI agent.', serviceId));
1105
1177
  }
@@ -2442,82 +2514,6 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2442
2514
  setInputValue(message.text);
2443
2515
  }
2444
2516
  };
2445
- // Generate and register AIT
2446
- const generateAndRegisterAIT = async (newPermissions, isFromAIAgent = false) => {
2447
- let currentSigner = signer;
2448
- let currentAddress = hitAddress;
2449
- // If we have an address but no signer, try to auto-connect wallet
2450
- if (currentAddress && !currentSigner) {
2451
- const storedWalletAddress = localStorage.getItem('walletAddress');
2452
- if (storedWalletAddress === currentAddress) {
2453
- try {
2454
- const autoConnectResult = await connectWallet(false); // Don't show sign-in message yet
2455
- if (autoConnectResult) {
2456
- // Wait for state to update
2457
- await new Promise(resolve => setTimeout(resolve, 1000));
2458
- // Get the updated signer and address
2459
- currentSigner = signerRef.current || signer;
2460
- currentAddress = hitAddressRef.current || hitAddress;
2461
- }
2462
- }
2463
- catch (error) {
2464
- console.error('Auto-connect failed during AIT generation:', error);
2465
- }
2466
- }
2467
- }
2468
- if (!currentSigner || !currentAddress) {
2469
- throw new Error('Missing signer or wallet address');
2470
- }
2471
- return generateAndRegisterAITWithSigner(newPermissions, isFromAIAgent, currentSigner, currentAddress);
2472
- };
2473
- // Generate and register AIT with explicit signer and address
2474
- const generateAndRegisterAITWithSigner = async (newPermissions, isFromAIAgent = false, explicitSigner, explicitAddress) => {
2475
- const currentSigner = explicitSigner || signer;
2476
- const currentAddress = explicitAddress || hitAddress;
2477
- if (!currentSigner || !currentAddress) {
2478
- throw new Error('Missing signer or wallet address');
2479
- }
2480
- // If AI Agent is creating, must check if user has existing AIT
2481
- if (isFromAIAgent && !aitRef.current) {
2482
- throw new Error('You must have an existing AIT before AI Agent can create new AITs');
2483
- }
2484
- const timestamp = Math.floor(Date.now() / 1000);
2485
- const aitId = `did:polygon:nxtlinq:${currentAddress}:${timestamp}`;
2486
- const metadata = {
2487
- permissions: newPermissions || permissions,
2488
- issuedBy: currentAddress,
2489
- };
2490
- const metadataStr = stringify(metadata);
2491
- // ethers v6: utils.keccak256 -> keccak256, utils.toUtf8Bytes -> toUtf8Bytes
2492
- const metadataHash = ethers.keccak256(ethers.toUtf8Bytes(metadataStr));
2493
- const uploadResponse = await nxtlinqApi.metadata.createMetadata(metadata, nxtlinqAITServiceAccessToken || '');
2494
- if ('error' in uploadResponse) {
2495
- throw new Error(`Failed to upload metadata: ${uploadResponse.error}`);
2496
- }
2497
- const { metadataCid } = uploadResponse;
2498
- const createAITParams = {
2499
- aitId,
2500
- controller: currentAddress,
2501
- serviceId,
2502
- metadataHash,
2503
- metadataCid,
2504
- isFromAIAgent: isFromAIAgent,
2505
- parentAITId: isFromAIAgent ? aitRef.current?.aitId : undefined,
2506
- };
2507
- const createAITResponse = await nxtlinqApi.ait.createAIT(createAITParams, nxtlinqAITServiceAccessToken || '');
2508
- if ('error' in createAITResponse) {
2509
- throw new Error(`Failed to create AIT: ${createAITResponse.error}`);
2510
- }
2511
- const aitInfo = {
2512
- aitId,
2513
- controller: currentAddress,
2514
- metadata,
2515
- metadataHash,
2516
- metadataCid,
2517
- };
2518
- setAit(aitInfo);
2519
- setPermissions(newPermissions || permissions);
2520
- };
2521
2517
  // Auto enable AIT permission
2522
2518
  const enableAIT = async (toolName) => {
2523
2519
  if (isAITEnabling)
@@ -2579,35 +2575,41 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2579
2575
  }
2580
2576
  }
2581
2577
  try {
2582
- // Get available permissions to find the tool
2583
- const availablePermissionLabels = availablePermissions.map(p => p.label);
2584
- if (!availablePermissionLabels.includes(toolName)) {
2578
+ const context = {
2579
+ controller: currentHitAddress,
2580
+ serviceId,
2581
+ ...(roles !== undefined ? { roles: [...roles] } : {}),
2582
+ ...(permissionGroup !== undefined ? { permissionGroup } : {}),
2583
+ };
2584
+ const enabled = await runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
2585
+ runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2586
+ const current = await recomputeRuntimeAIT(context);
2587
+ if (!current.maximumPermissions.includes(toolName)) {
2588
+ return false;
2589
+ }
2590
+ const nextDeniedPermissions = removeOneDeniedPermission(current.deniedPermissions, toolName);
2591
+ runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2592
+ await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
2593
+ return true;
2594
+ });
2595
+ if (!enabled) {
2585
2596
  showError(`Tool ${toolName} is not available for your current identity provider`);
2586
2597
  setIsAITEnabling(false);
2587
2598
  return false;
2588
2599
  }
2589
- // Get current permissions from AIT metadata instead of React state
2590
- // This ensures we don't lose existing permissions when enabling new ones
2591
- const currentAITPermissions = aitRef.current?.metadata?.permissions || permissions;
2592
- const newPermissions = [...currentAITPermissions];
2593
- if (!newPermissions.includes(toolName)) {
2594
- newPermissions.push(toolName);
2595
- }
2596
- // Filter out deleted permissions before saving
2597
- const validPermissions = newPermissions.filter(permission => availablePermissionLabels.includes(permission));
2598
- // Generate and register AIT with new permissions
2599
- // For auto-enable, we should create a regular AIT (not AI Agent AIT) if user doesn't have existing AIT
2600
- const shouldCreateAsAIAgent = !!aitRef.current; // Only create as AI Agent if user already has an AIT
2601
- await generateAndRegisterAITWithSigner(validPermissions, shouldCreateAsAIAgent, currentSigner, currentHitAddress);
2602
2600
  showSuccess('AIT permission enabled successfully! You can now use the AI agent.');
2603
- await refreshAIT(true);
2604
2601
  setIsAITEnabling(false);
2605
2602
  return true;
2606
2603
  }
2607
2604
  catch (error) {
2608
- console.error('Failed to auto-enable AIT:', error);
2605
+ if (!(error instanceof StaleRuntimeAITResponseError)) {
2606
+ console.error('Failed to auto-enable AIT:', error);
2607
+ }
2609
2608
  setIsAITEnabling(false);
2610
- if (error instanceof Error) {
2609
+ if (error instanceof StaleRuntimeAITResponseError) {
2610
+ return false;
2611
+ }
2612
+ else if (error instanceof Error) {
2611
2613
  showError(error.message);
2612
2614
  }
2613
2615
  else {
@@ -2620,20 +2622,36 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2620
2622
  const savePermissions = async (newPermissions) => {
2621
2623
  setIsDisabled(true);
2622
2624
  try {
2623
- // Filter out deleted permissions before saving
2624
- const permissionsToSave = newPermissions || permissions;
2625
- const availablePermissionLabels = availablePermissions.map(p => p.label);
2626
- const validPermissions = permissionsToSave.filter(permission => availablePermissionLabels.includes(permission));
2627
- await generateAndRegisterAIT(validPermissions, false);
2625
+ if (!hitAddress) {
2626
+ throw new Error('Please connect your wallet first');
2627
+ }
2628
+ const context = {
2629
+ controller: hitAddress,
2630
+ serviceId,
2631
+ ...(roles !== undefined ? { roles: [...roles] } : {}),
2632
+ ...(permissionGroup !== undefined ? { permissionGroup } : {}),
2633
+ };
2634
+ const checkedPermissions = [...(newPermissions ?? permissions)];
2635
+ await runtimeMutationQueueRef.current.run(runtimeAITSubjectKey(context), async () => {
2636
+ runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2637
+ const fresh = await recomputeRuntimeAIT(context);
2638
+ const nextDeniedPermissions = replaceCurrentMaximumDenyList(fresh.deniedPermissions, fresh.maximumPermissions, checkedPermissions);
2639
+ runtimeRecomputeCoordinatorRef.current.assertContextActive(context);
2640
+ await dispatchRuntimeDenyListReplacement(context, nextDeniedPermissions);
2641
+ });
2628
2642
  showSuccess('AIT permissions saved successfully! You can now use the AI agent with your configured permissions.');
2629
2643
  setShowPermissionForm(false);
2630
2644
  setIsPermissionFormOpen(false);
2631
- await refreshAIT(true);
2632
2645
  }
2633
2646
  catch (error) {
2634
- console.error('Failed to generate AIT:', error);
2647
+ if (!(error instanceof StaleRuntimeAITResponseError)) {
2648
+ console.error('Failed to update AIT deny-list:', error);
2649
+ }
2635
2650
  setIsDisabled(false);
2636
- if (error instanceof Error) {
2651
+ if (error instanceof StaleRuntimeAITResponseError) {
2652
+ return;
2653
+ }
2654
+ else if (error instanceof Error) {
2637
2655
  showError(error.message);
2638
2656
  }
2639
2657
  else {
@@ -2679,14 +2697,12 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2679
2697
  const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
2680
2698
  if (!('error' in walletResponse)) {
2681
2699
  setWalletInfo(walletResponse);
2682
- const aitResponse = await nxtlinqApi.ait.getAITByServiceIdAndController({
2683
- serviceId,
2700
+ await queueRuntimeAITRefresh({
2684
2701
  controller: address,
2685
- customUsername: (!requireWalletIDVVerification && customUsername) ? getFinalCustomUsername(customUsername) : undefined
2686
- }, token);
2687
- if (!('error' in aitResponse)) {
2688
- setAit(aitResponse);
2689
- }
2702
+ serviceId,
2703
+ ...(roles !== undefined ? { roles: [...roles] } : {}),
2704
+ ...(permissionGroup !== undefined ? { permissionGroup } : {}),
2705
+ });
2690
2706
  }
2691
2707
  }
2692
2708
  finally {
@@ -2719,14 +2735,12 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2719
2735
  const walletResponse = await nxtlinqApi.wallet.getWallet({ address }, token);
2720
2736
  if (!('error' in walletResponse)) {
2721
2737
  setWalletInfo(walletResponse);
2722
- const aitResponse = await nxtlinqApi.ait.getAITByServiceIdAndController({
2723
- serviceId,
2738
+ await queueRuntimeAITRefresh({
2724
2739
  controller: address,
2725
- customUsername: (!requireWalletIDVVerification && customUsername) ? getFinalCustomUsername(customUsername) : undefined
2726
- }, token);
2727
- if (!('error' in aitResponse)) {
2728
- setAit(aitResponse);
2729
- }
2740
+ serviceId,
2741
+ ...(roles !== undefined ? { roles: [...roles] } : {}),
2742
+ ...(permissionGroup !== undefined ? { permissionGroup } : {}),
2743
+ });
2730
2744
  }
2731
2745
  }
2732
2746
  finally {
@@ -2835,7 +2849,7 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2835
2849
  if (hitAddress && nxtlinqAITServiceAccessToken) {
2836
2850
  refreshAIT();
2837
2851
  }
2838
- }, [hitAddress, nxtlinqAITServiceAccessToken]);
2852
+ }, [hitAddress, nxtlinqAITServiceAccessToken, permissionGroup, runtimeRolesKey, serviceId]);
2839
2853
  // Set loading state when permission form opens
2840
2854
  React.useEffect(() => {
2841
2855
  if (isPermissionFormOpen && hitAddress) {
@@ -2914,6 +2928,7 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2914
2928
  };
2915
2929
  updateExternalId();
2916
2930
  }, [hitAddress, nxtlinqApi, authFields, pseudoId]);
2931
+ const runtimeAuthorizationMatchesRenderedContext = runtimeAuthorizationMatchesContext(runtimeAuthorizationContextKey, runtimeContext);
2917
2932
  const contextValue = {
2918
2933
  // State
2919
2934
  messages,
@@ -2921,9 +2936,16 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2921
2936
  isLoading,
2922
2937
  isOpen,
2923
2938
  hitAddress,
2924
- ait,
2925
- permissions,
2926
- availablePermissions,
2939
+ ait: runtimeAuthorizationMatchesRenderedContext ? ait : null,
2940
+ permissions: runtimeAuthorizationMatchesRenderedContext ? permissions : [],
2941
+ maximumPermissions: runtimeAuthorizationMatchesRenderedContext ? maximumPermissions : [],
2942
+ deniedPermissions: runtimeAuthorizationMatchesRenderedContext ? deniedPermissions : [],
2943
+ runtimePermissionsUnavailable: runtimeAuthorizationMatchesRenderedContext
2944
+ ? runtimePermissionsUnavailable
2945
+ : runtimeContext !== null,
2946
+ availablePermissions: runtimeAuthorizationMatchesRenderedContext
2947
+ ? availablePermissions
2948
+ : [],
2927
2949
  showPermissionForm,
2928
2950
  isPermissionFormOpen,
2929
2951
  isAITLoading,
@@ -2959,7 +2981,6 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
2959
2981
  setIsOpen,
2960
2982
  setShowPermissionForm,
2961
2983
  setIsPermissionFormOpen,
2962
- setPermissions,
2963
2984
  setIsDisabled,
2964
2985
  setIsWalletLoading,
2965
2986
  setNotification,
@@ -3007,6 +3028,7 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
3007
3028
  onVerifyWallet: (method) => handleVerifyWalletClick(method),
3008
3029
  serviceId,
3009
3030
  permissionGroup,
3031
+ roles,
3010
3032
  // Props
3011
3033
  props: {
3012
3034
  onMessage,
@@ -3024,6 +3046,7 @@ piiDisplayMode = 'redacted', voiceThresholds, debugVoiceRms = false, sttGlossary
3024
3046
  getAuthToken,
3025
3047
  onVerifyWallet,
3026
3048
  permissionGroup,
3049
+ roles,
3027
3050
  onModelChange,
3028
3051
  storageMode,
3029
3052
  requireWalletIDVVerification,
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { ChatBot } from './ChatBot';
2
2
  export { ChatBotProvider, useChatBot } from './context/ChatBotContext';
3
3
  export { ChatBotUI, MessageInput, MessageList, ModelSelector, NotificationModal, PermissionForm, PresetMessages, BerifyMeModal, } from './ui/index';
4
- export type { AIModel, AITMetadata, ChatBotContextType, ChatBotProps, NovaError, NovaResponse, ToolCall, ToolUse, PresetMessage, } from './types/ChatBotTypes';
4
+ export type { AIModel, ChatBotContextType, ChatBotProps, NovaError, NovaResponse, ToolCall, ToolUse, PresetMessage, } from './types/ChatBotTypes';
5
5
  export type { AgentEnvironment, AgentConfig, Attachment, AgentResponse, Message, SendMessageOptions, NxtlinqAgentSnapshot, VoiceSession, VoiceStatus, } from '@bytexbyte/nxtlinq-ai-agent-core-development';
6
6
  export { NxtlinqAgent, setApiHosts, VoiceNotSupportedError, STORAGE_KEYS, } from '@bytexbyte/nxtlinq-ai-agent-core-development';
7
7
  export { createNxtlinqApi, useLocalStorage, useSessionStorage, useSpeechToTextFromMic, useVoiceMode, metakeepClient, getEthers, sleep, walletTextUtils, } from '@bytexbyte/nxtlinq-ai-agent-web-development';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,OAAO,EACP,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,aAAa,GACd,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,WAAW,GACZ,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,YAAY,GACb,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,SAAS,EACT,KAAK,EACL,eAAe,GAChB,MAAM,6CAA6C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EACL,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,OAAO,EACP,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,aAAa,GACd,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,WAAW,GACZ,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,YAAY,EACZ,WAAW,EACX,sBAAsB,EACtB,YAAY,GACb,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,SAAS,EACT,KAAK,EACL,eAAe,GAChB,MAAM,6CAA6C,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { AIT, RuntimeAITResult } from '@bytexbyte/nxtlinq-ai-agent-core-development';
2
+ import * as React from 'react';
3
+ export declare function commitProviderRuntime<T, E>(identityRef: React.MutableRefObject<T>, identity: T, environment: E, publishEnvironment: (environment: E) => void): void;
4
+ export declare function useProviderRuntimeCommit<T, E>(identityRef: React.MutableRefObject<T>, identity: T, environment: E, publishEnvironment: (environment: E) => void): void;
5
+ export declare function replaceCurrentMaximumDenyList(persistedDeniedPermissions: readonly string[], maximumPermissions: readonly string[], checkedPermissions: readonly string[]): string[];
6
+ export declare function removeOneDeniedPermission(persistedDeniedPermissions: readonly string[], permission: string): string[];
7
+ export type RuntimeAITContext = {
8
+ controller: string;
9
+ serviceId: string;
10
+ roles?: string[];
11
+ permissionGroup?: string;
12
+ };
13
+ export declare function runtimeAITContextKey(context: RuntimeAITContext): string;
14
+ export declare function runtimeAITSubjectKey(context: RuntimeAITContext): string;
15
+ export declare function runtimeAuthorizationMatchesContext(authorizationContextKey: string | null, renderedContext: RuntimeAITContext | null): boolean;
16
+ export declare class StaleRuntimeAITResponseError extends Error {
17
+ constructor();
18
+ }
19
+ /**
20
+ * Owns the authoritative recompute lifecycle. Only the newest request for the
21
+ * active captured context may write state; its failures clear state first.
22
+ */
23
+ export declare class RuntimeAITRecomputeCoordinator {
24
+ private activeContextKey;
25
+ private activeContext;
26
+ private generation;
27
+ commitContext(context: RuntimeAITContext | null, invalidate: () => void): boolean;
28
+ getActiveContext(): RuntimeAITContext | null;
29
+ isContextActive(context: RuntimeAITContext): boolean;
30
+ assertContextActive(context: RuntimeAITContext): void;
31
+ run<T>(context: RuntimeAITContext, request: () => Promise<T>, apply: (result: T, context: RuntimeAITContext) => void, clear: () => void): Promise<T>;
32
+ }
33
+ export declare function useRuntimeAITContextCommit(coordinator: RuntimeAITRecomputeCoordinator, context: RuntimeAITContext | null, invalidate: () => void): void;
34
+ export declare function dispatchRuntimeAITCompleteReplacement(coordinator: RuntimeAITRecomputeCoordinator, context: RuntimeAITContext, update: () => Promise<unknown>, converge: (subjectKey: string) => Promise<void>, clear: () => void): Promise<void>;
35
+ /** Serializes reads, complete replacements, and convergence for one persistence subject. */
36
+ export declare class RuntimeAITMutationQueue {
37
+ private readonly tails;
38
+ run<T>(subjectKey: string, mutation: () => Promise<T>): Promise<T>;
39
+ }
40
+ export type RuntimeAuthorizationState = {
41
+ ait: AIT | null;
42
+ maximumPermissions: string[];
43
+ effectivePermissions: string[];
44
+ deniedPermissions: string[];
45
+ selectedRuleId: string | null;
46
+ selectedRuleType: RuntimeAITResult['selectedRuleType'];
47
+ expiresAt: string | null;
48
+ grantActive: boolean;
49
+ unavailable: boolean;
50
+ };
51
+ export declare function runtimeAuthorizationState(result: RuntimeAITResult, controller: string, serviceId: string): RuntimeAuthorizationState;
52
+ export declare function unavailableRuntimeAuthorization(persistedDeniedPermissions: readonly string[]): RuntimeAuthorizationState;
53
+ //# sourceMappingURL=permissionState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionState.d.ts","sourceRoot":"","sources":["../src/permissionState.ts"],"names":[],"mappings":"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"}