@iblai/web-utils 1.6.0 → 1.6.2

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.
package/dist/index.esm.js CHANGED
@@ -996,6 +996,15 @@ function clearCookies() {
996
996
  document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;Domain=${getParentDomain(window.location.hostname)}`;
997
997
  }
998
998
  }
999
+ /**
1000
+ * Get the value of a cookie by name
1001
+ * @param name - Cookie name
1002
+ * @returns The cookie value or null if not found
1003
+ */
1004
+ function getCookieValue(name) {
1005
+ const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`));
1006
+ return match ? decodeURIComponent(match[1]) : null;
1007
+ }
999
1008
  /**
1000
1009
  * Check if user is currently logged in
1001
1010
  * @param tokenKey - The localStorage key for the auth token (default: 'axd_token')
@@ -1060,8 +1069,48 @@ async function redirectToAuthSpa(options) {
1060
1069
  userData: "ibl_user_data",
1061
1070
  tenant: "ibl_tenant",
1062
1071
  logoutTimestamp: "ibl_logout_timestamp",
1063
- }, } = options;
1064
- // Clear localStorage
1072
+ loginTimestamp: "ibl_login_timestamp",
1073
+ tenantSwitching: "ibl_tenant_switching",
1074
+ }, hasNonExpiredAuthToken, isOffline, preserveTokenKey, authRedirectProxy, isNativeApp, } = options;
1075
+ console.log("[redirectToAuthSpa] starting redirect to auth spa", redirectTo, platformKey, logout, saveRedirect);
1076
+ // Skip if a tenant switch is already in progress
1077
+ if (cookieNames.tenantSwitching &&
1078
+ document.cookie.includes(cookieNames.tenantSwitching)) {
1079
+ console.log("[redirectToAuthSpa] Tenant switch in progress, skipping redirect");
1080
+ return;
1081
+ }
1082
+ // Skip if a login occurred after the last logout (login takes precedence)
1083
+ // but only if this app actually has a valid auth token
1084
+ if (hasNonExpiredAuthToken &&
1085
+ cookieNames.loginTimestamp &&
1086
+ cookieNames.logoutTimestamp) {
1087
+ const loginTs = getCookieValue(cookieNames.loginTimestamp);
1088
+ const logoutTs = getCookieValue(cookieNames.logoutTimestamp);
1089
+ const hasValidToken = hasNonExpiredAuthToken();
1090
+ console.log("[redirectToAuthSpa] Login/logout timestamp check", {
1091
+ loginTs,
1092
+ logoutTs,
1093
+ hasValidToken,
1094
+ loginAhead: loginTs && logoutTs ? Number(loginTs) > Number(logoutTs) : false,
1095
+ });
1096
+ if (hasValidToken &&
1097
+ loginTs &&
1098
+ logoutTs &&
1099
+ Number(loginTs) > Number(logoutTs)) {
1100
+ console.log("[redirectToAuthSpa] Login timestamp is ahead of logout timestamp, skipping redirect", { loginTs, logoutTs });
1101
+ return;
1102
+ }
1103
+ }
1104
+ // Skip redirect in offline mode
1105
+ if (isOffline === null || isOffline === void 0 ? void 0 : isOffline()) {
1106
+ console.log("[redirectToAuthSpa] Skipping redirect - offline mode");
1107
+ return;
1108
+ }
1109
+ // Preserve a token before clearing localStorage if requested
1110
+ const preservedToken = preserveTokenKey
1111
+ ? window.localStorage.getItem(preserveTokenKey)
1112
+ : null;
1113
+ console.log("[redirectToAuthSpa] clearing local storage");
1065
1114
  localStorage.clear();
1066
1115
  if (logout || isInIframe()) {
1067
1116
  // Delete authentication cookies for cross-SPA synchronization
@@ -1076,7 +1125,7 @@ async function redirectToAuthSpa(options) {
1076
1125
  deleteCookieOnAllDomains(cookieNames.tenant, currentDomain);
1077
1126
  }
1078
1127
  // Set logout timestamp cookie to trigger logout on other SPAs
1079
- if (cookieNames.logoutTimestamp) {
1128
+ if (cookieNames.logoutTimestamp && !isInIframe()) {
1080
1129
  setCookieForAuth(cookieNames.logoutTimestamp, Date.now().toString());
1081
1130
  }
1082
1131
  }
@@ -1105,8 +1154,22 @@ async function redirectToAuthSpa(options) {
1105
1154
  }
1106
1155
  // Small delay for any pending operations
1107
1156
  await new Promise((resolve) => setTimeout(resolve, 100));
1108
- // Redirect to auth SPA
1109
- window.location.href = authRedirectUrl;
1157
+ if (isNativeApp === null || isNativeApp === void 0 ? void 0 : isNativeApp()) {
1158
+ // On native apps (e.g., Tauri), pass preserved token and navigate directly
1159
+ if (preservedToken && preserveTokenKey) {
1160
+ authRedirectUrl += `&token=${encodeURIComponent(preservedToken)}`;
1161
+ console.log("[redirectToAuthSpa] Added preserved token to auth URL");
1162
+ }
1163
+ console.log("[redirectToAuthSpa] Native app, navigating to auth URL:", authRedirectUrl);
1164
+ window.location.href = authRedirectUrl;
1165
+ }
1166
+ else if (authRedirectProxy) {
1167
+ // Use auth redirect proxy endpoint
1168
+ window.location.href = `${authRedirectProxy}?to=${encodeURIComponent(authRedirectUrl)}`;
1169
+ }
1170
+ else {
1171
+ window.location.href = authRedirectUrl;
1172
+ }
1110
1173
  }
1111
1174
  /**
1112
1175
  * Get the URL for joining a tenant (sign up flow)
@@ -2859,6 +2922,10 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
2859
2922
  * Skipped if enableStorageSync is false
2860
2923
  */
