@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.js CHANGED
@@ -1016,6 +1016,15 @@ function clearCookies() {
1016
1016
  document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;Domain=${getParentDomain(window.location.hostname)}`;
1017
1017
  }
1018
1018
  }
1019
+ /**
1020
+ * Get the value of a cookie by name
1021
+ * @param name - Cookie name
1022
+ * @returns The cookie value or null if not found
1023
+ */
1024
+ function getCookieValue(name) {
1025
+ const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`));
1026
+ return match ? decodeURIComponent(match[1]) : null;
1027
+ }
1019
1028
  /**
1020
1029
  * Check if user is currently logged in
1021
1030
  * @param tokenKey - The localStorage key for the auth token (default: 'axd_token')
@@ -1080,8 +1089,48 @@ async function redirectToAuthSpa(options) {
1080
1089
  userData: "ibl_user_data",
1081
1090
  tenant: "ibl_tenant",
1082
1091
  logoutTimestamp: "ibl_logout_timestamp",
1083
- }, } = options;
1084
- // Clear localStorage
1092
+ loginTimestamp: "ibl_login_timestamp",
1093
+ tenantSwitching: "ibl_tenant_switching",
1094
+ }, hasNonExpiredAuthToken, isOffline, preserveTokenKey, authRedirectProxy, isNativeApp, } = options;
1095
+ console.log("[redirectToAuthSpa] starting redirect to auth spa", redirectTo, platformKey, logout, saveRedirect);
1096
+ // Skip if a tenant switch is already in progress
1097
+ if (cookieNames.tenantSwitching &&
1098
+ document.cookie.includes(cookieNames.tenantSwitching)) {
1099
+ console.log("[redirectToAuthSpa] Tenant switch in progress, skipping redirect");
1100
+ return;
1101
+ }
1102
+ // Skip if a login occurred after the last logout (login takes precedence)
1103
+ // but only if this app actually has a valid auth token
1104
+ if (hasNonExpiredAuthToken &&
1105
+ cookieNames.loginTimestamp &&
1106
+ cookieNames.logoutTimestamp) {
1107
+ const loginTs = getCookieValue(cookieNames.loginTimestamp);
1108
+ const logoutTs = getCookieValue(cookieNames.logoutTimestamp);
1109
+ const hasValidToken = hasNonExpiredAuthToken();
1110
+ console.log("[redirectToAuthSpa] Login/logout timestamp check", {
1111
+ loginTs,
1112
+ logoutTs,
1113
+ hasValidToken,
1114
+ loginAhead: loginTs && logoutTs ? Number(loginTs) > Number(logoutTs) : false,
1115
+ });
1116
+ if (hasValidToken &&
1117
+ loginTs &&
1118
+ logoutTs &&
1119
+ Number(loginTs) > Number(logoutTs)) {
1120
+ console.log("[redirectToAuthSpa] Login timestamp is ahead of logout timestamp, skipping redirect", { loginTs, logoutTs });
1121
+ return;
1122
+ }
1123
+ }
1124
+ // Skip redirect in offline mode
1125
+ if (isOffline === null || isOffline === void 0 ? void 0 : isOffline()) {
1126
+ console.log("[redirectToAuthSpa] Skipping redirect - offline mode");
1127
+ return;
1128
+ }
1129
+ // Preserve a token before clearing localStorage if requested
1130
+ const preservedToken = preserveTokenKey
1131
+ ? window.localStorage.getItem(preserveTokenKey)
1132
+ : null;
1133
+ console.log("[redirectToAuthSpa] clearing local storage");
1085
1134
  localStorage.clear();
1086
1135
  if (logout || isInIframe()) {
1087
1136
  // Delete authentication cookies for cross-SPA synchronization
@@ -1096,7 +1145,7 @@ async function redirectToAuthSpa(options) {
1096
1145
  deleteCookieOnAllDomains(cookieNames.tenant, currentDomain);
1097
1146
  }
1098
1147
  // Set logout timestamp cookie to trigger logout on other SPAs
1099
- if (cookieNames.logoutTimestamp) {
1148
+ if (cookieNames.logoutTimestamp && !isInIframe()) {
1100
1149
  setCookieForAuth(cookieNames.logoutTimestamp, Date.now().toString());
1101
1150
  }
1102
1151
  }
@@ -1125,8 +1174,22 @@ async function redirectToAuthSpa(options) {
1125
1174
  }
1126
1175
  // Small delay for any pending operations
1127
1176
  await new Promise((resolve) => setTimeout(resolve, 100));
1128
- // Redirect to auth SPA
1129
- window.location.href = authRedirectUrl;
1177
+ if (isNativeApp === null || isNativeApp === void 0 ? void 0 : isNativeApp()) {
1178
+ // On native apps (e.g., Tauri), pass preserved token and navigate directly
1179
+ if (preservedToken && preserveTokenKey) {
1180
+ authRedirectUrl += `&token=${encodeURIComponent(preservedToken)}`;
1181
+ console.log("[redirectToAuthSpa] Added preserved token to auth URL");
1182
+ }
1183
+ console.log("[redirectToAuthSpa] Native app, navigating to auth URL:", authRedirectUrl);
1184
+ window.location.href = authRedirectUrl;
1185
+ }
1186
+ else if (authRedirectProxy) {
1187
+ // Use auth redirect proxy endpoint
1188
+ window.location.href = `${authRedirectProxy}?to=${encodeURIComponent(authRedirectUrl)}`;
1189
+ }
1190
+ else {
1191
+ window.location.href = authRedirectUrl;
1192
+ }
1130
1193
  }
1131
1194
  /**
1132
1195
  * Get the URL for joining a tenant (sign up flow)
@@ -2879,6 +2942,10 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
2879
2942
  * Skipped if enableStorageSync is false
2880
2943
  */
