@iblai/web-utils 1.11.4 → 1.11.6
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/data-layer/src/features/analytics/api-slice.d.ts +134 -1
- package/dist/data-layer/src/features/analytics/constants.d.ts +4 -0
- package/dist/data-layer/src/features/analytics/types.d.ts +117 -0
- package/dist/data-layer/src/features/user/api-slice.d.ts +14 -14
- package/dist/data-layer/src/features/user/types.d.ts +6 -0
- package/dist/index.esm.js +115 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +115 -11
- package/dist/index.js.map +1 -1
- package/dist/package.json +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnalyticsDateParams, AnalyticsPaginationParams, OverviewSummaryResponse, ConversationSummaryResponse, TopicStatisticsResponse, TopicOverviewResponse, UserMetricsResponse, UserMetricsPieChartResponse, UserCohortsOverTimeResponse, TopStudentsResponse, TopicsSummaryResponse, AverageMessagesPerSessionResponse, TopicsStatsArgs, TopicsStatsResponse, UsersStatsResponse, UsersStatsArgs, SessionStatsArgs, SessionStatsResponse, TopicsDetailsStatsResponse, TopicsDetailsStatsArgs, AccessTimeHeatmapResponse, AccessTimeHeatmapArgs, UserDetailsStatsResponse, UserDetailsStatsArgs, FinancialStatsResponse, FinancialStatsArgs, DetailedFinancialStatsResponse, DetailedFinancialStatsArgs, TranscriptsMessagesArgs, TranscriptsMessagesResponse, TranscriptsMessagesDetailsArgs, TranscriptsMessagesDetailsResponse, TranscriptsConversationHeadlineArgs, TranscriptsConversationHeadlineResponse, TimeTrackingResponse, TimeTrackingRequest, ContentAnalyticsResponse, ContentAnalyticsArgs, ContentAnalyticsDetailsResponse, ContentAnalyticsDetailsArgs } from './types';
|
|
1
|
+
import type { AnalyticsDateParams, AnalyticsPaginationParams, OverviewSummaryResponse, ConversationSummaryResponse, TopicStatisticsResponse, TopicOverviewResponse, UserMetricsResponse, UserMetricsPieChartResponse, UserCohortsOverTimeResponse, TopStudentsResponse, TopicsSummaryResponse, AverageMessagesPerSessionResponse, TopicsStatsArgs, TopicsStatsResponse, UsersStatsResponse, UsersStatsArgs, SessionStatsArgs, SessionStatsResponse, TopicsDetailsStatsResponse, TopicsDetailsStatsArgs, AccessTimeHeatmapResponse, AccessTimeHeatmapArgs, UserDetailsStatsResponse, UserDetailsStatsArgs, FinancialStatsResponse, FinancialStatsArgs, DetailedFinancialStatsResponse, DetailedFinancialStatsArgs, TranscriptsMessagesArgs, TranscriptsMessagesResponse, TranscriptsMessagesDetailsArgs, TranscriptsMessagesDetailsResponse, TranscriptsConversationHeadlineArgs, TranscriptsConversationHeadlineResponse, TimeTrackingResponse, TimeTrackingRequest, ContentAnalyticsResponse, ContentAnalyticsArgs, ContentAnalyticsDetailsResponse, ContentAnalyticsDetailsArgs, LearnerDetailsResponse, LearnerDetailsArgs } from './types';
|
|
2
2
|
export declare const analyticsApiSlice: import("@reduxjs/toolkit/query").Api<import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, {
|
|
3
3
|
getOverviewSummary: import("@reduxjs/toolkit/query").QueryDefinition<AnalyticsDateParams, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", OverviewSummaryResponse, "analyticsApiSlice", unknown>;
|
|
4
4
|
getConversation: import("@reduxjs/toolkit/query").QueryDefinition<AnalyticsDateParams, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", ConversationSummaryResponse[], "analyticsApiSlice", unknown>;
|
|
@@ -27,6 +27,7 @@ export declare const analyticsApiSlice: import("@reduxjs/toolkit/query").Api<imp
|
|
|
27
27
|
getTranscriptsConversationHeadline: import("@reduxjs/toolkit/query").QueryDefinition<TranscriptsConversationHeadlineArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", TranscriptsConversationHeadlineResponse, "analyticsApiSlice", unknown>;
|
|
28
28
|
getContentAnalytics: import("@reduxjs/toolkit/query").QueryDefinition<ContentAnalyticsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", ContentAnalyticsResponse, "analyticsApiSlice", unknown>;
|
|
29
29
|
getContentAnalyticsDetails: import("@reduxjs/toolkit/query").QueryDefinition<ContentAnalyticsDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", ContentAnalyticsDetailsResponse, "analyticsApiSlice", unknown>;
|
|
30
|
+
getLearnerDetails: import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>;
|
|
30
31
|
}, "analyticsApiSlice", "Analytics", typeof import("@reduxjs/toolkit/query").coreModuleName | typeof import("@reduxjs/toolkit/dist/query/react").reactHooksModuleName>;
|
|
31
32
|
export declare const useGetOverviewSummaryQuery: <R extends Record<string, any> = import("@reduxjs/toolkit/query").TSHelpersId<(Omit<{
|
|
32
33
|
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
@@ -3620,4 +3621,136 @@ export declare const useGetOverviewSummaryQuery: <R extends Record<string, any>
|
|
|
3620
3621
|
}) => R) | undefined;
|
|
3621
3622
|
}) | undefined) => [R][R extends any ? 0 : never] & {
|
|
3622
3623
|
refetch: () => import("@reduxjs/toolkit/query").QueryActionCreatorResult<import("@reduxjs/toolkit/query").QueryDefinition<ContentAnalyticsDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", ContentAnalyticsDetailsResponse, "analyticsApiSlice", unknown>>;
|
|
3624
|
+
}, useGetLearnerDetailsQuery: <R extends Record<string, any> = import("@reduxjs/toolkit/query").TSHelpersId<(Omit<{
|
|
3625
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
3626
|
+
originalArgs?: undefined | undefined;
|
|
3627
|
+
data?: undefined | undefined;
|
|
3628
|
+
error?: undefined | undefined;
|
|
3629
|
+
requestId?: undefined | undefined;
|
|
3630
|
+
endpointName?: string | undefined;
|
|
3631
|
+
startedTimeStamp?: undefined | undefined;
|
|
3632
|
+
fulfilledTimeStamp?: undefined | undefined;
|
|
3633
|
+
} & {
|
|
3634
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3635
|
+
isUninitialized: false;
|
|
3636
|
+
isLoading: false;
|
|
3637
|
+
isFetching: false;
|
|
3638
|
+
isSuccess: false;
|
|
3639
|
+
isError: false;
|
|
3640
|
+
}, "isUninitialized"> & {
|
|
3641
|
+
isUninitialized: true;
|
|
3642
|
+
}) | import("@reduxjs/toolkit/query").TSHelpersOverride<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3643
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3644
|
+
isUninitialized: false;
|
|
3645
|
+
isLoading: false;
|
|
3646
|
+
isFetching: false;
|
|
3647
|
+
isSuccess: false;
|
|
3648
|
+
isError: false;
|
|
3649
|
+
}, {
|
|
3650
|
+
isLoading: true;
|
|
3651
|
+
isFetching: boolean;
|
|
3652
|
+
data: undefined;
|
|
3653
|
+
} | ({
|
|
3654
|
+
isSuccess: true;
|
|
3655
|
+
isFetching: true;
|
|
3656
|
+
error: undefined;
|
|
3657
|
+
} & Required<Pick<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3658
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3659
|
+
isUninitialized: false;
|
|
3660
|
+
isLoading: false;
|
|
3661
|
+
isFetching: false;
|
|
3662
|
+
isSuccess: false;
|
|
3663
|
+
isError: false;
|
|
3664
|
+
}, "data" | "fulfilledTimeStamp">>) | ({
|
|
3665
|
+
isSuccess: true;
|
|
3666
|
+
isFetching: false;
|
|
3667
|
+
error: undefined;
|
|
3668
|
+
} & Required<Pick<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3669
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3670
|
+
isUninitialized: false;
|
|
3671
|
+
isLoading: false;
|
|
3672
|
+
isFetching: false;
|
|
3673
|
+
isSuccess: false;
|
|
3674
|
+
isError: false;
|
|
3675
|
+
}, "data" | "fulfilledTimeStamp" | "currentData">>) | ({
|
|
3676
|
+
isError: true;
|
|
3677
|
+
} & Required<Pick<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3678
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3679
|
+
isUninitialized: false;
|
|
3680
|
+
isLoading: false;
|
|
3681
|
+
isFetching: false;
|
|
3682
|
+
isSuccess: false;
|
|
3683
|
+
isError: false;
|
|
3684
|
+
}, "error">>)>> & {
|
|
3685
|
+
status: import("@reduxjs/toolkit/query").QueryStatus;
|
|
3686
|
+
}>(arg: LearnerDetailsArgs | typeof import("@reduxjs/toolkit/query").skipToken, options?: (import("@reduxjs/toolkit/query").SubscriptionOptions & {
|
|
3687
|
+
skip?: boolean;
|
|
3688
|
+
refetchOnMountOrArgChange?: boolean | number;
|
|
3689
|
+
} & {
|
|
3690
|
+
skip?: boolean;
|
|
3691
|
+
selectFromResult?: ((state: import("@reduxjs/toolkit/query").TSHelpersId<(Omit<{
|
|
3692
|
+
status: import("@reduxjs/toolkit/query").QueryStatus.uninitialized;
|
|
3693
|
+
originalArgs?: undefined | undefined;
|
|
3694
|
+
data?: undefined | undefined;
|
|
3695
|
+
error?: undefined | undefined;
|
|
3696
|
+
requestId?: undefined | undefined;
|
|
3697
|
+
endpointName?: string | undefined;
|
|
3698
|
+
startedTimeStamp?: undefined | undefined;
|
|
3699
|
+
fulfilledTimeStamp?: undefined | undefined;
|
|
3700
|
+
} & {
|
|
3701
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3702
|
+
isUninitialized: false;
|
|
3703
|
+
isLoading: false;
|
|
3704
|
+
isFetching: false;
|
|
3705
|
+
isSuccess: false;
|
|
3706
|
+
isError: false;
|
|
3707
|
+
}, "isUninitialized"> & {
|
|
3708
|
+
isUninitialized: true;
|
|
3709
|
+
}) | import("@reduxjs/toolkit/query").TSHelpersOverride<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3710
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3711
|
+
isUninitialized: false;
|
|
3712
|
+
isLoading: false;
|
|
3713
|
+
isFetching: false;
|
|
3714
|
+
isSuccess: false;
|
|
3715
|
+
isError: false;
|
|
3716
|
+
}, {
|
|
3717
|
+
isLoading: true;
|
|
3718
|
+
isFetching: boolean;
|
|
3719
|
+
data: undefined;
|
|
3720
|
+
} | ({
|
|
3721
|
+
isSuccess: true;
|
|
3722
|
+
isFetching: true;
|
|
3723
|
+
error: undefined;
|
|
3724
|
+
} & Required<Pick<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3725
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3726
|
+
isUninitialized: false;
|
|
3727
|
+
isLoading: false;
|
|
3728
|
+
isFetching: false;
|
|
3729
|
+
isSuccess: false;
|
|
3730
|
+
isError: false;
|
|
3731
|
+
}, "data" | "fulfilledTimeStamp">>) | ({
|
|
3732
|
+
isSuccess: true;
|
|
3733
|
+
isFetching: false;
|
|
3734
|
+
error: undefined;
|
|
3735
|
+
} & Required<Pick<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3736
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3737
|
+
isUninitialized: false;
|
|
3738
|
+
isLoading: false;
|
|
3739
|
+
isFetching: false;
|
|
3740
|
+
isSuccess: false;
|
|
3741
|
+
isError: false;
|
|
3742
|
+
}, "data" | "fulfilledTimeStamp" | "currentData">>) | ({
|
|
3743
|
+
isError: true;
|
|
3744
|
+
} & Required<Pick<import("@reduxjs/toolkit/query").QuerySubState<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>> & {
|
|
3745
|
+
currentData?: LearnerDetailsResponse | undefined;
|
|
3746
|
+
isUninitialized: false;
|
|
3747
|
+
isLoading: false;
|
|
3748
|
+
isFetching: false;
|
|
3749
|
+
isSuccess: false;
|
|
3750
|
+
isError: false;
|
|
3751
|
+
}, "error">>)>> & {
|
|
3752
|
+
status: import("@reduxjs/toolkit/query").QueryStatus;
|
|
3753
|
+
}) => R) | undefined;
|
|
3754
|
+
}) | undefined) => [R][R extends any ? 0 : never] & {
|
|
3755
|
+
refetch: () => import("@reduxjs/toolkit/query").QueryActionCreatorResult<import("@reduxjs/toolkit/query").QueryDefinition<LearnerDetailsArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, "Analytics", LearnerDetailsResponse, "analyticsApiSlice", unknown>>;
|
|
3623
3756
|
};
|
|
@@ -111,6 +111,10 @@ export declare const NON_AI_ANALYTICS_ENDPOINTS: {
|
|
|
111
111
|
service: SERVICES;
|
|
112
112
|
path: (content_id: string) => string;
|
|
113
113
|
};
|
|
114
|
+
GET_LEARNER_DETAILS: {
|
|
115
|
+
service: SERVICES;
|
|
116
|
+
path: (username: string, platform_key: string, metrics: string, course_id?: string, include_edx_progress?: boolean, program_id?: string) => string;
|
|
117
|
+
};
|
|
114
118
|
};
|
|
115
119
|
export declare const ANALYTICS_QUERY_KEYS: {
|
|
116
120
|
GET_OVERVIEW_SUMMARY: () => string[];
|
|
@@ -577,3 +577,120 @@ export interface ContentAnalyticsDetailsResponse {
|
|
|
577
577
|
pagination: ContentAnalyticsPagination;
|
|
578
578
|
learners: ContentAnalyticsLearner[];
|
|
579
579
|
}
|
|
580
|
+
export interface LearnerDetailsArgs {
|
|
581
|
+
username: string;
|
|
582
|
+
platform_key: string;
|
|
583
|
+
metrics: string;
|
|
584
|
+
course_id?: string;
|
|
585
|
+
program_id?: string;
|
|
586
|
+
include_edx_progress?: boolean;
|
|
587
|
+
}
|
|
588
|
+
export interface LearnerDetailsUser {
|
|
589
|
+
user_id: number;
|
|
590
|
+
username: string;
|
|
591
|
+
email: string;
|
|
592
|
+
name: string;
|
|
593
|
+
is_active: boolean;
|
|
594
|
+
last_active: string;
|
|
595
|
+
date_joined: string;
|
|
596
|
+
}
|
|
597
|
+
export interface LearnerContentEnrollment {
|
|
598
|
+
created: string;
|
|
599
|
+
started: string | null;
|
|
600
|
+
ended: string | null;
|
|
601
|
+
active: boolean;
|
|
602
|
+
}
|
|
603
|
+
export interface LearnerContentCompletion {
|
|
604
|
+
completed: boolean;
|
|
605
|
+
completion_percentage: number;
|
|
606
|
+
passed: boolean;
|
|
607
|
+
passed_date: string | null;
|
|
608
|
+
}
|
|
609
|
+
export interface LearnerEdxCompletionSummary {
|
|
610
|
+
complete_count: number;
|
|
611
|
+
incomplete_count: number;
|
|
612
|
+
locked_count: number;
|
|
613
|
+
}
|
|
614
|
+
export interface LearnerEdxCourseGrade {
|
|
615
|
+
letter_grade: string | null;
|
|
616
|
+
percent: number;
|
|
617
|
+
is_passing: boolean;
|
|
618
|
+
}
|
|
619
|
+
export interface LearnerEdxAssignmentPolicy {
|
|
620
|
+
type: string;
|
|
621
|
+
short_label: string;
|
|
622
|
+
weight: number;
|
|
623
|
+
num_total: number;
|
|
624
|
+
num_droppable: number;
|
|
625
|
+
}
|
|
626
|
+
export interface LearnerEdxGradingPolicy {
|
|
627
|
+
assignment_policies: LearnerEdxAssignmentPolicy[];
|
|
628
|
+
grade_range: Record<string, number>;
|
|
629
|
+
}
|
|
630
|
+
export interface LearnerEdxSubsectionScore {
|
|
631
|
+
display_name: string;
|
|
632
|
+
block_key: string;
|
|
633
|
+
format?: string;
|
|
634
|
+
has_graded_assignment: boolean;
|
|
635
|
+
num_points_earned: number;
|
|
636
|
+
num_points_possible: number;
|
|
637
|
+
percent_graded: number;
|
|
638
|
+
problem_scores: Array<Record<string, unknown>>;
|
|
639
|
+
learner_has_access: boolean;
|
|
640
|
+
url: string;
|
|
641
|
+
}
|
|
642
|
+
export interface LearnerEdxSectionScore {
|
|
643
|
+
display_name: string;
|
|
644
|
+
subsections: LearnerEdxSubsectionScore[];
|
|
645
|
+
}
|
|
646
|
+
export interface LearnerEdxCertificateData {
|
|
647
|
+
cert_status: string | null;
|
|
648
|
+
cert_web_view_url: string | null;
|
|
649
|
+
download_url: string | null;
|
|
650
|
+
certificate_available_date: string | null;
|
|
651
|
+
}
|
|
652
|
+
export interface LearnerEdxProgress {
|
|
653
|
+
completion_summary?: LearnerEdxCompletionSummary;
|
|
654
|
+
course_grade?: LearnerEdxCourseGrade;
|
|
655
|
+
enrollment_mode?: string;
|
|
656
|
+
user_has_passing_grade?: boolean;
|
|
657
|
+
certificate_data?: LearnerEdxCertificateData;
|
|
658
|
+
grading_policy?: LearnerEdxGradingPolicy;
|
|
659
|
+
section_scores?: LearnerEdxSectionScore[];
|
|
660
|
+
}
|
|
661
|
+
export interface LearnerCourseDetail {
|
|
662
|
+
course_id: string;
|
|
663
|
+
name: string;
|
|
664
|
+
platform: string;
|
|
665
|
+
enrollment: LearnerContentEnrollment;
|
|
666
|
+
completion: LearnerContentCompletion | null;
|
|
667
|
+
time_spent: string;
|
|
668
|
+
time_spent_secs: number;
|
|
669
|
+
edx_progress?: LearnerEdxProgress | null;
|
|
670
|
+
}
|
|
671
|
+
export interface LearnerProgramDetail {
|
|
672
|
+
program_id: string;
|
|
673
|
+
name: string;
|
|
674
|
+
platform: string;
|
|
675
|
+
enrollment: LearnerContentEnrollment;
|
|
676
|
+
completion: LearnerContentCompletion | null;
|
|
677
|
+
time_spent: string;
|
|
678
|
+
time_spent_secs: number;
|
|
679
|
+
edx_progress?: LearnerEdxProgress | null;
|
|
680
|
+
}
|
|
681
|
+
export interface LearnerTimeSpentSummary {
|
|
682
|
+
courses: unknown[];
|
|
683
|
+
total_time_spent: string;
|
|
684
|
+
total_time_spent_secs: number;
|
|
685
|
+
}
|
|
686
|
+
export interface LearnerDetailsData {
|
|
687
|
+
courses?: LearnerCourseDetail[];
|
|
688
|
+
programs?: LearnerProgramDetail[];
|
|
689
|
+
pathways?: Array<Record<string, unknown>>;
|
|
690
|
+
skills?: Array<Record<string, unknown>>;
|
|
691
|
+
time_spent?: LearnerTimeSpentSummary;
|
|
692
|
+
}
|
|
693
|
+
export interface LearnerDetailsResponse {
|
|
694
|
+
user: LearnerDetailsUser;
|
|
695
|
+
data: LearnerDetailsData;
|
|
696
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { UserProfile, GetUserMetadataArgs, UpdateUserRoleRequest, UpdateUserAccountRequest, UploadProfileImageResponse, RemoveProfileImageResponse, UserPlatformMetadata, GetUserPlatformMetadataArgs, UpdateUserPlatformMetadataArgs } from './types';
|
|
1
|
+
import type { UserProfile, GetUserMetadataArgs, ResetPasswordArgs, UpdateUserRoleRequest, UpdateUserAccountRequest, UploadProfileImageResponse, RemoveProfileImageResponse, UserPlatformMetadata, GetUserPlatformMetadataArgs, UpdateUserPlatformMetadataArgs } from './types';
|
|
2
2
|
export declare const userApiSlice: import("@reduxjs/toolkit/query").Api<import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, {
|
|
3
3
|
getUserMetadata: import("@reduxjs/toolkit/query").QueryDefinition<GetUserMetadataArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, UserProfile, "userApiSlice", unknown>;
|
|
4
4
|
updateUserMetadata: import("@reduxjs/toolkit/query").MutationDefinition<UserProfile, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, unknown, "userApiSlice", unknown>;
|
|
5
5
|
updateUserAccount: import("@reduxjs/toolkit/query").MutationDefinition<UpdateUserAccountRequest, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, unknown, "userApiSlice", unknown>;
|
|
6
|
-
resetPassword: import("@reduxjs/toolkit/query").MutationDefinition<
|
|
6
|
+
resetPassword: import("@reduxjs/toolkit/query").MutationDefinition<ResetPasswordArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, void, "userApiSlice", unknown>;
|
|
7
7
|
updateUserRole: import("@reduxjs/toolkit/query").MutationDefinition<UpdateUserRoleRequest, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, unknown, "userApiSlice", unknown>;
|
|
8
8
|
getUserMetadataEdx: import("@reduxjs/toolkit/query").QueryDefinition<GetUserMetadataArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, Partial<UserProfile>, "userApiSlice", unknown>;
|
|
9
9
|
uploadProfileImage: import("@reduxjs/toolkit/query").MutationDefinition<{
|
|
@@ -624,14 +624,14 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
624
624
|
status: import("@reduxjs/toolkit/query").QueryStatus.fulfilled;
|
|
625
625
|
} & Omit<{
|
|
626
626
|
requestId: string;
|
|
627
|
-
data?:
|
|
627
|
+
data?: void | undefined;
|
|
628
628
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
629
629
|
endpointName: string;
|
|
630
630
|
startedTimeStamp: number;
|
|
631
631
|
fulfilledTimeStamp?: number;
|
|
632
632
|
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
|
|
633
633
|
requestId: string;
|
|
634
|
-
data?:
|
|
634
|
+
data?: void | undefined;
|
|
635
635
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
636
636
|
endpointName: string;
|
|
637
637
|
startedTimeStamp: number;
|
|
@@ -648,7 +648,7 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
648
648
|
status: import("@reduxjs/toolkit/query").QueryStatus.pending;
|
|
649
649
|
} & {
|
|
650
650
|
requestId: string;
|
|
651
|
-
data?:
|
|
651
|
+
data?: void | undefined;
|
|
652
652
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
653
653
|
endpointName: string;
|
|
654
654
|
startedTimeStamp: number;
|
|
@@ -665,14 +665,14 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
665
665
|
status: import("@reduxjs/toolkit/query").QueryStatus.rejected;
|
|
666
666
|
} & Omit<{
|
|
667
667
|
requestId: string;
|
|
668
|
-
data?:
|
|
668
|
+
data?: void | undefined;
|
|
669
669
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
670
670
|
endpointName: string;
|
|
671
671
|
startedTimeStamp: number;
|
|
672
672
|
fulfilledTimeStamp?: number;
|
|
673
673
|
}, "error"> & Required<Pick<{
|
|
674
674
|
requestId: string;
|
|
675
|
-
data?:
|
|
675
|
+
data?: void | undefined;
|
|
676
676
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
677
677
|
endpointName: string;
|
|
678
678
|
startedTimeStamp: number;
|
|
@@ -702,14 +702,14 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
702
702
|
status: import("@reduxjs/toolkit/query").QueryStatus.fulfilled;
|
|
703
703
|
} & Omit<{
|
|
704
704
|
requestId: string;
|
|
705
|
-
data?:
|
|
705
|
+
data?: void | undefined;
|
|
706
706
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
707
707
|
endpointName: string;
|
|
708
708
|
startedTimeStamp: number;
|
|
709
709
|
fulfilledTimeStamp?: number;
|
|
710
710
|
}, "data" | "fulfilledTimeStamp"> & Required<Pick<{
|
|
711
711
|
requestId: string;
|
|
712
|
-
data?:
|
|
712
|
+
data?: void | undefined;
|
|
713
713
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
714
714
|
endpointName: string;
|
|
715
715
|
startedTimeStamp: number;
|
|
@@ -726,7 +726,7 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
726
726
|
status: import("@reduxjs/toolkit/query").QueryStatus.pending;
|
|
727
727
|
} & {
|
|
728
728
|
requestId: string;
|
|
729
|
-
data?:
|
|
729
|
+
data?: void | undefined;
|
|
730
730
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
731
731
|
endpointName: string;
|
|
732
732
|
startedTimeStamp: number;
|
|
@@ -743,14 +743,14 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
743
743
|
status: import("@reduxjs/toolkit/query").QueryStatus.rejected;
|
|
744
744
|
} & Omit<{
|
|
745
745
|
requestId: string;
|
|
746
|
-
data?:
|
|
746
|
+
data?: void | undefined;
|
|
747
747
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
748
748
|
endpointName: string;
|
|
749
749
|
startedTimeStamp: number;
|
|
750
750
|
fulfilledTimeStamp?: number;
|
|
751
751
|
}, "error"> & Required<Pick<{
|
|
752
752
|
requestId: string;
|
|
753
|
-
data?:
|
|
753
|
+
data?: void | undefined;
|
|
754
754
|
error?: import("../utils").ExtendedFetchBaseQueryError | import("@reduxjs/toolkit").SerializedError | undefined;
|
|
755
755
|
endpointName: string;
|
|
756
756
|
startedTimeStamp: number;
|
|
@@ -763,8 +763,8 @@ export declare const useGetUserMetadataQuery: <R extends Record<string, any> = i
|
|
|
763
763
|
isError: true;
|
|
764
764
|
})) => R) | undefined;
|
|
765
765
|
fixedCacheKey?: string;
|
|
766
|
-
} | undefined) => readonly [(arg:
|
|
767
|
-
originalArgs?:
|
|
766
|
+
} | undefined) => readonly [(arg: ResetPasswordArgs) => import("@reduxjs/toolkit/query").MutationActionCreatorResult<import("@reduxjs/toolkit/query").MutationDefinition<ResetPasswordArgs, import("@reduxjs/toolkit/query").BaseQueryFn<import("../utils").CustomQueryArgs, unknown, import("../utils").ExtendedFetchBaseQueryError, Record<string, unknown>, import("@reduxjs/toolkit/query").FetchBaseQueryMeta>, string, void, "userApiSlice", unknown>>, import("@reduxjs/toolkit/query").TSHelpersNoInfer<R> & {
|
|
767
|
+
originalArgs?: ResetPasswordArgs | undefined;
|
|
768
768
|
reset: () => void;
|
|
769
769
|
}], useUpdateUserRoleMutation: <R extends Record<string, any> = ({
|
|
770
770
|
requestId?: undefined;
|
|
@@ -62,6 +62,12 @@ export interface GetUserMetadataArgs {
|
|
|
62
62
|
username: string;
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
|
+
export interface ResetPasswordArgs {
|
|
66
|
+
email: string;
|
|
67
|
+
platformKey?: string;
|
|
68
|
+
redirectTo?: string;
|
|
69
|
+
app?: string;
|
|
70
|
+
}
|
|
65
71
|
export interface UpdateUserAccountRequest {
|
|
66
72
|
username: string;
|
|
67
73
|
name?: string;
|
package/dist/index.esm.js
CHANGED
|
@@ -9375,6 +9375,14 @@ async function validateJwtToken(storageService) {
|
|
|
9375
9375
|
return false;
|
|
9376
9376
|
}
|
|
9377
9377
|
}
|
|
9378
|
+
/**
|
|
9379
|
+
* How long (ms) a redirect may be "in progress" before we assume the
|
|
9380
|
+
* navigation failed and allow a fresh attempt. Must be longer than the 3s
|
|
9381
|
+
* safety timer in `safeRedirectToAuthSpa` so the two don't fight; this is
|
|
9382
|
+
* the backstop for when that timer is lost because the page began
|
|
9383
|
+
* unloading and then survived (bfcache restore, aborted navigation).
|
|
9384
|
+
*/
|
|
9385
|
+
const REDIRECT_STUCK_MS = 5000;
|
|
9378
9386
|
function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure, redirectToAuthSpa, username, pathname, storageService, skipAuthCheck, token, enableStorageSync = true, }) {
|
|
9379
9387
|
const [isAuthenticating, setIsAuthenticating] = useState(true);
|
|
9380
9388
|
const [userIsAccessingPublicRoute, setUserIsAccessingPublicRoute] = useState(false);
|
|
@@ -9382,21 +9390,51 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
|
|
|
9382
9390
|
const cookieCheckIntervalRef = useRef(null);
|
|
9383
9391
|
const lastLogoutTimestampRef = useRef(null);
|
|
9384
9392
|
const lastLoginTimestampRef = useRef(null);
|
|
9385
|
-
// Guard to prevent poll from firing
|
|
9386
|
-
//
|
|
9393
|
+
// Guard to prevent the poll from firing redundant redirects while a
|
|
9394
|
+
// navigation to the auth SPA is already underway.
|
|
9387
9395
|
const isRedirectingRef = useRef(false);
|
|
9396
|
+
// Wall-clock time (ms) at which the in-progress redirect was started.
|
|
9397
|
+
// Used to self-heal a stuck guard: the browser discards our 3s safety
|
|
9398
|
+
// timer the instant navigation begins, so if navigation never actually
|
|
9399
|
+
// completes (page restored from bfcache, redirect aborted/slow, timers
|
|
9400
|
+
// throttled during unload) the boolean alone would latch ON forever and
|
|
9401
|
+
// suppress every future redirect. This timestamp lets the poll detect
|
|
9402
|
+
// that case and reset the guard. See `redirectInProgress`.
|
|
9403
|
+
const redirectStartedAtRef = useRef(0);
|
|
9388
9404
|
// RTK Query hook for refreshing JWT token
|
|
9389
9405
|
const [refreshJwtToken] = useLazyRefreshJwtTokenQuery();
|
|
9390
9406
|
/**
|
|
9391
|
-
*
|
|
9392
|
-
*
|
|
9407
|
+
* Whether a redirect is genuinely still in progress.
|
|
9408
|
+
*
|
|
9409
|
+
* Returns false (and resets the guard) when the redirect was started more
|
|
9410
|
+
* than REDIRECT_STUCK_MS ago, since at that point the page is clearly
|
|
9411
|
+
* still alive and the navigation must have failed. This is what lets the
|
|
9412
|
+
* app recover on its own instead of latching the guard ON forever and
|
|
9413
|
+
* needing a manual cookie clear / hard reload.
|
|
9414
|
+
*/
|
|
9415
|
+
const redirectInProgress = () => {
|
|
9416
|
+
if (!isRedirectingRef.current)
|
|
9417
|
+
return false;
|
|
9418
|
+
const elapsed = Date.now() - redirectStartedAtRef.current;
|
|
9419
|
+
if (elapsed > REDIRECT_STUCK_MS) {
|
|
9420
|
+
console.log("[AuthProvider] redirect guard stuck for", elapsed, "ms — navigation never completed, resetting so we can retry");
|
|
9421
|
+
isRedirectingRef.current = false;
|
|
9422
|
+
redirectStartedAtRef.current = 0;
|
|
9423
|
+
return false;
|
|
9424
|
+
}
|
|
9425
|
+
return true;
|
|
9426
|
+
};
|
|
9427
|
+
/**
|
|
9428
|
+
* Wrapper around redirectToAuthSpa that prevents redundant redirect calls
|
|
9429
|
+
* from racing while a navigation is already underway.
|
|
9393
9430
|
*/
|
|
9394
9431
|
const safeRedirectToAuthSpa = (...args) => {
|
|
9395
|
-
if (
|
|
9432
|
+
if (redirectInProgress()) {
|
|
9396
9433
|
console.log("[AuthProvider] Redirect already in progress, skipping");
|
|
9397
9434
|
return;
|
|
9398
9435
|
}
|
|
9399
9436
|
isRedirectingRef.current = true;
|
|
9437
|
+
redirectStartedAtRef.current = Date.now();
|
|
9400
9438
|
// NOTE: we intentionally do NOT clear the interval here.
|
|
9401
9439
|
// The isRedirectingRef guard prevents redundant redirects while navigation
|
|
9402
9440
|
// is in progress. Clearing the interval preemptively can permanently stop
|
|
@@ -9411,6 +9449,7 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
|
|
|
9411
9449
|
if (isRedirectingRef.current) {
|
|
9412
9450
|
console.log("[AuthProvider] safeRedirectToAuthSpa: navigation did not occur, resetting redirect guard");
|
|
9413
9451
|
isRedirectingRef.current = false;
|
|
9452
|
+
redirectStartedAtRef.current = 0;
|
|
9414
9453
|
}
|
|
9415
9454
|
}, 3000);
|
|
9416
9455
|
};
|
|
@@ -9437,6 +9476,7 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
|
|
|
9437
9476
|
}
|
|
9438
9477
|
// Reset redirect guard on effect setup (new mount / dep change)
|
|
9439
9478
|
isRedirectingRef.current = false;
|
|
9479
|
+
redirectStartedAtRef.current = 0;
|
|
9440
9480
|
// Initial sync on mount
|
|
9441
9481
|
async function initialSync() {
|
|
9442
9482
|
console.log("[AuthProvider] initialSync starting");
|
|
@@ -9467,8 +9507,11 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
|
|
|
9467
9507
|
initialSync();
|
|
9468
9508
|
// Poll for cookie changes every 2 seconds to detect cross-SPA updates
|
|
9469
9509
|
cookieCheckIntervalRef.current = setInterval(async () => {
|
|
9470
|
-
// If a redirect is
|
|
9471
|
-
|
|
9510
|
+
// If a redirect is genuinely still in progress, skip entirely.
|
|
9511
|
+
// redirectInProgress() self-heals a guard that got stuck because a
|
|
9512
|
+
// navigation was initiated but the page survived (bfcache, aborted
|
|
9513
|
+
// redirect), so this no longer latches ON forever.
|
|
9514
|
+
if (redirectInProgress()) {
|
|
9472
9515
|
console.log("[AuthProvider] interval: redirect already in progress, skipping");
|
|
9473
9516
|
return;
|
|
9474
9517
|
}
|
|
@@ -9541,6 +9584,27 @@ function useAuthProvider({ middleware = new Map(), onAuthSuccess, onAuthFailure,
|
|
|
9541
9584
|
window.addEventListener("storage", handleStorageChange);
|
|
9542
9585
|
return () => window.removeEventListener("storage", handleStorageChange);
|
|
9543
9586
|
}, [storageService, enableStorageSync]);
|
|
9587
|
+
/**
|
|
9588
|
+
* Reset the redirect guard when the page is restored from the back/forward
|
|
9589
|
+
* cache (web only). When a redirect calls window.location.href the browser
|
|
9590
|
+
* may freeze and bfcache the page rather than destroy it; navigating back
|
|
9591
|
+
* then restores it with isRedirectingRef still latched ON and the 3s safety
|
|
9592
|
+
* timer discarded. Clearing the guard here lets redirects fire again
|
|
9593
|
+
* without a manual cookie clear / hard reload.
|
|
9594
|
+
*/
|
|
9595
|
+
useEffect(() => {
|
|
9596
|
+
if (!isWeb$1() || skipAuthCheck)
|
|
9597
|
+
return;
|
|
9598
|
+
const handlePageShow = (event) => {
|
|
9599
|
+
if (event.persisted) {
|
|
9600
|
+
console.log("[AuthProvider] pageshow from bfcache — resetting redirect guard");
|
|
9601
|
+
isRedirectingRef.current = false;
|
|
9602
|
+
redirectStartedAtRef.current = 0;
|
|
9603
|
+
}
|
|
9604
|
+
};
|
|
9605
|
+
window.addEventListener("pageshow", handlePageShow);
|
|
9606
|
+
return () => window.removeEventListener("pageshow", handlePageShow);
|
|
9607
|
+
}, [skipAuthCheck]);
|
|
9544
9608
|
/**
|
|
9545
9609
|
* Performs the authentication check by:
|
|
9546
9610
|
* 1. Validating the auth token
|
|
@@ -12345,7 +12409,35 @@ const selectEnableChatActionsPopup = (state) => state.chat.enableChatActionsPopu
|
|
|
12345
12409
|
* because browsers block mixed content (HTTPS page -> HTTP localhost).
|
|
12346
12410
|
*/
|
|
12347
12411
|
const OLLAMA_BASE_URL = "http://localhost:11434";
|
|
12412
|
+
/**
|
|
12413
|
+
* Ollama-compatible MCP/tool proxy. Chat for tool-capable models is routed here
|
|
12414
|
+
* (instead of plain Ollama) so the model gets MCP tools. The host (ghost-os)
|
|
12415
|
+
* owns the real routing for the Tauri path; this is the fetch-path equivalent.
|
|
12416
|
+
*/
|
|
12417
|
+
const TOOL_BRIDGE_BASE_URL = "http://localhost:8000";
|
|
12348
12418
|
const OLLAMA_MODEL = "phi3:mini";
|
|
12419
|
+
const LOCAL_LLM_MODEL_KEY = "ibl_local_llm_model";
|
|
12420
|
+
const LOCAL_LLM_TOOL_SUPPORT_KEY = "ibl_local_llm_tool_support";
|
|
12421
|
+
/**
|
|
12422
|
+
* The model the user has chosen to chat with (persisted by the Local Models
|
|
12423
|
+
* settings UI), falling back to the default model.
|
|
12424
|
+
*/
|
|
12425
|
+
function getSelectedModel() {
|
|
12426
|
+
if (typeof window === "undefined")
|
|
12427
|
+
return OLLAMA_MODEL;
|
|
12428
|
+
return localStorage.getItem(LOCAL_LLM_MODEL_KEY) || OLLAMA_MODEL;
|
|
12429
|
+
}
|
|
12430
|
+
/**
|
|
12431
|
+
* Whether the selected model supports tools / function calling, persisted by the
|
|
12432
|
+
* Local Models settings UI (`setLocalLLMToolSupport` in @iblai/web-containers).
|
|
12433
|
+
* Read directly from localStorage to avoid a web-utils → web-containers import
|
|
12434
|
+
* cycle — same approach as {@link getSelectedModel}.
|
|
12435
|
+
*/
|
|
12436
|
+
function getSelectedModelToolSupport() {
|
|
12437
|
+
if (typeof window === "undefined")
|
|
12438
|
+
return false;
|
|
12439
|
+
return localStorage.getItem(LOCAL_LLM_TOOL_SUPPORT_KEY) === "true";
|
|
12440
|
+
}
|
|
12349
12441
|
/**
|
|
12350
12442
|
* Check if running in Tauri
|
|
12351
12443
|
*/
|
|
@@ -12429,11 +12521,17 @@ async function streamOllamaChatViaTauri(messages, callbacks, generationId) {
|
|
|
12429
12521
|
}
|
|
12430
12522
|
});
|
|
12431
12523
|
try {
|
|
12432
|
-
|
|
12524
|
+
const model = getSelectedModel();
|
|
12525
|
+
const toolSupport = getSelectedModelToolSupport();
|
|
12526
|
+
console.log("[LocalLLM] Chatting with model:", model, "toolSupport:", toolSupport);
|
|
12527
|
+
// Call the Tauri command to start streaming. `toolSupport` (→ Rust
|
|
12528
|
+
// `tool_support`) lets the host route to the MCP/tool proxy (:8000) vs
|
|
12529
|
+
// plain Ollama (:11434); the host owns the actual routing decision.
|
|
12433
12530
|
await invoke("ollama_chat_stream", {
|
|
12434
12531
|
messages,
|
|
12435
|
-
model
|
|
12532
|
+
model,
|
|
12436
12533
|
generationId,
|
|
12534
|
+
toolSupport,
|
|
12437
12535
|
});
|
|
12438
12536
|
}
|
|
12439
12537
|
finally {
|
|
@@ -12456,13 +12554,19 @@ async function streamOllamaChatViaFetch(messages, callbacks, generationId, abort
|
|
|
12456
12554
|
try {
|
|
12457
12555
|
// Notify start
|
|
12458
12556
|
callbacks.onStart(generationId);
|
|
12459
|
-
const
|
|
12557
|
+
const model = getSelectedModel();
|
|
12558
|
+
const toolSupport = getSelectedModelToolSupport();
|
|
12559
|
+
// Tool-capable models stream from the MCP/tool proxy (:8000); others from
|
|
12560
|
+
// plain Ollama (:11434).
|
|
12561
|
+
const base = toolSupport ? TOOL_BRIDGE_BASE_URL : OLLAMA_BASE_URL;
|
|
12562
|
+
console.log("[LocalLLM] Chatting with model:", model, "toolSupport:", toolSupport, "via", base);
|
|
12563
|
+
const response = await fetch(`${base}/api/chat`, {
|
|
12460
12564
|
method: "POST",
|
|
12461
12565
|
headers: {
|
|
12462
12566
|
"Content-Type": "application/json",
|
|
12463
12567
|
},
|
|
12464
12568
|
body: JSON.stringify({
|
|
12465
|
-
model
|
|
12569
|
+
model,
|
|
12466
12570
|
messages,
|
|
12467
12571
|
stream: true,
|
|
12468
12572
|
}),
|