2861
2924
  useEffect(() => {
2925
+ if (skipAuthCheck) {
2926
+ setInitialSyncComplete(true);
2927
+ return;
2928
+ }
2862
2929
  console.log("[AuthProvider] cookie-sync effect running", {
2863
2930
  pathname,
2864
2931
  enableStorageSync,
@@ -2967,7 +3034,7 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
2967
3034
  * Skipped if enableStorageSync is false
2968
3035
  */
2969
3036
  useEffect(() => {
2970
- if (!storageService || !isWeb$1() || !enableStorageSync)
3037
+ if (!storageService || !isWeb$1() || !enableStorageSync || skipAuthCheck)
2971
3038
  return;
2972
3039
  const handleStorageChange = async (event) => {
2973
3040
  // Only handle changes to our auth-related keys
@@ -3067,6 +3134,11 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
3067
3134
  }
3068
3135
  }
3069
3136
  useEffect(() => {
3137
+ if (skipAuthCheck) {
3138
+ setIsAuthenticating(false);
3139
+ setUserIsAccessingPublicRoute(true);
3140
+ return;
3141
+ }
3070
3142
  // Wait for initial sync to complete before performing auth check
3071
3143
  if (!initialSyncComplete) {
3072
3144
  console.log("[useAuthProvider] Waiting for initial sync to complete...");
@@ -3144,7 +3216,7 @@ async function determineAuthRequired(middleware, pathname) {
3144
3216
  * 4. Handles redirects to auth SPA when needed
3145
3217
  * 5. Manages public route access state
3146
3218
  */
3147
- function AuthProvider({ children, fallback, middleware = new Map(), onAuthSuccess, onAuthFailure, redirectToAuthSpa, hasNonExpiredAuthToken, username, pathname, skipAuthCheck = false, storageService, token, enableStorageSync = true, skip = false, }) {
3219
+ function AuthProvider({ children, fallback, middleware = new Map(), onAuthSuccess, onAuthFailure, redirectToAuthSpa, hasNonExpiredAuthToken, username, pathname, storageService, token, enableStorageSync = true, skip = false, }) {
3148
3220
  const { isAuthenticating, userIsAccessingPublicRoute, setUserIsAccessingPublicRoute, } = useAuthProvider({
3149
3221
  middleware,
3150
3222
  onAuthSuccess,
@@ -3154,7 +3226,7 @@ function AuthProvider({ children, fallback, middleware = new Map(), onAuthSucces
3154
3226
  username,
3155
3227
  pathname,
3156
3228
  storageService,
3157
- skipAuthCheck,
3229
+ skip,
3158
3230
  token,
3159
3231
  enableStorageSync,
3160
3232
  });
@@ -17626,6 +17698,570 @@ createApi({
17626
17698
  }),
17627
17699
  });
17628
17700
 
17701
+ const CLAW_REDUCER_PATH = 'clawApiSlice';
17702
+ const CLAW_TAG_TYPES = [
17703
+ 'ClawMentorConfig',
17704
+ 'ClawInstances',
17705
+ 'AgentConfig',
17706
+ 'AgentSkills',
17707
+ 'AgentSkillResources',
17708
+ 'MentorSkillAssignments',
17709
+ ];
17710
+ const CLAW_ENDPOINTS = {
17711
+ // ── Claw Mentor Config (singular, nested under mentor) ─────────────────────
17712
+ GET_MENTOR_CONFIG: {
17713
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17714
+ service: SERVICES.DM,
17715
+ },
17716
+ CREATE_MENTOR_CONFIG: {
17717
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17718
+ service: SERVICES.DM,
17719
+ },
17720
+ UPDATE_MENTOR_CONFIG: {
17721
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17722
+ service: SERVICES.DM,
17723
+ },
17724
+ DELETE_MENTOR_CONFIG: {
17725
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17726
+ service: SERVICES.DM,
17727
+ },
17728
+ PUSH_CONFIG: {
17729
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/push-config/`,
17730
+ service: SERVICES.DM,
17731
+ },
17732
+ // ── Claw Instances (unchanged) ─────────────────────────────────────────────
17733
+ GET_INSTANCES: {
17734
+ path: (org) => `/api/ai-mentor/orgs/${org}/claw/instances/`,
17735
+ service: SERVICES.DM,
17736
+ },
17737
+ GET_INSTANCE: {
17738
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/`,
17739
+ service: SERVICES.DM,
17740
+ },
17741
+ CREATE_INSTANCE: {
17742
+ path: (org) => `/api/ai-mentor/orgs/${org}/claw/instances/`,
17743
+ service: SERVICES.DM,
17744
+ },
17745
+ UPDATE_INSTANCE: {
17746
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/`,
17747
+ service: SERVICES.DM,
17748
+ },
17749
+ DELETE_INSTANCE: {
17750
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/`,
17751
+ service: SERVICES.DM,
17752
+ },
17753
+ HEALTH_CHECK_INSTANCE: {
17754
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/health-check/`,
17755
+ service: SERVICES.DM,
17756
+ },
17757
+ TEST_CONNECTIVITY_INSTANCE: {
17758
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/test-connectivity/`,
17759
+ service: SERVICES.DM,
17760
+ },
17761
+ REFRESH_VERSION_INSTANCE: {
17762
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/refresh-version/`,
17763
+ service: SERVICES.DM,
17764
+ },
17765
+ // ── Agent Config (singular, nested under mentor) ───────────────────────────
17766
+ GET_AGENT_CONFIG: {
17767
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/agent-config/`,
17768
+ service: SERVICES.DM,
17769
+ },
17770
+ /** PATCH is upsert — first write bootstraps the row, no separate POST. */
17771
+ UPDATE_AGENT_CONFIG: {
17772
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/agent-config/`,
17773
+ service: SERVICES.DM,
17774
+ },
17775
+ // ── Agent Skills (platform-level, unchanged) ───────────────────────────────
17776
+ GET_AGENT_SKILLS: {
17777
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skills/`,
17778
+ service: SERVICES.DM,
17779
+ },
17780
+ GET_AGENT_SKILL: {
17781
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skills/${id}/`,
17782
+ service: SERVICES.DM,
17783
+ },
17784
+ CREATE_AGENT_SKILL: {
17785
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skills/`,
17786
+ service: SERVICES.DM,
17787
+ },
17788
+ UPDATE_AGENT_SKILL: {
17789
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skills/${id}/`,
17790
+ service: SERVICES.DM,
17791
+ },
17792
+ DELETE_AGENT_SKILL: {
17793
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skills/${id}/`,
17794
+ service: SERVICES.DM,
17795
+ },
17796
+ // ── Agent Skill Resources (file resources attached to skills) ──────────────
17797
+ GET_AGENT_SKILL_RESOURCES: {
17798
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/`,
17799
+ service: SERVICES.DM,
17800
+ },
17801
+ GET_AGENT_SKILL_RESOURCE: {
17802
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/${id}/`,
17803
+ service: SERVICES.DM,
17804
+ },
17805
+ CREATE_AGENT_SKILL_RESOURCE: {
17806
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/`,
17807
+ service: SERVICES.DM,
17808
+ },
17809
+ UPDATE_AGENT_SKILL_RESOURCE: {
17810
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/${id}/`,
17811
+ service: SERVICES.DM,
17812
+ },
17813
+ DELETE_AGENT_SKILL_RESOURCE: {
17814
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/${id}/`,
17815
+ service: SERVICES.DM,
17816
+ },
17817
+ // ── Mentor Skill Assignments (nested under mentor) ─────────────────────────
17818
+ GET_MENTOR_SKILL_ASSIGNMENTS: {
17819
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/`,
17820
+ service: SERVICES.DM,
17821
+ },
17822
+ CREATE_MENTOR_SKILL_ASSIGNMENT: {
17823
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/`,
17824
+ service: SERVICES.DM,
17825
+ },
17826
+ GET_MENTOR_SKILL_ASSIGNMENT: {
17827
+ path: (org, mentorUniqueId, assignmentPk) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/${assignmentPk}/`,
17828
+ service: SERVICES.DM,
17829
+ },
17830
+ UPDATE_MENTOR_SKILL_ASSIGNMENT: {
17831
+ path: (org, mentorUniqueId, assignmentPk) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/${assignmentPk}/`,
17832
+ service: SERVICES.DM,
17833
+ },
17834
+ DELETE_MENTOR_SKILL_ASSIGNMENT: {
17835
+ path: (org, mentorUniqueId, assignmentPk) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/${assignmentPk}/`,
17836
+ service: SERVICES.DM,
17837
+ },
17838
+ };
17839
+
17840
+ /**
17841
+ * Normalize API responses that may return either a plain array or a
17842
+ * paginated envelope `{ results: T[] }`.
17843
+ */
17844
+ function normalizeList(response) {
17845
+ return Array.isArray(response) ? response : response.results;
17846
+ }
17847
+ const clawApiSlice = createApi({
17848
+ reducerPath: CLAW_REDUCER_PATH,
17849
+ baseQuery: iblFetchBaseQuery,
17850
+ tagTypes: [...CLAW_TAG_TYPES],
17851
+ endpoints: (builder) => ({
17852
+ // ── Claw Mentor Config (singular) ─────────────────────────────────────
17853
+ getClawMentorConfig: builder.query({
17854
+ query: (args) => ({
17855
+ url: CLAW_ENDPOINTS.GET_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17856
+ service: CLAW_ENDPOINTS.GET_MENTOR_CONFIG.service,
17857
+ }),
17858
+ providesTags: (_result, _error, args) => [
17859
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17860
+ ],
17861
+ }),
17862
+ createClawMentorConfig: builder.mutation({
17863
+ query: (args) => ({
17864
+ url: CLAW_ENDPOINTS.CREATE_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17865
+ service: CLAW_ENDPOINTS.CREATE_MENTOR_CONFIG.service,
17866
+ method: 'POST',
17867
+ body: {
17868
+ server: args.server,
17869
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
17870
+ ...(args.agent_id !== undefined && { agent_id: args.agent_id }),
17871
+ },
17872
+ }),
17873
+ // Seed the GET cache with the create response and then invalidate so the
17874
+ // subscribed query refetches the joined fields (server_name, status, etc.)
17875
+ // that the POST body doesn't include. The refetch is a 200 — no retry storm.
17876
+ async onQueryStarted({ org, mentorUniqueId }, { dispatch, queryFulfilled }) {
17877
+ try {
17878
+ const { data } = await queryFulfilled;
17879
+ dispatch(clawApiSlice.util.upsertQueryData('getClawMentorConfig', { org, mentorUniqueId }, data));
17880
+ }
17881
+ catch (_a) {
17882
+ // Surface error via the mutation's own error state.
17883
+ }
17884
+ },
17885
+ invalidatesTags: (_result, _error, args) => [
17886
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17887
+ ],
17888
+ }),
17889
+ updateClawMentorConfig: builder.mutation({
17890
+ query: (args) => ({
17891
+ url: CLAW_ENDPOINTS.UPDATE_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17892
+ service: CLAW_ENDPOINTS.UPDATE_MENTOR_CONFIG.service,
17893
+ method: 'PATCH',
17894
+ body: {
17895
+ ...(args.server !== undefined && { server: args.server }),
17896
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
17897
+ ...(args.auto_push !== undefined && { auto_push: args.auto_push }),
17898
+ ...(args.agent_config !== undefined && { agent_config: args.agent_config }),
17899
+ ...(args.agent_id !== undefined && { agent_id: args.agent_id }),
17900
+ },
17901
+ }),
17902
+ invalidatesTags: (_result, _error, args) => [
17903
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17904
+ ],
17905
+ }),
17906
+ deleteClawMentorConfig: builder.mutation({
17907
+ query: (args) => ({
17908
+ url: CLAW_ENDPOINTS.DELETE_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17909
+ service: CLAW_ENDPOINTS.DELETE_MENTOR_CONFIG.service,
17910
+ method: 'DELETE',
17911
+ }),
17912
+ // Optimistically clear the GET cache before the request resolves so the
17913
+ // UI flips to "not connected" instantly. On failure, invalidate to refetch
17914
+ // the real state. We don't invalidate on success — the GET would 404 and
17915
+ // the base query retries 3× on error, which is the lag the user sees.
17916
+ async onQueryStarted({ org, mentorUniqueId }, { dispatch, queryFulfilled }) {
17917
+ dispatch(clawApiSlice.util.upsertQueryData('getClawMentorConfig', { org, mentorUniqueId }, null));
17918
+ try {
17919
+ await queryFulfilled;
17920
+ }
17921
+ catch (_a) {
17922
+ dispatch(clawApiSlice.util.invalidateTags([{ type: 'ClawMentorConfig', id: mentorUniqueId }]));
17923
+ }
17924
+ },
17925
+ }),
17926
+ pushClawConfig: builder.mutation({
17927
+ query: (args) => ({
17928
+ url: CLAW_ENDPOINTS.PUSH_CONFIG.path(args.org, args.mentorUniqueId),
17929
+ service: CLAW_ENDPOINTS.PUSH_CONFIG.service,
17930
+ method: 'POST',
17931
+ }),
17932
+ invalidatesTags: (_result, _error, args) => [
17933
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17934
+ ],
17935
+ }),
17936
+ // ── Claw Instances ────────────────────────────────────────────────────
17937
+ getClawInstances: builder.query({
17938
+ query: (args) => ({
17939
+ url: CLAW_ENDPOINTS.GET_INSTANCES.path(args.org),
17940
+ service: CLAW_ENDPOINTS.GET_INSTANCES.service,
17941
+ }),
17942
+ transformResponse: (response) => normalizeList(response),
17943
+ providesTags: ['ClawInstances'],
17944
+ }),
17945
+ getClawInstance: builder.query({
17946
+ query: (args) => ({
17947
+ url: CLAW_ENDPOINTS.GET_INSTANCE.path(args.org, args.id),
17948
+ service: CLAW_ENDPOINTS.GET_INSTANCE.service,
17949
+ }),
17950
+ providesTags: (_result, _error, args) => [{ type: 'ClawInstances', id: args.id }],
17951
+ }),
17952
+ createClawInstance: builder.mutation({
17953
+ query: (args) => ({
17954
+ url: CLAW_ENDPOINTS.CREATE_INSTANCE.path(args.org),
17955
+ service: CLAW_ENDPOINTS.CREATE_INSTANCE.service,
17956
+ method: 'POST',
17957
+ body: {
17958
+ name: args.name,
17959
+ claw_type: args.claw_type,
17960
+ server_url: args.server_url,
17961
+ ...(args.gateway_token && { gateway_token: args.gateway_token }),
17962
+ ...(args.auth_headers && { auth_headers: args.auth_headers }),
17963
+ ...(args.connection_params && { connection_params: args.connection_params }),
17964
+ ...(args.deployment_backend !== undefined && {
17965
+ deployment_backend: args.deployment_backend,
17966
+ }),
17967
+ },
17968
+ }),
17969
+ invalidatesTags: ['ClawInstances'],
17970
+ }),
17971
+ updateClawInstance: builder.mutation({
17972
+ query: (args) => ({
17973
+ url: CLAW_ENDPOINTS.UPDATE_INSTANCE.path(args.org, args.id),
17974
+ service: CLAW_ENDPOINTS.UPDATE_INSTANCE.service,
17975
+ method: 'PATCH',
17976
+ body: {
17977
+ ...(args.name !== undefined && { name: args.name }),
17978
+ ...(args.claw_type !== undefined && { claw_type: args.claw_type }),
17979
+ ...(args.server_url !== undefined && { server_url: args.server_url }),
17980
+ ...(args.gateway_token && { gateway_token: args.gateway_token }),
17981
+ ...(args.auth_headers && { auth_headers: args.auth_headers }),
17982
+ ...(args.connection_params && { connection_params: args.connection_params }),
17983
+ ...(args.deployment_backend !== undefined && {
17984
+ deployment_backend: args.deployment_backend,
17985
+ }),
17986
+ },
17987
+ }),
17988
+ invalidatesTags: (_result, _error, args) => [
17989
+ { type: 'ClawInstances', id: args.id },
17990
+ 'ClawInstances',
17991
+ ],
17992
+ }),
17993
+ deleteClawInstance: builder.mutation({
17994
+ query: (args) => ({
17995
+ url: CLAW_ENDPOINTS.DELETE_INSTANCE.path(args.org, args.id),
17996
+ service: CLAW_ENDPOINTS.DELETE_INSTANCE.service,
17997
+ method: 'DELETE',
17998
+ }),
17999
+ invalidatesTags: ['ClawInstances'],
18000
+ }),
18001
+ healthCheckClawInstance: builder.mutation({
18002
+ query: (args) => ({
18003
+ url: CLAW_ENDPOINTS.HEALTH_CHECK_INSTANCE.path(args.org, args.id),
18004
+ service: CLAW_ENDPOINTS.HEALTH_CHECK_INSTANCE.service,
18005
+ method: 'POST',
18006
+ }),
18007
+ // Health check updates last_health_check / last_health_status / claw_version
18008
+ // on the instance — invalidate so the list refetches with fresh values.
18009
+ invalidatesTags: (_result, _error, args) => [
18010
+ { type: 'ClawInstances', id: args.id },
18011
+ 'ClawInstances',
18012
+ ],
18013
+ }),
18014
+ testConnectivityClawInstance: builder.mutation({
18015
+ query: (args) => ({
18016
+ url: CLAW_ENDPOINTS.TEST_CONNECTIVITY_INSTANCE.path(args.org, args.id),
18017
+ service: CLAW_ENDPOINTS.TEST_CONNECTIVITY_INSTANCE.service,
18018
+ method: 'POST',
18019
+ }),
18020
+ invalidatesTags: (_result, _error, args) => [
18021
+ { type: 'ClawInstances', id: args.id },
18022
+ 'ClawInstances',
18023
+ ],
18024
+ }),
18025
+ refreshVersionClawInstance: builder.mutation({
18026
+ query: (args) => ({
18027
+ url: CLAW_ENDPOINTS.REFRESH_VERSION_INSTANCE.path(args.org, args.id),
18028
+ service: CLAW_ENDPOINTS.REFRESH_VERSION_INSTANCE.service,
18029
+ method: 'POST',
18030
+ }),
18031
+ // Refresh-version updates the instance's `claw_version` (and may touch
18032
+ // health fields too) — invalidate so the table picks up the new value.
18033
+ invalidatesTags: (_result, _error, args) => [
18034
+ { type: 'ClawInstances', id: args.id },
18035
+ 'ClawInstances',
18036
+ ],
18037
+ }),
18038
+ // ── Agent Config (singular, PATCH is upsert) ──────────────────────────
18039
+ getAgentConfig: builder.query({
18040
+ query: (args) => ({
18041
+ url: CLAW_ENDPOINTS.GET_AGENT_CONFIG.path(args.org, args.mentorUniqueId),
18042
+ service: CLAW_ENDPOINTS.GET_AGENT_CONFIG.service,
18043
+ }),
18044
+ providesTags: (_result, _error, args) => [{ type: 'AgentConfig', id: args.mentorUniqueId }],
18045
+ }),
18046
+ updateAgentConfig: builder.mutation({
18047
+ query: (args) => ({
18048
+ url: CLAW_ENDPOINTS.UPDATE_AGENT_CONFIG.path(args.org, args.mentorUniqueId),
18049
+ service: CLAW_ENDPOINTS.UPDATE_AGENT_CONFIG.service,
18050
+ method: 'PATCH',
18051
+ body: {
18052
+ ...(args.identity !== undefined && { identity: args.identity }),
18053
+ ...(args.soul !== undefined && { soul: args.soul }),
18054
+ ...(args.user_context !== undefined && { user_context: args.user_context }),
18055
+ ...(args.tools !== undefined && { tools: args.tools }),
18056
+ ...(args.agents !== undefined && { agents: args.agents }),
18057
+ ...(args.bootstrap !== undefined && { bootstrap: args.bootstrap }),
18058
+ ...(args.heartbeat !== undefined && { heartbeat: args.heartbeat }),
18059
+ ...(args.memory !== undefined && { memory: args.memory }),
18060
+ ...(args.model !== undefined && { model: args.model }),
18061
+ ...(args.config !== undefined && { config: args.config }),
18062
+ },
18063
+ }),
18064
+ // PATCH is upsert and returns the full AgentConfig. Write it straight into
18065
+ // the GET cache so UI subscribers see the new value immediately — relying
18066
+ // on tag invalidation alone leaves a stale window when the prior GET was a
18067
+ // 404 (the entry sits in error state until the refetch completes).
18068
+ async onQueryStarted({ org, mentorUniqueId }, { dispatch, queryFulfilled }) {
18069
+ try {
18070
+ const { data } = await queryFulfilled;
18071
+ dispatch(clawApiSlice.util.upsertQueryData('getAgentConfig', { org, mentorUniqueId }, data));
18072
+ }
18073
+ catch (_a) {
18074
+ // Mutation error surfaces via the hook's own state.
18075
+ }
18076
+ },
18077
+ invalidatesTags: (_result, _error, args) => [
18078
+ { type: 'AgentConfig', id: args.mentorUniqueId },
18079
+ ],
18080
+ }),
18081
+ // ── Agent Skills (platform-level) ─────────────────────────────────────
18082
+ getAgentSkills: builder.query({
18083
+ query: (args) => ({
18084
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILLS.path(args.org),
18085
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILLS.service,
18086
+ }),
18087
+ transformResponse: (response) => normalizeList(response),
18088
+ providesTags: ['AgentSkills'],
18089
+ }),
18090
+ getAgentSkill: builder.query({
18091
+ query: (args) => ({
18092
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILL.path(args.org, args.id),
18093
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILL.service,
18094
+ }),
18095
+ providesTags: (_result, _error, args) => [{ type: 'AgentSkills', id: args.id }],
18096
+ }),
18097
+ createAgentSkill: builder.mutation({
18098
+ query: (args) => ({
18099
+ url: CLAW_ENDPOINTS.CREATE_AGENT_SKILL.path(args.org),
18100
+ service: CLAW_ENDPOINTS.CREATE_AGENT_SKILL.service,
18101
+ method: 'POST',
18102
+ body: {
18103
+ name: args.name,
18104
+ slug: args.slug,
18105
+ ...(args.description !== undefined && { description: args.description }),
18106
+ ...(args.version !== undefined && { version: args.version }),
18107
+ ...(args.instruction !== undefined && { instruction: args.instruction }),
18108
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18109
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18110
+ },
18111
+ }),
18112
+ invalidatesTags: ['AgentSkills'],
18113
+ }),
18114
+ updateAgentSkill: builder.mutation({
18115
+ query: (args) => ({
18116
+ url: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL.path(args.org, args.id),
18117
+ service: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL.service,
18118
+ method: 'PATCH',
18119
+ body: {
18120
+ ...(args.name !== undefined && { name: args.name }),
18121
+ ...(args.slug !== undefined && { slug: args.slug }),
18122
+ ...(args.description !== undefined && { description: args.description }),
18123
+ ...(args.version !== undefined && { version: args.version }),
18124
+ ...(args.instruction !== undefined && { instruction: args.instruction }),
18125
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18126
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18127
+ },
18128
+ }),
18129
+ invalidatesTags: (_result, _error, args) => [
18130
+ { type: 'AgentSkills', id: args.id },
18131
+ 'AgentSkills',
18132
+ ],
18133
+ }),
18134
+ deleteAgentSkill: builder.mutation({
18135
+ query: (args) => ({
18136
+ url: CLAW_ENDPOINTS.DELETE_AGENT_SKILL.path(args.org, args.id),
18137
+ service: CLAW_ENDPOINTS.DELETE_AGENT_SKILL.service,
18138
+ method: 'DELETE',
18139
+ }),
18140
+ invalidatesTags: ['AgentSkills'],
18141
+ }),
18142
+ // ── Agent Skill Resources ─────────────────────────────────────────────
18143
+ getAgentSkillResources: builder.query({
18144
+ query: (args) => ({
18145
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCES.path(args.org),
18146
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCES.service,
18147
+ params: {
18148
+ ...(args.skill !== undefined && { skill: args.skill }),
18149
+ ...(args.file_type !== undefined && { file_type: args.file_type }),
18150
+ },
18151
+ }),
18152
+ transformResponse: (response) => normalizeList(response),
18153
+ providesTags: ['AgentSkillResources'],
18154
+ }),
18155
+ getAgentSkillResource: builder.query({
18156
+ query: (args) => ({
18157
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCE.path(args.org, args.id),
18158
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCE.service,
18159
+ }),
18160
+ providesTags: (_result, _error, args) => [{ type: 'AgentSkillResources', id: args.id }],
18161
+ }),
18162
+ createAgentSkillResource: builder.mutation({
18163
+ query: (args) => ({
18164
+ url: CLAW_ENDPOINTS.CREATE_AGENT_SKILL_RESOURCE.path(args.org),
18165
+ service: CLAW_ENDPOINTS.CREATE_AGENT_SKILL_RESOURCE.service,
18166
+ method: 'POST',
18167
+ body: {
18168
+ skill: args.skill,
18169
+ file_type: args.file_type,
18170
+ name: args.name,
18171
+ ...(args.url !== undefined && { url: args.url }),
18172
+ ...(args.content !== undefined && { content: args.content }),
18173
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18174
+ },
18175
+ }),
18176
+ invalidatesTags: ['AgentSkillResources'],
18177
+ }),
18178
+ updateAgentSkillResource: builder.mutation({
18179
+ query: (args) => ({
18180
+ url: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL_RESOURCE.path(args.org, args.id),
18181
+ service: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL_RESOURCE.service,
18182
+ method: 'PATCH',
18183
+ body: {
18184
+ ...(args.skill !== undefined && { skill: args.skill }),
18185
+ ...(args.file_type !== undefined && { file_type: args.file_type }),
18186
+ ...(args.name !== undefined && { name: args.name }),
18187
+ ...(args.url !== undefined && { url: args.url }),
18188
+ ...(args.content !== undefined && { content: args.content }),
18189
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18190
+ },
18191
+ }),
18192
+ invalidatesTags: (_result, _error, args) => [
18193
+ { type: 'AgentSkillResources', id: args.id },
18194
+ 'AgentSkillResources',
18195
+ ],
18196
+ }),
18197
+ deleteAgentSkillResource: builder.mutation({
18198
+ query: (args) => ({
18199
+ url: CLAW_ENDPOINTS.DELETE_AGENT_SKILL_RESOURCE.path(args.org, args.id),
18200
+ service: CLAW_ENDPOINTS.DELETE_AGENT_SKILL_RESOURCE.service,
18201
+ method: 'DELETE',
18202
+ }),
18203
+ invalidatesTags: ['AgentSkillResources'],
18204
+ }),
18205
+ // ── Mentor Skill Assignments (nested under mentor) ────────────────────
18206
+ getMentorSkillAssignments: builder.query({
18207
+ query: (args) => ({
18208
+ url: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENTS.path(args.org, args.mentorUniqueId),
18209
+ service: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENTS.service,
18210
+ }),
18211
+ transformResponse: (response) => normalizeList(response),
18212
+ providesTags: (_result, _error, args) => [
18213
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18214
+ ],
18215
+ }),
18216
+ getMentorSkillAssignment: builder.query({
18217
+ query: (args) => ({
18218
+ url: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId, args.assignmentPk),
18219
+ service: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENT.service,
18220
+ }),
18221
+ providesTags: (_result, _error, args) => [
18222
+ { type: 'MentorSkillAssignments', id: args.assignmentPk },
18223
+ ],
18224
+ }),
18225
+ createMentorSkillAssignment: builder.mutation({
18226
+ query: (args) => ({
18227
+ url: CLAW_ENDPOINTS.CREATE_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId),
18228
+ service: CLAW_ENDPOINTS.CREATE_MENTOR_SKILL_ASSIGNMENT.service,
18229
+ method: 'POST',
18230
+ body: {
18231
+ skill: args.skill,
18232
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18233
+ },
18234
+ }),
18235
+ invalidatesTags: (_result, _error, args) => [
18236
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18237
+ ],
18238
+ }),
18239
+ updateMentorSkillAssignment: builder.mutation({
18240
+ query: (args) => ({
18241
+ url: CLAW_ENDPOINTS.UPDATE_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId, args.assignmentPk),
18242
+ service: CLAW_ENDPOINTS.UPDATE_MENTOR_SKILL_ASSIGNMENT.service,
18243
+ method: 'PATCH',
18244
+ body: {
18245
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18246
+ },
18247
+ }),
18248
+ invalidatesTags: (_result, _error, args) => [
18249
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18250
+ ],
18251
+ }),
18252
+ deleteMentorSkillAssignment: builder.mutation({
18253
+ query: (args) => ({
18254
+ url: CLAW_ENDPOINTS.DELETE_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId, args.assignmentPk),
18255
+ service: CLAW_ENDPOINTS.DELETE_MENTOR_SKILL_ASSIGNMENT.service,
18256
+ method: 'DELETE',
18257
+ }),
18258
+ invalidatesTags: (_result, _error, args) => [
18259
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18260
+ ],
18261
+ }),
18262
+ }),
18263
+ });
18264
+
17629
18265
  const CUSTOM_DOMAIN_REDUCER_PATH = 'customDomainApiSlice';
17630
18266
  const CUSTOM_DOMAIN_ENDPOINTS = {
17631
18267
  GET_CUSTOM_DOMAINS: {
@@ -23982,5 +24618,5 @@ const checkRbacPermission = (rbacPermissions, rbacResource, enableRBAC = true) =
23982
24618
  return checkRbacPermissionInternal(rbacPermissions, rbacResource);
23983
24619
  };
23984
24620
 
23985
- export { ALPHANUMERIC_32_REGEX, ANONYMOUS_USERNAME, AuthContext, AuthContextProvider, AuthProvider, CHAT_AREA_SIZE, LOCAL_STORAGE_KEYS, MAX_INITIAL_WEBSOCKET_CONNECTION_ATTEMPTS, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, METADATAS, MentorProvider, REQUIRED_ACTIONS_FOR_GROUPS, STREAMING_CONTENT_BUFFER_THRESHOLD, STREAMING_CONTENT_FLUSH_INTERVAL, SUBSCRIPTION_MESSAGES, SUBSCRIPTION_PACKAGES, SUBSCRIPTION_PACKAGES_V2, SUBSCRIPTION_TRIGGERS, SUBSCRIPTION_V2_TRIGGERS, SubscriptionFlow, SubscriptionFlowV2, TOOLS, TenantContext, TenantContextProvider, TenantProvider, TimeTracker, WithFormPermissions, WithPermissions, addFiles, addProtocolToUrl, advancedTabs, advancedTabsProperties, chatActions, chatSliceReducerShared, checkModelAvailable, checkOllamaHealth, checkRbacPermission, clearAuthCookies, clearCookies, clearCurrentTenantCookie, clearFiles, combineCSVData, convertToOllamaMessages, createFileReference, createMultipleFileReferences, csvDataToText, defaultSessionIds, deleteCookie, deleteCookieOnAllDomains, filesReducer, filesSlice, formatRelativeTime, getAuthSpaJoinUrl, getDomainParts, getFileInfo, getInitials, getLocalLLMSystemPrompt, getNextNavigation, getParentDomain, getPlatform, getPlatformKey, getTimeAgo, getUserName, handleLogout, isAlphaNumeric32, isExpo, isInIframe, isJSON, isLoggedIn, isNode, isReactNative$1 as isReactNative, isTauri, isWeb$2 as isWeb, loadMetadataConfig, markdownToPlainText, monetizationSlice, parseCSV, redirectToAuthSpa, redirectToAuthSpaJoinTenant, removeFile, requestPresignedUrl, safeRequire, selectActiveChatMessages, selectActiveTab, selectArtifactsEnabled, selectChats, selectCurrentStreamingArtifact, selectCurrentStreamingMessage, selectDocumentFilter, selectIframeContext, selectIsError, selectIsPending, selectIsStopped, selectIsTyping, selectLastArtifactContentFlushTime, selectMetadata, selectNumberOfActiveChatMessages, selectSessionId, selectSessionIds, selectShouldStartNewChat, selectShowingSharedChat, selectStatus, selectStreaming, selectStreamingArtifactContentBuffer, selectStreamingArtifactFullContent, selectToken, selectTokenEnabled, selectTools, sendMessageToParentWebsite, setAccessCheckResponse, setAdvancedDisplayMonetizationCheckoutModal, setCookieForAuth, setDisplayMonetizationCheckoutModal, showMonetizationCheckoutModal, streamOllamaChat, syncAuthToCookies, tenantKeySchema, tenantSchema, translatePrompt, updateFileMetadata, updateFileProgress, updateFileRetryCount, updateFileStatus, updateFileUrl, updateFileUrlFromWebSocket, uploadToS3, useAdvancedChat, useAuthContext, useAuthProvider, useChat, useDayJs, useExternalPricingPlan, useMentorSettings, useMentorTools, useProfileImageUpload, useStripeUpgrade, useSubscriptionHandler, useSubscriptionHandlerV2, useTenantContext, useTenantMetadata, useTimeTracker, useTimeTrackerNative, useUserProfileUpdate, userDataSchema, validateFile };
24621
+ export { ALPHANUMERIC_32_REGEX, ANONYMOUS_USERNAME, AuthContext, AuthContextProvider, AuthProvider, CHAT_AREA_SIZE, LOCAL_STORAGE_KEYS, MAX_INITIAL_WEBSOCKET_CONNECTION_ATTEMPTS, MENTOR_CHAT_DOCUMENTS_EXTENSIONS, METADATAS, MentorProvider, REQUIRED_ACTIONS_FOR_GROUPS, STREAMING_CONTENT_BUFFER_THRESHOLD, STREAMING_CONTENT_FLUSH_INTERVAL, SUBSCRIPTION_MESSAGES, SUBSCRIPTION_PACKAGES, SUBSCRIPTION_PACKAGES_V2, SUBSCRIPTION_TRIGGERS, SUBSCRIPTION_V2_TRIGGERS, SubscriptionFlow, SubscriptionFlowV2, TOOLS, TenantContext, TenantContextProvider, TenantProvider, TimeTracker, WithFormPermissions, WithPermissions, addFiles, addProtocolToUrl, advancedTabs, advancedTabsProperties, chatActions, chatSliceReducerShared, checkModelAvailable, checkOllamaHealth, checkRbacPermission, clearAuthCookies, clearCookies, clearCurrentTenantCookie, clearFiles, combineCSVData, convertToOllamaMessages, createFileReference, createMultipleFileReferences, csvDataToText, defaultSessionIds, deleteCookie, deleteCookieOnAllDomains, filesReducer, filesSlice, formatRelativeTime, getAuthSpaJoinUrl, getCookieValue, getDomainParts, getFileInfo, getInitials, getLocalLLMSystemPrompt, getNextNavigation, getParentDomain, getPlatform, getPlatformKey, getTimeAgo, getUserName, handleLogout, isAlphaNumeric32, isExpo, isInIframe, isJSON, isLoggedIn, isNode, isReactNative$1 as isReactNative, isTauri, isWeb$2 as isWeb, loadMetadataConfig, markdownToPlainText, monetizationSlice, parseCSV, redirectToAuthSpa, redirectToAuthSpaJoinTenant, removeFile, requestPresignedUrl, safeRequire, selectActiveChatMessages, selectActiveTab, selectArtifactsEnabled, selectChats, selectCurrentStreamingArtifact, selectCurrentStreamingMessage, selectDocumentFilter, selectIframeContext, selectIsError, selectIsPending, selectIsStopped, selectIsTyping, selectLastArtifactContentFlushTime, selectMetadata, selectNumberOfActiveChatMessages, selectSessionId, selectSessionIds, selectShouldStartNewChat, selectShowingSharedChat, selectStatus, selectStreaming, selectStreamingArtifactContentBuffer, selectStreamingArtifactFullContent, selectToken, selectTokenEnabled, selectTools, sendMessageToParentWebsite, setAccessCheckResponse, setAdvancedDisplayMonetizationCheckoutModal, setCookieForAuth, setDisplayMonetizationCheckoutModal, showMonetizationCheckoutModal, streamOllamaChat, syncAuthToCookies, tenantKeySchema, tenantSchema, translatePrompt, updateFileMetadata, updateFileProgress, updateFileRetryCount, updateFileStatus, updateFileUrl, updateFileUrlFromWebSocket, uploadToS3, useAdvancedChat, useAuthContext, useAuthProvider, useChat, useDayJs, useExternalPricingPlan, useMentorSettings, useMentorTools, useProfileImageUpload, useStripeUpgrade, useSubscriptionHandler, useSubscriptionHandlerV2, useTenantContext, useTenantMetadata, useTimeTracker, useTimeTrackerNative, useUserProfileUpdate, userDataSchema, validateFile };
23986
24622
  //# sourceMappingURL=index.esm.js.map