2881
2944
  React.useEffect(() => {
2945
+ if (skipAuthCheck) {
2946
+ setInitialSyncComplete(true);
2947
+ return;
2948
+ }
2882
2949
  console.log("[AuthProvider] cookie-sync effect running", {
2883
2950
  pathname,
2884
2951
  enableStorageSync,
@@ -2987,7 +3054,7 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
2987
3054
  * Skipped if enableStorageSync is false
2988
3055
  */
2989
3056
  React.useEffect(() => {
2990
- if (!storageService || !isWeb$1() || !enableStorageSync)
3057
+ if (!storageService || !isWeb$1() || !enableStorageSync || skipAuthCheck)
2991
3058
  return;
2992
3059
  const handleStorageChange = async (event) => {
2993
3060
  // Only handle changes to our auth-related keys
@@ -3087,6 +3154,11 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
3087
3154
  }
3088
3155
  }
3089
3156
  React.useEffect(() => {
3157
+ if (skipAuthCheck) {
3158
+ setIsAuthenticating(false);
3159
+ setUserIsAccessingPublicRoute(true);
3160
+ return;
3161
+ }
3090
3162
  // Wait for initial sync to complete before performing auth check
3091
3163
  if (!initialSyncComplete) {
3092
3164
  console.log("[useAuthProvider] Waiting for initial sync to complete...");
@@ -3164,7 +3236,7 @@ async function determineAuthRequired(middleware, pathname) {
3164
3236
  * 4. Handles redirects to auth SPA when needed
3165
3237
  * 5. Manages public route access state
3166
3238
  */
3167
- function AuthProvider({ children, fallback, middleware = new Map(), onAuthSuccess, onAuthFailure, redirectToAuthSpa, hasNonExpiredAuthToken, username, pathname, skipAuthCheck = false, storageService, token, enableStorageSync = true, skip = false, }) {
3239
+ function AuthProvider({ children, fallback, middleware = new Map(), onAuthSuccess, onAuthFailure, redirectToAuthSpa, hasNonExpiredAuthToken, username, pathname, storageService, token, enableStorageSync = true, skip = false, }) {
3168
3240
  const { isAuthenticating, userIsAccessingPublicRoute, setUserIsAccessingPublicRoute, } = useAuthProvider({
3169
3241
  middleware,
3170
3242
  onAuthSuccess,
@@ -3174,7 +3246,7 @@ function AuthProvider({ children, fallback, middleware = new Map(), onAuthSucces
3174
3246
  username,
3175
3247
  pathname,
3176
3248
  storageService,
3177
- skipAuthCheck,
3249
+ skip,
3178
3250
  token,
3179
3251
  enableStorageSync,
3180
3252
  });
@@ -17646,6 +17718,570 @@ createApi({
17646
17718
  }),
17647
17719
  });
17648
17720
 
17721
+ const CLAW_REDUCER_PATH = 'clawApiSlice';
17722
+ const CLAW_TAG_TYPES = [
17723
+ 'ClawMentorConfig',
17724
+ 'ClawInstances',
17725
+ 'AgentConfig',
17726
+ 'AgentSkills',
17727
+ 'AgentSkillResources',
17728
+ 'MentorSkillAssignments',
17729
+ ];
17730
+ const CLAW_ENDPOINTS = {
17731
+ // ── Claw Mentor Config (singular, nested under mentor) ─────────────────────
17732
+ GET_MENTOR_CONFIG: {
17733
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17734
+ service: SERVICES.DM,
17735
+ },
17736
+ CREATE_MENTOR_CONFIG: {
17737
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17738
+ service: SERVICES.DM,
17739
+ },
17740
+ UPDATE_MENTOR_CONFIG: {
17741
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17742
+ service: SERVICES.DM,
17743
+ },
17744
+ DELETE_MENTOR_CONFIG: {
17745
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/`,
17746
+ service: SERVICES.DM,
17747
+ },
17748
+ PUSH_CONFIG: {
17749
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/claw-config/push-config/`,
17750
+ service: SERVICES.DM,
17751
+ },
17752
+ // ── Claw Instances (unchanged) ─────────────────────────────────────────────
17753
+ GET_INSTANCES: {
17754
+ path: (org) => `/api/ai-mentor/orgs/${org}/claw/instances/`,
17755
+ service: SERVICES.DM,
17756
+ },
17757
+ GET_INSTANCE: {
17758
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/`,
17759
+ service: SERVICES.DM,
17760
+ },
17761
+ CREATE_INSTANCE: {
17762
+ path: (org) => `/api/ai-mentor/orgs/${org}/claw/instances/`,
17763
+ service: SERVICES.DM,
17764
+ },
17765
+ UPDATE_INSTANCE: {
17766
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/`,
17767
+ service: SERVICES.DM,
17768
+ },
17769
+ DELETE_INSTANCE: {
17770
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/`,
17771
+ service: SERVICES.DM,
17772
+ },
17773
+ HEALTH_CHECK_INSTANCE: {
17774
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/health-check/`,
17775
+ service: SERVICES.DM,
17776
+ },
17777
+ TEST_CONNECTIVITY_INSTANCE: {
17778
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/test-connectivity/`,
17779
+ service: SERVICES.DM,
17780
+ },
17781
+ REFRESH_VERSION_INSTANCE: {
17782
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/claw/instances/${id}/refresh-version/`,
17783
+ service: SERVICES.DM,
17784
+ },
17785
+ // ── Agent Config (singular, nested under mentor) ───────────────────────────
17786
+ GET_AGENT_CONFIG: {
17787
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/agent-config/`,
17788
+ service: SERVICES.DM,
17789
+ },
17790
+ /** PATCH is upsert — first write bootstraps the row, no separate POST. */
17791
+ UPDATE_AGENT_CONFIG: {
17792
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/agent-config/`,
17793
+ service: SERVICES.DM,
17794
+ },
17795
+ // ── Agent Skills (platform-level, unchanged) ───────────────────────────────
17796
+ GET_AGENT_SKILLS: {
17797
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skills/`,
17798
+ service: SERVICES.DM,
17799
+ },
17800
+ GET_AGENT_SKILL: {
17801
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skills/${id}/`,
17802
+ service: SERVICES.DM,
17803
+ },
17804
+ CREATE_AGENT_SKILL: {
17805
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skills/`,
17806
+ service: SERVICES.DM,
17807
+ },
17808
+ UPDATE_AGENT_SKILL: {
17809
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skills/${id}/`,
17810
+ service: SERVICES.DM,
17811
+ },
17812
+ DELETE_AGENT_SKILL: {
17813
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skills/${id}/`,
17814
+ service: SERVICES.DM,
17815
+ },
17816
+ // ── Agent Skill Resources (file resources attached to skills) ──────────────
17817
+ GET_AGENT_SKILL_RESOURCES: {
17818
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/`,
17819
+ service: SERVICES.DM,
17820
+ },
17821
+ GET_AGENT_SKILL_RESOURCE: {
17822
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/${id}/`,
17823
+ service: SERVICES.DM,
17824
+ },
17825
+ CREATE_AGENT_SKILL_RESOURCE: {
17826
+ path: (org) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/`,
17827
+ service: SERVICES.DM,
17828
+ },
17829
+ UPDATE_AGENT_SKILL_RESOURCE: {
17830
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/${id}/`,
17831
+ service: SERVICES.DM,
17832
+ },
17833
+ DELETE_AGENT_SKILL_RESOURCE: {
17834
+ path: (org, id) => `/api/ai-mentor/orgs/${org}/agent-skill-resources/${id}/`,
17835
+ service: SERVICES.DM,
17836
+ },
17837
+ // ── Mentor Skill Assignments (nested under mentor) ─────────────────────────
17838
+ GET_MENTOR_SKILL_ASSIGNMENTS: {
17839
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/`,
17840
+ service: SERVICES.DM,
17841
+ },
17842
+ CREATE_MENTOR_SKILL_ASSIGNMENT: {
17843
+ path: (org, mentorUniqueId) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/`,
17844
+ service: SERVICES.DM,
17845
+ },
17846
+ GET_MENTOR_SKILL_ASSIGNMENT: {
17847
+ path: (org, mentorUniqueId, assignmentPk) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/${assignmentPk}/`,
17848
+ service: SERVICES.DM,
17849
+ },
17850
+ UPDATE_MENTOR_SKILL_ASSIGNMENT: {
17851
+ path: (org, mentorUniqueId, assignmentPk) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/${assignmentPk}/`,
17852
+ service: SERVICES.DM,
17853
+ },
17854
+ DELETE_MENTOR_SKILL_ASSIGNMENT: {
17855
+ path: (org, mentorUniqueId, assignmentPk) => `/api/ai-mentor/orgs/${org}/mentors/${mentorUniqueId}/skills/${assignmentPk}/`,
17856
+ service: SERVICES.DM,
17857
+ },
17858
+ };
17859
+
17860
+ /**
17861
+ * Normalize API responses that may return either a plain array or a
17862
+ * paginated envelope `{ results: T[] }`.
17863
+ */
17864
+ function normalizeList(response) {
17865
+ return Array.isArray(response) ? response : response.results;
17866
+ }
17867
+ const clawApiSlice = createApi({
17868
+ reducerPath: CLAW_REDUCER_PATH,
17869
+ baseQuery: iblFetchBaseQuery,
17870
+ tagTypes: [...CLAW_TAG_TYPES],
17871
+ endpoints: (builder) => ({
17872
+ // ── Claw Mentor Config (singular) ─────────────────────────────────────
17873
+ getClawMentorConfig: builder.query({
17874
+ query: (args) => ({
17875
+ url: CLAW_ENDPOINTS.GET_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17876
+ service: CLAW_ENDPOINTS.GET_MENTOR_CONFIG.service,
17877
+ }),
17878
+ providesTags: (_result, _error, args) => [
17879
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17880
+ ],
17881
+ }),
17882
+ createClawMentorConfig: builder.mutation({
17883
+ query: (args) => ({
17884
+ url: CLAW_ENDPOINTS.CREATE_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17885
+ service: CLAW_ENDPOINTS.CREATE_MENTOR_CONFIG.service,
17886
+ method: 'POST',
17887
+ body: {
17888
+ server: args.server,
17889
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
17890
+ ...(args.agent_id !== undefined && { agent_id: args.agent_id }),
17891
+ },
17892
+ }),
17893
+ // Seed the GET cache with the create response and then invalidate so the
17894
+ // subscribed query refetches the joined fields (server_name, status, etc.)
17895
+ // that the POST body doesn't include. The refetch is a 200 — no retry storm.
17896
+ async onQueryStarted({ org, mentorUniqueId }, { dispatch, queryFulfilled }) {
17897
+ try {
17898
+ const { data } = await queryFulfilled;
17899
+ dispatch(clawApiSlice.util.upsertQueryData('getClawMentorConfig', { org, mentorUniqueId }, data));
17900
+ }
17901
+ catch (_a) {
17902
+ // Surface error via the mutation's own error state.
17903
+ }
17904
+ },
17905
+ invalidatesTags: (_result, _error, args) => [
17906
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17907
+ ],
17908
+ }),
17909
+ updateClawMentorConfig: builder.mutation({
17910
+ query: (args) => ({
17911
+ url: CLAW_ENDPOINTS.UPDATE_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17912
+ service: CLAW_ENDPOINTS.UPDATE_MENTOR_CONFIG.service,
17913
+ method: 'PATCH',
17914
+ body: {
17915
+ ...(args.server !== undefined && { server: args.server }),
17916
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
17917
+ ...(args.auto_push !== undefined && { auto_push: args.auto_push }),
17918
+ ...(args.agent_config !== undefined && { agent_config: args.agent_config }),
17919
+ ...(args.agent_id !== undefined && { agent_id: args.agent_id }),
17920
+ },
17921
+ }),
17922
+ invalidatesTags: (_result, _error, args) => [
17923
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17924
+ ],
17925
+ }),
17926
+ deleteClawMentorConfig: builder.mutation({
17927
+ query: (args) => ({
17928
+ url: CLAW_ENDPOINTS.DELETE_MENTOR_CONFIG.path(args.org, args.mentorUniqueId),
17929
+ service: CLAW_ENDPOINTS.DELETE_MENTOR_CONFIG.service,
17930
+ method: 'DELETE',
17931
+ }),
17932
+ // Optimistically clear the GET cache before the request resolves so the
17933
+ // UI flips to "not connected" instantly. On failure, invalidate to refetch
17934
+ // the real state. We don't invalidate on success — the GET would 404 and
17935
+ // the base query retries 3× on error, which is the lag the user sees.
17936
+ async onQueryStarted({ org, mentorUniqueId }, { dispatch, queryFulfilled }) {
17937
+ dispatch(clawApiSlice.util.upsertQueryData('getClawMentorConfig', { org, mentorUniqueId }, null));
17938
+ try {
17939
+ await queryFulfilled;
17940
+ }
17941
+ catch (_a) {
17942
+ dispatch(clawApiSlice.util.invalidateTags([{ type: 'ClawMentorConfig', id: mentorUniqueId }]));
17943
+ }
17944
+ },
17945
+ }),
17946
+ pushClawConfig: builder.mutation({
17947
+ query: (args) => ({
17948
+ url: CLAW_ENDPOINTS.PUSH_CONFIG.path(args.org, args.mentorUniqueId),
17949
+ service: CLAW_ENDPOINTS.PUSH_CONFIG.service,
17950
+ method: 'POST',
17951
+ }),
17952
+ invalidatesTags: (_result, _error, args) => [
17953
+ { type: 'ClawMentorConfig', id: args.mentorUniqueId },
17954
+ ],
17955
+ }),
17956
+ // ── Claw Instances ────────────────────────────────────────────────────
17957
+ getClawInstances: builder.query({
17958
+ query: (args) => ({
17959
+ url: CLAW_ENDPOINTS.GET_INSTANCES.path(args.org),
17960
+ service: CLAW_ENDPOINTS.GET_INSTANCES.service,
17961
+ }),
17962
+ transformResponse: (response) => normalizeList(response),
17963
+ providesTags: ['ClawInstances'],
17964
+ }),
17965
+ getClawInstance: builder.query({
17966
+ query: (args) => ({
17967
+ url: CLAW_ENDPOINTS.GET_INSTANCE.path(args.org, args.id),
17968
+ service: CLAW_ENDPOINTS.GET_INSTANCE.service,
17969
+ }),
17970
+ providesTags: (_result, _error, args) => [{ type: 'ClawInstances', id: args.id }],
17971
+ }),
17972
+ createClawInstance: builder.mutation({
17973
+ query: (args) => ({
17974
+ url: CLAW_ENDPOINTS.CREATE_INSTANCE.path(args.org),
17975
+ service: CLAW_ENDPOINTS.CREATE_INSTANCE.service,
17976
+ method: 'POST',
17977
+ body: {
17978
+ name: args.name,
17979
+ claw_type: args.claw_type,
17980
+ server_url: args.server_url,
17981
+ ...(args.gateway_token && { gateway_token: args.gateway_token }),
17982
+ ...(args.auth_headers && { auth_headers: args.auth_headers }),
17983
+ ...(args.connection_params && { connection_params: args.connection_params }),
17984
+ ...(args.deployment_backend !== undefined && {
17985
+ deployment_backend: args.deployment_backend,
17986
+ }),
17987
+ },
17988
+ }),
17989
+ invalidatesTags: ['ClawInstances'],
17990
+ }),
17991
+ updateClawInstance: builder.mutation({
17992
+ query: (args) => ({
17993
+ url: CLAW_ENDPOINTS.UPDATE_INSTANCE.path(args.org, args.id),
17994
+ service: CLAW_ENDPOINTS.UPDATE_INSTANCE.service,
17995
+ method: 'PATCH',
17996
+ body: {
17997
+ ...(args.name !== undefined && { name: args.name }),
17998
+ ...(args.claw_type !== undefined && { claw_type: args.claw_type }),
17999
+ ...(args.server_url !== undefined && { server_url: args.server_url }),
18000
+ ...(args.gateway_token && { gateway_token: args.gateway_token }),
18001
+ ...(args.auth_headers && { auth_headers: args.auth_headers }),
18002
+ ...(args.connection_params && { connection_params: args.connection_params }),
18003
+ ...(args.deployment_backend !== undefined && {
18004
+ deployment_backend: args.deployment_backend,
18005
+ }),
18006
+ },
18007
+ }),
18008
+ invalidatesTags: (_result, _error, args) => [
18009
+ { type: 'ClawInstances', id: args.id },
18010
+ 'ClawInstances',
18011
+ ],
18012
+ }),
18013
+ deleteClawInstance: builder.mutation({
18014
+ query: (args) => ({
18015
+ url: CLAW_ENDPOINTS.DELETE_INSTANCE.path(args.org, args.id),
18016
+ service: CLAW_ENDPOINTS.DELETE_INSTANCE.service,
18017
+ method: 'DELETE',
18018
+ }),
18019
+ invalidatesTags: ['ClawInstances'],
18020
+ }),
18021
+ healthCheckClawInstance: builder.mutation({
18022
+ query: (args) => ({
18023
+ url: CLAW_ENDPOINTS.HEALTH_CHECK_INSTANCE.path(args.org, args.id),
18024
+ service: CLAW_ENDPOINTS.HEALTH_CHECK_INSTANCE.service,
18025
+ method: 'POST',
18026
+ }),
18027
+ // Health check updates last_health_check / last_health_status / claw_version
18028
+ // on the instance — invalidate so the list refetches with fresh values.
18029
+ invalidatesTags: (_result, _error, args) => [
18030
+ { type: 'ClawInstances', id: args.id },
18031
+ 'ClawInstances',
18032
+ ],
18033
+ }),
18034
+ testConnectivityClawInstance: builder.mutation({
18035
+ query: (args) => ({
18036
+ url: CLAW_ENDPOINTS.TEST_CONNECTIVITY_INSTANCE.path(args.org, args.id),
18037
+ service: CLAW_ENDPOINTS.TEST_CONNECTIVITY_INSTANCE.service,
18038
+ method: 'POST',
18039
+ }),
18040
+ invalidatesTags: (_result, _error, args) => [
18041
+ { type: 'ClawInstances', id: args.id },
18042
+ 'ClawInstances',
18043
+ ],
18044
+ }),
18045
+ refreshVersionClawInstance: builder.mutation({
18046
+ query: (args) => ({
18047
+ url: CLAW_ENDPOINTS.REFRESH_VERSION_INSTANCE.path(args.org, args.id),
18048
+ service: CLAW_ENDPOINTS.REFRESH_VERSION_INSTANCE.service,
18049
+ method: 'POST',
18050
+ }),
18051
+ // Refresh-version updates the instance's `claw_version` (and may touch
18052
+ // health fields too) — invalidate so the table picks up the new value.
18053
+ invalidatesTags: (_result, _error, args) => [
18054
+ { type: 'ClawInstances', id: args.id },
18055
+ 'ClawInstances',
18056
+ ],
18057
+ }),
18058
+ // ── Agent Config (singular, PATCH is upsert) ──────────────────────────
18059
+ getAgentConfig: builder.query({
18060
+ query: (args) => ({
18061
+ url: CLAW_ENDPOINTS.GET_AGENT_CONFIG.path(args.org, args.mentorUniqueId),
18062
+ service: CLAW_ENDPOINTS.GET_AGENT_CONFIG.service,
18063
+ }),
18064
+ providesTags: (_result, _error, args) => [{ type: 'AgentConfig', id: args.mentorUniqueId }],
18065
+ }),
18066
+ updateAgentConfig: builder.mutation({
18067
+ query: (args) => ({
18068
+ url: CLAW_ENDPOINTS.UPDATE_AGENT_CONFIG.path(args.org, args.mentorUniqueId),
18069
+ service: CLAW_ENDPOINTS.UPDATE_AGENT_CONFIG.service,
18070
+ method: 'PATCH',
18071
+ body: {
18072
+ ...(args.identity !== undefined && { identity: args.identity }),
18073
+ ...(args.soul !== undefined && { soul: args.soul }),
18074
+ ...(args.user_context !== undefined && { user_context: args.user_context }),
18075
+ ...(args.tools !== undefined && { tools: args.tools }),
18076
+ ...(args.agents !== undefined && { agents: args.agents }),
18077
+ ...(args.bootstrap !== undefined && { bootstrap: args.bootstrap }),
18078
+ ...(args.heartbeat !== undefined && { heartbeat: args.heartbeat }),
18079
+ ...(args.memory !== undefined && { memory: args.memory }),
18080
+ ...(args.model !== undefined && { model: args.model }),
18081
+ ...(args.config !== undefined && { config: args.config }),
18082
+ },
18083
+ }),
18084
+ // PATCH is upsert and returns the full AgentConfig. Write it straight into
18085
+ // the GET cache so UI subscribers see the new value immediately — relying
18086
+ // on tag invalidation alone leaves a stale window when the prior GET was a
18087
+ // 404 (the entry sits in error state until the refetch completes).
18088
+ async onQueryStarted({ org, mentorUniqueId }, { dispatch, queryFulfilled }) {
18089
+ try {
18090
+ const { data } = await queryFulfilled;
18091
+ dispatch(clawApiSlice.util.upsertQueryData('getAgentConfig', { org, mentorUniqueId }, data));
18092
+ }
18093
+ catch (_a) {
18094
+ // Mutation error surfaces via the hook's own state.
18095
+ }
18096
+ },
18097
+ invalidatesTags: (_result, _error, args) => [
18098
+ { type: 'AgentConfig', id: args.mentorUniqueId },
18099
+ ],
18100
+ }),
18101
+ // ── Agent Skills (platform-level) ─────────────────────────────────────
18102
+ getAgentSkills: builder.query({
18103
+ query: (args) => ({
18104
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILLS.path(args.org),
18105
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILLS.service,
18106
+ }),
18107
+ transformResponse: (response) => normalizeList(response),
18108
+ providesTags: ['AgentSkills'],
18109
+ }),
18110
+ getAgentSkill: builder.query({
18111
+ query: (args) => ({
18112
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILL.path(args.org, args.id),
18113
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILL.service,
18114
+ }),
18115
+ providesTags: (_result, _error, args) => [{ type: 'AgentSkills', id: args.id }],
18116
+ }),
18117
+ createAgentSkill: builder.mutation({
18118
+ query: (args) => ({
18119
+ url: CLAW_ENDPOINTS.CREATE_AGENT_SKILL.path(args.org),
18120
+ service: CLAW_ENDPOINTS.CREATE_AGENT_SKILL.service,
18121
+ method: 'POST',
18122
+ body: {
18123
+ name: args.name,
18124
+ slug: args.slug,
18125
+ ...(args.description !== undefined && { description: args.description }),
18126
+ ...(args.version !== undefined && { version: args.version }),
18127
+ ...(args.instruction !== undefined && { instruction: args.instruction }),
18128
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18129
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18130
+ },
18131
+ }),
18132
+ invalidatesTags: ['AgentSkills'],
18133
+ }),
18134
+ updateAgentSkill: builder.mutation({
18135
+ query: (args) => ({
18136
+ url: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL.path(args.org, args.id),
18137
+ service: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL.service,
18138
+ method: 'PATCH',
18139
+ body: {
18140
+ ...(args.name !== undefined && { name: args.name }),
18141
+ ...(args.slug !== undefined && { slug: args.slug }),
18142
+ ...(args.description !== undefined && { description: args.description }),
18143
+ ...(args.version !== undefined && { version: args.version }),
18144
+ ...(args.instruction !== undefined && { instruction: args.instruction }),
18145
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18146
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18147
+ },
18148
+ }),
18149
+ invalidatesTags: (_result, _error, args) => [
18150
+ { type: 'AgentSkills', id: args.id },
18151
+ 'AgentSkills',
18152
+ ],
18153
+ }),
18154
+ deleteAgentSkill: builder.mutation({
18155
+ query: (args) => ({
18156
+ url: CLAW_ENDPOINTS.DELETE_AGENT_SKILL.path(args.org, args.id),
18157
+ service: CLAW_ENDPOINTS.DELETE_AGENT_SKILL.service,
18158
+ method: 'DELETE',
18159
+ }),
18160
+ invalidatesTags: ['AgentSkills'],
18161
+ }),
18162
+ // ── Agent Skill Resources ─────────────────────────────────────────────
18163
+ getAgentSkillResources: builder.query({
18164
+ query: (args) => ({
18165
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCES.path(args.org),
18166
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCES.service,
18167
+ params: {
18168
+ ...(args.skill !== undefined && { skill: args.skill }),
18169
+ ...(args.file_type !== undefined && { file_type: args.file_type }),
18170
+ },
18171
+ }),
18172
+ transformResponse: (response) => normalizeList(response),
18173
+ providesTags: ['AgentSkillResources'],
18174
+ }),
18175
+ getAgentSkillResource: builder.query({
18176
+ query: (args) => ({
18177
+ url: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCE.path(args.org, args.id),
18178
+ service: CLAW_ENDPOINTS.GET_AGENT_SKILL_RESOURCE.service,
18179
+ }),
18180
+ providesTags: (_result, _error, args) => [{ type: 'AgentSkillResources', id: args.id }],
18181
+ }),
18182
+ createAgentSkillResource: builder.mutation({
18183
+ query: (args) => ({
18184
+ url: CLAW_ENDPOINTS.CREATE_AGENT_SKILL_RESOURCE.path(args.org),
18185
+ service: CLAW_ENDPOINTS.CREATE_AGENT_SKILL_RESOURCE.service,
18186
+ method: 'POST',
18187
+ body: {
18188
+ skill: args.skill,
18189
+ file_type: args.file_type,
18190
+ name: args.name,
18191
+ ...(args.url !== undefined && { url: args.url }),
18192
+ ...(args.content !== undefined && { content: args.content }),
18193
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18194
+ },
18195
+ }),
18196
+ invalidatesTags: ['AgentSkillResources'],
18197
+ }),
18198
+ updateAgentSkillResource: builder.mutation({
18199
+ query: (args) => ({
18200
+ url: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL_RESOURCE.path(args.org, args.id),
18201
+ service: CLAW_ENDPOINTS.UPDATE_AGENT_SKILL_RESOURCE.service,
18202
+ method: 'PATCH',
18203
+ body: {
18204
+ ...(args.skill !== undefined && { skill: args.skill }),
18205
+ ...(args.file_type !== undefined && { file_type: args.file_type }),
18206
+ ...(args.name !== undefined && { name: args.name }),
18207
+ ...(args.url !== undefined && { url: args.url }),
18208
+ ...(args.content !== undefined && { content: args.content }),
18209
+ ...(args.metadata !== undefined && { metadata: args.metadata }),
18210
+ },
18211
+ }),
18212
+ invalidatesTags: (_result, _error, args) => [
18213
+ { type: 'AgentSkillResources', id: args.id },
18214
+ 'AgentSkillResources',
18215
+ ],
18216
+ }),
18217
+ deleteAgentSkillResource: builder.mutation({
18218
+ query: (args) => ({
18219
+ url: CLAW_ENDPOINTS.DELETE_AGENT_SKILL_RESOURCE.path(args.org, args.id),
18220
+ service: CLAW_ENDPOINTS.DELETE_AGENT_SKILL_RESOURCE.service,
18221
+ method: 'DELETE',
18222
+ }),
18223
+ invalidatesTags: ['AgentSkillResources'],
18224
+ }),
18225
+ // ── Mentor Skill Assignments (nested under mentor) ────────────────────
18226
+ getMentorSkillAssignments: builder.query({
18227
+ query: (args) => ({
18228
+ url: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENTS.path(args.org, args.mentorUniqueId),
18229
+ service: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENTS.service,
18230
+ }),
18231
+ transformResponse: (response) => normalizeList(response),
18232
+ providesTags: (_result, _error, args) => [
18233
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18234
+ ],
18235
+ }),
18236
+ getMentorSkillAssignment: builder.query({
18237
+ query: (args) => ({
18238
+ url: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId, args.assignmentPk),
18239
+ service: CLAW_ENDPOINTS.GET_MENTOR_SKILL_ASSIGNMENT.service,
18240
+ }),
18241
+ providesTags: (_result, _error, args) => [
18242
+ { type: 'MentorSkillAssignments', id: args.assignmentPk },
18243
+ ],
18244
+ }),
18245
+ createMentorSkillAssignment: builder.mutation({
18246
+ query: (args) => ({
18247
+ url: CLAW_ENDPOINTS.CREATE_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId),
18248
+ service: CLAW_ENDPOINTS.CREATE_MENTOR_SKILL_ASSIGNMENT.service,
18249
+ method: 'POST',
18250
+ body: {
18251
+ skill: args.skill,
18252
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18253
+ },
18254
+ }),
18255
+ invalidatesTags: (_result, _error, args) => [
18256
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18257
+ ],
18258
+ }),
18259
+ updateMentorSkillAssignment: builder.mutation({
18260
+ query: (args) => ({
18261
+ url: CLAW_ENDPOINTS.UPDATE_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId, args.assignmentPk),
18262
+ service: CLAW_ENDPOINTS.UPDATE_MENTOR_SKILL_ASSIGNMENT.service,
18263
+ method: 'PATCH',
18264
+ body: {
18265
+ ...(args.enabled !== undefined && { enabled: args.enabled }),
18266
+ },
18267
+ }),
18268
+ invalidatesTags: (_result, _error, args) => [
18269
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18270
+ ],
18271
+ }),
18272
+ deleteMentorSkillAssignment: builder.mutation({
18273
+ query: (args) => ({
18274
+ url: CLAW_ENDPOINTS.DELETE_MENTOR_SKILL_ASSIGNMENT.path(args.org, args.mentorUniqueId, args.assignmentPk),
18275
+ service: CLAW_ENDPOINTS.DELETE_MENTOR_SKILL_ASSIGNMENT.service,
18276
+ method: 'DELETE',
18277
+ }),
18278
+ invalidatesTags: (_result, _error, args) => [
18279
+ { type: 'MentorSkillAssignments', id: args.mentorUniqueId },
18280
+ ],
18281
+ }),
18282
+ }),
18283
+ });
18284
+
17649
18285
  const CUSTOM_DOMAIN_REDUCER_PATH = 'customDomainApiSlice';
17650
18286
  const CUSTOM_DOMAIN_ENDPOINTS = {
17651
18287
  GET_CUSTOM_DOMAINS: {
@@ -24055,6 +24691,7 @@ exports.filesReducer = filesReducer;
24055
24691
  exports.filesSlice = filesSlice;
24056
24692
  exports.formatRelativeTime = formatRelativeTime;
24057
24693
  exports.getAuthSpaJoinUrl = getAuthSpaJoinUrl;
24694
+ exports.getCookieValue = getCookieValue;
24058
24695
  exports.getDomainParts = getDomainParts;
24059
24696
  exports.getFileInfo = getFileInfo;
24060
24697
  exports.getInitials = getInitials;