mirror of
https://github.com/twentyhq/twenty.git
synced 2024-10-05 13:27:12 +03:00
Text-to-SQL proof of concept (#5788)
Added: - An "Ask AI" command to the command menu. - A simple GraphQL resolver that converts the user's question into a relevant SQL query using an LLM, runs the query, and returns the result. <img width="428" alt="Screenshot 2024-06-09 at 20 53 09" src="https://github.com/twentyhq/twenty/assets/171685816/57127f37-d4a6-498d-b253-733ffa0d209f"> No security concerns have been addressed, this is only a proof-of-concept and not intended to be enabled in production. All changes are behind a feature flag called `IS_ASK_AI_ENABLED`. --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
parent
25fce27fe3
commit
4c642a0bb8
@ -20,6 +20,13 @@ export type Scalars = {
|
|||||||
Upload: any;
|
Upload: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type AisqlQueryResult = {
|
||||||
|
__typename?: 'AISQLQueryResult';
|
||||||
|
queryFailedErrorMessage?: Maybe<Scalars['String']>;
|
||||||
|
sqlQuery: Scalars['String'];
|
||||||
|
sqlQueryResult?: Maybe<Scalars['String']>;
|
||||||
|
};
|
||||||
|
|
||||||
export type ActivateWorkspaceInput = {
|
export type ActivateWorkspaceInput = {
|
||||||
displayName?: InputMaybe<Scalars['String']>;
|
displayName?: InputMaybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
@ -526,6 +533,7 @@ export type Query = {
|
|||||||
currentUser: User;
|
currentUser: User;
|
||||||
currentWorkspace: Workspace;
|
currentWorkspace: Workspace;
|
||||||
findWorkspaceFromInviteHash: Workspace;
|
findWorkspaceFromInviteHash: Workspace;
|
||||||
|
getAISQLQuery: AisqlQueryResult;
|
||||||
getPostgresCredentials?: Maybe<PostgresCredentials>;
|
getPostgresCredentials?: Maybe<PostgresCredentials>;
|
||||||
getProductPrices: ProductPricesEntity;
|
getProductPrices: ProductPricesEntity;
|
||||||
getTimelineCalendarEventsFromCompanyId: TimelineCalendarEventsWithTotal;
|
getTimelineCalendarEventsFromCompanyId: TimelineCalendarEventsWithTotal;
|
||||||
@ -559,6 +567,11 @@ export type QueryFindWorkspaceFromInviteHashArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type QueryGetAisqlQueryArgs = {
|
||||||
|
text: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type QueryGetProductPricesArgs = {
|
export type QueryGetProductPricesArgs = {
|
||||||
product: Scalars['String'];
|
product: Scalars['String'];
|
||||||
};
|
};
|
||||||
@ -1264,6 +1277,13 @@ export type SkipSyncEmailOnboardingStepMutationVariables = Exact<{ [key: string]
|
|||||||
|
|
||||||
export type SkipSyncEmailOnboardingStepMutation = { __typename?: 'Mutation', skipSyncEmailOnboardingStep: { __typename?: 'OnboardingStepSuccess', success: boolean } };
|
export type SkipSyncEmailOnboardingStepMutation = { __typename?: 'Mutation', skipSyncEmailOnboardingStep: { __typename?: 'OnboardingStepSuccess', success: boolean } };
|
||||||
|
|
||||||
|
export type GetAisqlQueryQueryVariables = Exact<{
|
||||||
|
text: Scalars['String'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type GetAisqlQueryQuery = { __typename?: 'Query', getAISQLQuery: { __typename?: 'AISQLQueryResult', sqlQuery: string, sqlQueryResult?: string | null, queryFailedErrorMessage?: string | null } };
|
||||||
|
|
||||||
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
|
export type UserQueryFragmentFragment = { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale: string, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: string, currentCacheVersion?: string | null, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> };
|
||||||
|
|
||||||
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
|
export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>;
|
||||||
@ -2449,6 +2469,43 @@ export function useSkipSyncEmailOnboardingStepMutation(baseOptions?: Apollo.Muta
|
|||||||
export type SkipSyncEmailOnboardingStepMutationHookResult = ReturnType<typeof useSkipSyncEmailOnboardingStepMutation>;
|
export type SkipSyncEmailOnboardingStepMutationHookResult = ReturnType<typeof useSkipSyncEmailOnboardingStepMutation>;
|
||||||
export type SkipSyncEmailOnboardingStepMutationResult = Apollo.MutationResult<SkipSyncEmailOnboardingStepMutation>;
|
export type SkipSyncEmailOnboardingStepMutationResult = Apollo.MutationResult<SkipSyncEmailOnboardingStepMutation>;
|
||||||
export type SkipSyncEmailOnboardingStepMutationOptions = Apollo.BaseMutationOptions<SkipSyncEmailOnboardingStepMutation, SkipSyncEmailOnboardingStepMutationVariables>;
|
export type SkipSyncEmailOnboardingStepMutationOptions = Apollo.BaseMutationOptions<SkipSyncEmailOnboardingStepMutation, SkipSyncEmailOnboardingStepMutationVariables>;
|
||||||
|
export const GetAisqlQueryDocument = gql`
|
||||||
|
query GetAISQLQuery($text: String!) {
|
||||||
|
getAISQLQuery(text: $text) {
|
||||||
|
sqlQuery
|
||||||
|
sqlQueryResult
|
||||||
|
queryFailedErrorMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetAisqlQueryQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetAisqlQueryQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetAisqlQueryQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useGetAisqlQueryQuery({
|
||||||
|
* variables: {
|
||||||
|
* text: // value for 'text'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetAisqlQueryQuery(baseOptions: Apollo.QueryHookOptions<GetAisqlQueryQuery, GetAisqlQueryQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<GetAisqlQueryQuery, GetAisqlQueryQueryVariables>(GetAisqlQueryDocument, options);
|
||||||
|
}
|
||||||
|
export function useGetAisqlQueryLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetAisqlQueryQuery, GetAisqlQueryQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<GetAisqlQueryQuery, GetAisqlQueryQueryVariables>(GetAisqlQueryDocument, options);
|
||||||
|
}
|
||||||
|
export type GetAisqlQueryQueryHookResult = ReturnType<typeof useGetAisqlQueryQuery>;
|
||||||
|
export type GetAisqlQueryLazyQueryHookResult = ReturnType<typeof useGetAisqlQueryLazyQuery>;
|
||||||
|
export type GetAisqlQueryQueryResult = Apollo.QueryResult<GetAisqlQueryQuery, GetAisqlQueryQueryVariables>;
|
||||||
export const DeleteUserAccountDocument = gql`
|
export const DeleteUserAccountDocument = gql`
|
||||||
mutation DeleteUserAccount {
|
mutation DeleteUserAccount {
|
||||||
deleteUser {
|
deleteUser {
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { copilotQueryState } from '@/activities/copilot/right-drawer/states/copilotQueryState';
|
||||||
|
import {
|
||||||
|
AutosizeTextInput,
|
||||||
|
AutosizeTextInputVariant,
|
||||||
|
} from '@/ui/input/components/AutosizeTextInput';
|
||||||
|
|
||||||
|
const StyledContainer = styled.div`
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: relative;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledChatArea = styled.div`
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow-y: scroll;
|
||||||
|
padding: ${({ theme }) => theme.spacing(6)};
|
||||||
|
padding-bottom: 0px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledNewMessageArea = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: ${({ theme }) => theme.spacing(6)};
|
||||||
|
padding-top: 0px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const RightDrawerAIChat = () => {
|
||||||
|
const setCopilotQuery = useSetRecoilState(copilotQueryState);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledContainer>
|
||||||
|
<StyledChatArea>{/* TODO */}</StyledChatArea>
|
||||||
|
<StyledNewMessageArea>
|
||||||
|
<AutosizeTextInput
|
||||||
|
autoFocus
|
||||||
|
placeholder="Ask anything"
|
||||||
|
variant={AutosizeTextInputVariant.Icon}
|
||||||
|
onValidate={(text) => {
|
||||||
|
setCopilotQuery(text);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</StyledNewMessageArea>
|
||||||
|
</StyledContainer>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,14 @@
|
|||||||
|
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
|
||||||
|
import { RightDrawerHotkeyScope } from '@/ui/layout/right-drawer/types/RightDrawerHotkeyScope';
|
||||||
|
import { RightDrawerPages } from '@/ui/layout/right-drawer/types/RightDrawerPages';
|
||||||
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
|
|
||||||
|
export const useOpenCopilotRightDrawer = () => {
|
||||||
|
const { openRightDrawer } = useRightDrawer();
|
||||||
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
||||||
|
openRightDrawer(RightDrawerPages.Copilot);
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,6 @@
|
|||||||
|
import { createState } from 'twenty-ui';
|
||||||
|
|
||||||
|
export const copilotQueryState = createState({
|
||||||
|
key: 'activities/copilot-query',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
@ -1,10 +1,12 @@
|
|||||||
import { useMemo, useRef } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { isNonEmptyString } from '@sniptt/guards';
|
import { isNonEmptyString } from '@sniptt/guards';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
import { Avatar, IconNotes } from 'twenty-ui';
|
import { Avatar, IconNotes, IconSparkles } from 'twenty-ui';
|
||||||
|
|
||||||
|
import { useOpenCopilotRightDrawer } from '@/activities/copilot/right-drawer/hooks/useOpenCopilotRightDrawer';
|
||||||
|
import { copilotQueryState } from '@/activities/copilot/right-drawer/states/copilotQueryState';
|
||||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
import { commandMenuSearchState } from '@/command-menu/states/commandMenuSearchState';
|
||||||
@ -21,6 +23,7 @@ import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
|||||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
|
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
import { getLogoUrlFromDomainName } from '~/utils';
|
||||||
import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields';
|
import { generateILikeFiltersForCompositeFields } from '~/utils/array/generateILikeFiltersForCompositeFields';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
@ -248,8 +251,27 @@ export const CommandMenu = () => {
|
|||||||
callback: closeCommandMenu,
|
callback: closeCommandMenu,
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectableItemIds = matchingCreateCommand
|
const isCopilotEnabled = useIsFeatureEnabled('IS_COPILOT_ENABLED');
|
||||||
|
const setCopilotQuery = useSetRecoilState(copilotQueryState);
|
||||||
|
const openCopilotRightDrawer = useOpenCopilotRightDrawer();
|
||||||
|
|
||||||
|
const copilotCommand: Command = {
|
||||||
|
id: 'copilot',
|
||||||
|
to: '', // TODO
|
||||||
|
Icon: IconSparkles,
|
||||||
|
label: 'Open Copilot',
|
||||||
|
type: CommandType.Navigate,
|
||||||
|
onCommandClick: () => {
|
||||||
|
setCopilotQuery(commandMenuSearch);
|
||||||
|
openCopilotRightDrawer();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const copilotCommands: Command[] = isCopilotEnabled ? [copilotCommand] : [];
|
||||||
|
|
||||||
|
const selectableItemIds = copilotCommands
|
||||||
.map((cmd) => cmd.id)
|
.map((cmd) => cmd.id)
|
||||||
|
.concat(matchingCreateCommand.map((cmd) => cmd.id))
|
||||||
.concat(matchingNavigateCommand.map((cmd) => cmd.id))
|
.concat(matchingNavigateCommand.map((cmd) => cmd.id))
|
||||||
.concat(people.map((person) => person.id))
|
.concat(people.map((person) => person.id))
|
||||||
.concat(companies.map((company) => company.id))
|
.concat(companies.map((company) => company.id))
|
||||||
@ -275,6 +297,7 @@ export const CommandMenu = () => {
|
|||||||
hotkeyScope={AppHotkeyScope.CommandMenu}
|
hotkeyScope={AppHotkeyScope.CommandMenu}
|
||||||
onEnter={(itemId) => {
|
onEnter={(itemId) => {
|
||||||
const command = [
|
const command = [
|
||||||
|
...copilotCommands,
|
||||||
...commandMenuCommands,
|
...commandMenuCommands,
|
||||||
...otherCommands,
|
...otherCommands,
|
||||||
].find((cmd) => cmd.id === itemId);
|
].find((cmd) => cmd.id === itemId);
|
||||||
@ -292,6 +315,22 @@ export const CommandMenu = () => {
|
|||||||
!activities.length && (
|
!activities.length && (
|
||||||
<StyledEmpty>No results found</StyledEmpty>
|
<StyledEmpty>No results found</StyledEmpty>
|
||||||
)}
|
)}
|
||||||
|
{isCopilotEnabled && (
|
||||||
|
<CommandGroup heading="Copilot">
|
||||||
|
<SelectableItem itemId={copilotCommand.id}>
|
||||||
|
<CommandMenuItem
|
||||||
|
id={copilotCommand.id}
|
||||||
|
Icon={copilotCommand.Icon}
|
||||||
|
label={`${copilotCommand.label} ${
|
||||||
|
commandMenuSearch.length > 2
|
||||||
|
? `"${commandMenuSearch}"`
|
||||||
|
: ''
|
||||||
|
}`}
|
||||||
|
onClick={copilotCommand.onCommandClick}
|
||||||
|
/>
|
||||||
|
</SelectableItem>
|
||||||
|
</CommandGroup>
|
||||||
|
)}
|
||||||
<CommandGroup heading="Create">
|
<CommandGroup heading="Create">
|
||||||
{matchingCreateCommand.map((cmd) => (
|
{matchingCreateCommand.map((cmd) => (
|
||||||
<SelectableItem itemId={cmd.id} key={cmd.id}>
|
<SelectableItem itemId={cmd.id} key={cmd.id}>
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const getCopilot = gql`
|
||||||
|
query GetAISQLQuery($text: String!) {
|
||||||
|
getAISQLQuery(text: $text) {
|
||||||
|
sqlQuery
|
||||||
|
sqlQueryResult
|
||||||
|
queryFailedErrorMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
@ -30,6 +30,8 @@ type AutosizeTextInputProps = {
|
|||||||
value?: string;
|
value?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
onBlur?: () => void;
|
onBlur?: () => void;
|
||||||
|
autoFocus?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -123,6 +125,8 @@ export const AutosizeTextInput = ({
|
|||||||
value = '',
|
value = '',
|
||||||
className,
|
className,
|
||||||
onBlur,
|
onBlur,
|
||||||
|
autoFocus,
|
||||||
|
disabled,
|
||||||
}: AutosizeTextInputProps) => {
|
}: AutosizeTextInputProps) => {
|
||||||
const [isFocused, setIsFocused] = useState(false);
|
const [isFocused, setIsFocused] = useState(false);
|
||||||
const [isHidden, setIsHidden] = useState(
|
const [isHidden, setIsHidden] = useState(
|
||||||
@ -212,7 +216,9 @@ export const AutosizeTextInput = ({
|
|||||||
{!isHidden && (
|
{!isHidden && (
|
||||||
<StyledTextArea
|
<StyledTextArea
|
||||||
ref={textInputRef}
|
ref={textInputRef}
|
||||||
autoFocus={variant === AutosizeTextInputVariant.Button}
|
autoFocus={
|
||||||
|
autoFocus || variant === AutosizeTextInputVariant.Button
|
||||||
|
}
|
||||||
placeholder={placeholder ?? 'Write a comment'}
|
placeholder={placeholder ?? 'Write a comment'}
|
||||||
maxRows={MAX_ROWS}
|
maxRows={MAX_ROWS}
|
||||||
minRows={computedMinRows}
|
minRows={computedMinRows}
|
||||||
@ -221,6 +227,7 @@ export const AutosizeTextInput = ({
|
|||||||
onFocus={handleFocus}
|
onFocus={handleFocus}
|
||||||
onBlur={handleBlur}
|
onBlur={handleBlur}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{variant === AutosizeTextInputVariant.Icon && (
|
{variant === AutosizeTextInputVariant.Icon && (
|
||||||
|
@ -2,6 +2,7 @@ import styled from '@emotion/styled';
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { RightDrawerCalendarEvent } from '@/activities/calendar/right-drawer/components/RightDrawerCalendarEvent';
|
import { RightDrawerCalendarEvent } from '@/activities/calendar/right-drawer/components/RightDrawerCalendarEvent';
|
||||||
|
import { RightDrawerAIChat } from '@/activities/copilot/right-drawer/components/RightDrawerAIChat';
|
||||||
import { RightDrawerEmailThread } from '@/activities/emails/right-drawer/components/RightDrawerEmailThread';
|
import { RightDrawerEmailThread } from '@/activities/emails/right-drawer/components/RightDrawerEmailThread';
|
||||||
import { RightDrawerCreateActivity } from '@/activities/right-drawer/components/create/RightDrawerCreateActivity';
|
import { RightDrawerCreateActivity } from '@/activities/right-drawer/components/create/RightDrawerCreateActivity';
|
||||||
import { RightDrawerEditActivity } from '@/activities/right-drawer/components/edit/RightDrawerEditActivity';
|
import { RightDrawerEditActivity } from '@/activities/right-drawer/components/edit/RightDrawerEditActivity';
|
||||||
@ -50,6 +51,10 @@ const RIGHT_DRAWER_PAGES_CONFIG = {
|
|||||||
page: <RightDrawerRecord />,
|
page: <RightDrawerRecord />,
|
||||||
topBar: <RightDrawerTopBar page={RightDrawerPages.ViewRecord} />,
|
topBar: <RightDrawerTopBar page={RightDrawerPages.ViewRecord} />,
|
||||||
},
|
},
|
||||||
|
[RightDrawerPages.Copilot]: {
|
||||||
|
page: <RightDrawerAIChat />,
|
||||||
|
topBar: <RightDrawerTopBar page={RightDrawerPages.Copilot} />,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RightDrawerRouter = () => {
|
export const RightDrawerRouter = () => {
|
||||||
|
@ -6,4 +6,5 @@ export const RIGHT_DRAWER_PAGE_ICONS = {
|
|||||||
[RightDrawerPages.ViewEmailThread]: 'IconMail',
|
[RightDrawerPages.ViewEmailThread]: 'IconMail',
|
||||||
[RightDrawerPages.ViewCalendarEvent]: 'IconCalendarEvent',
|
[RightDrawerPages.ViewCalendarEvent]: 'IconCalendarEvent',
|
||||||
[RightDrawerPages.ViewRecord]: 'Icon123',
|
[RightDrawerPages.ViewRecord]: 'Icon123',
|
||||||
|
[RightDrawerPages.Copilot]: 'IconSparkles',
|
||||||
};
|
};
|
||||||
|
@ -6,4 +6,5 @@ export const RIGHT_DRAWER_PAGE_TITLES = {
|
|||||||
[RightDrawerPages.ViewEmailThread]: 'Email Thread',
|
[RightDrawerPages.ViewEmailThread]: 'Email Thread',
|
||||||
[RightDrawerPages.ViewCalendarEvent]: 'Calendar Event',
|
[RightDrawerPages.ViewCalendarEvent]: 'Calendar Event',
|
||||||
[RightDrawerPages.ViewRecord]: 'Record Editor',
|
[RightDrawerPages.ViewRecord]: 'Record Editor',
|
||||||
|
[RightDrawerPages.Copilot]: 'Copilot',
|
||||||
};
|
};
|
||||||
|
@ -4,4 +4,5 @@ export enum RightDrawerPages {
|
|||||||
ViewEmailThread = 'view-email-thread',
|
ViewEmailThread = 'view-email-thread',
|
||||||
ViewCalendarEvent = 'view-calendar-event',
|
ViewCalendarEvent = 'view-calendar-event',
|
||||||
ViewRecord = 'view-record',
|
ViewRecord = 'view-record',
|
||||||
|
Copilot = 'copilot',
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ type TabProps = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
hasBetaPill?: boolean;
|
pill?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledTab = styled.div<{ active?: boolean; disabled?: boolean }>`
|
const StyledTab = styled.div<{ active?: boolean; disabled?: boolean }>`
|
||||||
@ -59,7 +59,7 @@ export const Tab = ({
|
|||||||
onClick,
|
onClick,
|
||||||
className,
|
className,
|
||||||
disabled,
|
disabled,
|
||||||
hasBetaPill,
|
pill,
|
||||||
}: TabProps) => {
|
}: TabProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
@ -73,7 +73,7 @@ export const Tab = ({
|
|||||||
<StyledHover>
|
<StyledHover>
|
||||||
{Icon && <Icon size={theme.icon.size.md} />}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
{title}
|
{title}
|
||||||
{hasBetaPill && <Pill label="Beta" />}
|
{pill && <Pill label={pill} />}
|
||||||
</StyledHover>
|
</StyledHover>
|
||||||
</StyledTab>
|
</StyledTab>
|
||||||
);
|
);
|
||||||
|
@ -15,7 +15,7 @@ type SingleTabProps = {
|
|||||||
id: string;
|
id: string;
|
||||||
hide?: boolean;
|
hide?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
hasBetaPill?: boolean;
|
pill?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TabListProps = {
|
type TabListProps = {
|
||||||
@ -62,7 +62,7 @@ export const TabList = ({ tabs, tabListId, loading }: TabListProps) => {
|
|||||||
setActiveTabId(tab.id);
|
setActiveTabId(tab.id);
|
||||||
}}
|
}}
|
||||||
disabled={tab.disabled ?? loading}
|
disabled={tab.disabled ?? loading}
|
||||||
hasBetaPill={tab.hasBetaPill}
|
pill={tab.pill}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
|
@ -4,4 +4,5 @@ export type FeatureFlagKey =
|
|||||||
| 'IS_EVENT_OBJECT_ENABLED'
|
| 'IS_EVENT_OBJECT_ENABLED'
|
||||||
| 'IS_AIRTABLE_INTEGRATION_ENABLED'
|
| 'IS_AIRTABLE_INTEGRATION_ENABLED'
|
||||||
| 'IS_POSTGRESQL_INTEGRATION_ENABLED'
|
| 'IS_POSTGRESQL_INTEGRATION_ENABLED'
|
||||||
| 'IS_STRIPE_INTEGRATION_ENABLED';
|
| 'IS_STRIPE_INTEGRATION_ENABLED'
|
||||||
|
| 'IS_COPILOT_ENABLED';
|
||||||
|
@ -72,4 +72,4 @@ SIGN_IN_PREFILLED=true
|
|||||||
# API_RATE_LIMITING_LIMIT=
|
# API_RATE_LIMITING_LIMIT=
|
||||||
# MUTATION_MAXIMUM_AFFECTED_RECORDS=100
|
# MUTATION_MAXIMUM_AFFECTED_RECORDS=100
|
||||||
# CHROME_EXTENSION_ID=bggmipldbceihilonnbpgoeclgbkblkp
|
# CHROME_EXTENSION_ID=bggmipldbceihilonnbpgoeclgbkblkp
|
||||||
# PG_SSL_ALLOW_SELF_SIGNED=true
|
# PG_SSL_ALLOW_SELF_SIGNED=true
|
@ -15,6 +15,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga-nestjs-npm-2.1.0-cb509e6047.patch",
|
"@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga-nestjs-npm-2.1.0-cb509e6047.patch",
|
||||||
|
"@langchain/mistralai": "^0.0.24",
|
||||||
|
"@langchain/openai": "^0.1.3",
|
||||||
"@nestjs/cache-manager": "^2.2.1",
|
"@nestjs/cache-manager": "^2.2.1",
|
||||||
"@nestjs/devtools-integration": "^0.1.6",
|
"@nestjs/devtools-integration": "^0.1.6",
|
||||||
"@nestjs/graphql": "patch:@nestjs/graphql@12.1.1#./patches/@nestjs+graphql+12.1.1.patch",
|
"@nestjs/graphql": "patch:@nestjs/graphql@12.1.1#./patches/@nestjs+graphql+12.1.1.patch",
|
||||||
@ -25,13 +27,16 @@
|
|||||||
"graphql-middleware": "^6.1.35",
|
"graphql-middleware": "^6.1.35",
|
||||||
"jsdom": "~22.1.0",
|
"jsdom": "~22.1.0",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
"langchain": "^0.2.6",
|
||||||
|
"langfuse-langchain": "^3.11.2",
|
||||||
"lodash.differencewith": "^4.5.0",
|
"lodash.differencewith": "^4.5.0",
|
||||||
"lodash.omitby": "^4.6.0",
|
"lodash.omitby": "^4.6.0",
|
||||||
"lodash.uniq": "^4.5.0",
|
"lodash.uniq": "^4.5.0",
|
||||||
"lodash.uniqby": "^4.7.0",
|
"lodash.uniqby": "^4.7.0",
|
||||||
"passport": "^0.7.0",
|
"passport": "^0.7.0",
|
||||||
"psl": "^1.9.0",
|
"psl": "^1.9.0",
|
||||||
"tsconfig-paths": "^4.2.0"
|
"tsconfig-paths": "^4.2.0",
|
||||||
|
"zod-to-json-schema": "^3.23.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nestjs/cli": "10.3.0",
|
"@nestjs/cli": "10.3.0",
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
|
|
||||||
import isEmpty from 'lodash.isempty';
|
import isEmpty from 'lodash.isempty';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
import { IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
import { IConnection } from 'src/engine/api/graphql/workspace-query-runner/interfaces/connection.interface';
|
||||||
import {
|
import {
|
||||||
@ -620,15 +621,12 @@ export class WorkspaceQueryRunnerService {
|
|||||||
return sanitizedRecord;
|
return sanitizedRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(
|
async executeSQL(
|
||||||
query: string,
|
workspaceDataSource: DataSource,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
): Promise<PGGraphQLResult | undefined> {
|
sqlQuery: string,
|
||||||
const workspaceDataSource =
|
parameters?: any[],
|
||||||
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
|
) {
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await workspaceDataSource?.transaction(
|
return await workspaceDataSource?.transaction(
|
||||||
async (transactionManager) => {
|
async (transactionManager) => {
|
||||||
@ -638,10 +636,7 @@ export class WorkspaceQueryRunnerService {
|
|||||||
)};
|
)};
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const results = transactionManager.query<PGGraphQLResult>(
|
const results = transactionManager.query(sqlQuery, parameters);
|
||||||
`SELECT graphql.resolve($1);`,
|
|
||||||
[query],
|
|
||||||
);
|
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
@ -655,6 +650,23 @@ export class WorkspaceQueryRunnerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async execute(
|
||||||
|
query: string,
|
||||||
|
workspaceId: string,
|
||||||
|
): Promise<PGGraphQLResult | undefined> {
|
||||||
|
const workspaceDataSource =
|
||||||
|
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.executeSQL(
|
||||||
|
workspaceDataSource,
|
||||||
|
workspaceId,
|
||||||
|
`SELECT graphql.resolve($1);`,
|
||||||
|
[query],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private async parseResult<Result>(
|
private async parseResult<Result>(
|
||||||
graphqlResult: PGGraphQLResult | undefined,
|
graphqlResult: PGGraphQLResult | undefined,
|
||||||
objectMetadataItem: ObjectMetadataInterface,
|
objectMetadataItem: ObjectMetadataInterface,
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||||
|
import { UserModule } from 'src/engine/core-modules/user/user.module';
|
||||||
|
import { AISQLQueryResolver } from 'src/engine/core-modules/ai-sql-query/ai-sql-query.resolver';
|
||||||
|
import { AISQLQueryService } from 'src/engine/core-modules/ai-sql-query/ai-sql-query.service';
|
||||||
|
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||||
|
import { WorkspaceQueryRunnerModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module';
|
||||||
|
import { LLMChatModelModule } from 'src/engine/integrations/llm-chat-model/llm-chat-model.module';
|
||||||
|
import { EnvironmentModule } from 'src/engine/integrations/environment/environment.module';
|
||||||
|
import { LLMTracingModule } from 'src/engine/integrations/llm-tracing/llm-tracing.module';
|
||||||
|
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||||
|
import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module';
|
||||||
|
@Module({
|
||||||
|
imports: [
|
||||||
|
WorkspaceDataSourceModule,
|
||||||
|
WorkspaceQueryRunnerModule,
|
||||||
|
UserModule,
|
||||||
|
TypeOrmModule.forFeature([FeatureFlagEntity], 'core'),
|
||||||
|
LLMChatModelModule,
|
||||||
|
LLMTracingModule,
|
||||||
|
EnvironmentModule,
|
||||||
|
ObjectMetadataModule,
|
||||||
|
WorkspaceSyncMetadataModule,
|
||||||
|
],
|
||||||
|
exports: [],
|
||||||
|
providers: [AISQLQueryResolver, AISQLQueryService],
|
||||||
|
})
|
||||||
|
export class AISQLQueryModule {}
|
@ -0,0 +1,14 @@
|
|||||||
|
import { PromptTemplate } from '@langchain/core/prompts';
|
||||||
|
|
||||||
|
export const sqlGenerationPromptTemplate = PromptTemplate.fromTemplate<{
|
||||||
|
llmOutputJsonSchema: string;
|
||||||
|
sqlCreateTableStatements: string;
|
||||||
|
userQuestion: string;
|
||||||
|
}>(`Always respond following this JSON Schema: {llmOutputJsonSchema}
|
||||||
|
|
||||||
|
Based on the table schema below, write a PostgreSQL query that would answer the user's question. All column names must be enclosed in double quotes.
|
||||||
|
|
||||||
|
{sqlCreateTableStatements}
|
||||||
|
|
||||||
|
Question: {userQuestion}
|
||||||
|
SQL Query:`);
|
@ -0,0 +1,64 @@
|
|||||||
|
import { Args, Query, Resolver, ArgsType, Field } from '@nestjs/graphql';
|
||||||
|
import { ForbiddenException, UseGuards } from '@nestjs/common';
|
||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
|
import {
|
||||||
|
FeatureFlagEntity,
|
||||||
|
FeatureFlagKeys,
|
||||||
|
} from 'src/engine/core-modules/feature-flag/feature-flag.entity';
|
||||||
|
import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||||
|
import { AISQLQueryResult } from 'src/engine/core-modules/ai-sql-query/dtos/ai-sql-query-result.dto';
|
||||||
|
import { AISQLQueryService } from 'src/engine/core-modules/ai-sql-query/ai-sql-query.service';
|
||||||
|
|
||||||
|
@ArgsType()
|
||||||
|
class GetAISQLQueryArgs {
|
||||||
|
@Field(() => String)
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Resolver(() => AISQLQueryResult)
|
||||||
|
export class AISQLQueryResolver {
|
||||||
|
constructor(
|
||||||
|
private readonly aiSqlQueryService: AISQLQueryService,
|
||||||
|
@InjectRepository(FeatureFlagEntity, 'core')
|
||||||
|
private readonly featureFlagRepository: Repository<FeatureFlagEntity>,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Query(() => AISQLQueryResult)
|
||||||
|
async getAISQLQuery(
|
||||||
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
|
@AuthUser() user: User,
|
||||||
|
@Args() { text }: GetAISQLQueryArgs,
|
||||||
|
) {
|
||||||
|
const isCopilotEnabledFeatureFlag =
|
||||||
|
await this.featureFlagRepository.findOneBy({
|
||||||
|
workspaceId,
|
||||||
|
key: FeatureFlagKeys.IsCopilotEnabled,
|
||||||
|
value: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isCopilotEnabledFeatureFlag?.value) {
|
||||||
|
throw new ForbiddenException(
|
||||||
|
`${FeatureFlagKeys.IsCopilotEnabled} feature flag is disabled`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const traceMetadata = {
|
||||||
|
userId: user.id,
|
||||||
|
userEmail: user.email,
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.aiSqlQueryService.generateAndExecute(
|
||||||
|
workspaceId,
|
||||||
|
text,
|
||||||
|
traceMetadata,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,253 @@
|
|||||||
|
import { Injectable, Logger } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { RunnableSequence } from '@langchain/core/runnables';
|
||||||
|
import { StructuredOutputParser } from '@langchain/core/output_parsers';
|
||||||
|
import { DataSource, QueryFailedError } from 'typeorm';
|
||||||
|
import { z } from 'zod';
|
||||||
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
||||||
|
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';
|
||||||
|
import groupBy from 'lodash.groupby';
|
||||||
|
|
||||||
|
import { PartialFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/partial-field-metadata.interface';
|
||||||
|
|
||||||
|
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||||
|
import { WorkspaceQueryRunnerService } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-runner.service';
|
||||||
|
import { LLMChatModelService } from 'src/engine/integrations/llm-chat-model/llm-chat-model.service';
|
||||||
|
import { LLMTracingService } from 'src/engine/integrations/llm-tracing/llm-tracing.service';
|
||||||
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
|
import { DEFAULT_LABEL_IDENTIFIER_FIELD_NAME } from 'src/engine/metadata-modules/object-metadata/object-metadata.constants';
|
||||||
|
import { StandardObjectFactory } from 'src/engine/workspace-manager/workspace-sync-metadata/factories/standard-object.factory';
|
||||||
|
import { standardObjectMetadataDefinitions } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-objects';
|
||||||
|
import { AISQLQueryResult } from 'src/engine/core-modules/ai-sql-query/dtos/ai-sql-query-result.dto';
|
||||||
|
import { sqlGenerationPromptTemplate } from 'src/engine/core-modules/ai-sql-query/ai-sql-query.prompt-templates';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AISQLQueryService {
|
||||||
|
private readonly logger = new Logger(AISQLQueryService.name);
|
||||||
|
constructor(
|
||||||
|
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||||
|
private readonly workspaceQueryRunnerService: WorkspaceQueryRunnerService,
|
||||||
|
private readonly llmChatModelService: LLMChatModelService,
|
||||||
|
private readonly llmTracingService: LLMTracingService,
|
||||||
|
private readonly standardObjectFactory: StandardObjectFactory,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private getLabelIdentifierName(
|
||||||
|
objectMetadata: ObjectMetadataEntity,
|
||||||
|
dataSourceId,
|
||||||
|
workspaceId,
|
||||||
|
workspaceFeatureFlagsMap,
|
||||||
|
): string | undefined {
|
||||||
|
const customObjectLabelIdentifierFieldMetadata = objectMetadata.fields.find(
|
||||||
|
(fieldMetadata) =>
|
||||||
|
fieldMetadata.id === objectMetadata.labelIdentifierFieldMetadataId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const standardObjectMetadataCollection = this.standardObjectFactory.create(
|
||||||
|
standardObjectMetadataDefinitions,
|
||||||
|
{ workspaceId, dataSourceId },
|
||||||
|
workspaceFeatureFlagsMap,
|
||||||
|
);
|
||||||
|
|
||||||
|
const standardObjectLabelIdentifierFieldMetadata =
|
||||||
|
standardObjectMetadataCollection
|
||||||
|
.find(
|
||||||
|
(standardObjectMetadata) =>
|
||||||
|
standardObjectMetadata.nameSingular === objectMetadata.nameSingular,
|
||||||
|
)
|
||||||
|
?.fields.find(
|
||||||
|
(field: PartialFieldMetadata) =>
|
||||||
|
field.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME,
|
||||||
|
) as PartialFieldMetadata;
|
||||||
|
|
||||||
|
const labelIdentifierFieldMetadata =
|
||||||
|
customObjectLabelIdentifierFieldMetadata ??
|
||||||
|
standardObjectLabelIdentifierFieldMetadata;
|
||||||
|
|
||||||
|
return (
|
||||||
|
labelIdentifierFieldMetadata?.name ?? DEFAULT_LABEL_IDENTIFIER_FIELD_NAME
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getColInfosByTableName(dataSource: DataSource) {
|
||||||
|
const { schema } = dataSource.options as PostgresConnectionOptions;
|
||||||
|
|
||||||
|
// From LangChain sql_utils.ts
|
||||||
|
const sqlQuery = `SELECT
|
||||||
|
t.table_name,
|
||||||
|
c.*
|
||||||
|
FROM
|
||||||
|
information_schema.tables t
|
||||||
|
JOIN information_schema.columns c
|
||||||
|
ON t.table_name = c.table_name
|
||||||
|
WHERE
|
||||||
|
t.table_schema = '${schema}'
|
||||||
|
AND c.table_schema = '${schema}'
|
||||||
|
ORDER BY
|
||||||
|
t.table_name,
|
||||||
|
c.ordinal_position;`;
|
||||||
|
const colInfos = await dataSource.query<
|
||||||
|
{
|
||||||
|
table_name: string;
|
||||||
|
column_name: string;
|
||||||
|
data_type: string | undefined;
|
||||||
|
is_nullable: 'YES' | 'NO';
|
||||||
|
}[]
|
||||||
|
>(sqlQuery);
|
||||||
|
|
||||||
|
return groupBy(colInfos, (colInfo) => colInfo.table_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCreateTableStatement(tableName: string, colInfos: any[]) {
|
||||||
|
return `${`CREATE TABLE ${tableName} (\n`} ${colInfos
|
||||||
|
.map(
|
||||||
|
(colInfo) =>
|
||||||
|
`${colInfo.column_name} ${colInfo.data_type} ${
|
||||||
|
colInfo.is_nullable === 'YES' ? '' : 'NOT NULL'
|
||||||
|
}`,
|
||||||
|
)
|
||||||
|
.join(', ')});`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getRelationDescriptions() {
|
||||||
|
// TODO - Construct sentences like the following:
|
||||||
|
// investorId: a foreign key referencing the person table, indicating the investor who owns this portfolio company.
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTableDescription(tableName: string, colInfos: any[]) {
|
||||||
|
return [
|
||||||
|
this.getCreateTableStatement(tableName, colInfos),
|
||||||
|
this.getRelationDescriptions(),
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getWorkspaceSchemaDescription(
|
||||||
|
dataSource: DataSource,
|
||||||
|
): Promise<string> {
|
||||||
|
const colInfoByTableName = await this.getColInfosByTableName(dataSource);
|
||||||
|
|
||||||
|
return Object.entries(colInfoByTableName)
|
||||||
|
.map(([tableName, colInfos]) =>
|
||||||
|
this.getTableDescription(tableName, colInfos),
|
||||||
|
)
|
||||||
|
.join('\n\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async generateWithDataSource(
|
||||||
|
workspaceId: string,
|
||||||
|
workspaceDataSource: DataSource,
|
||||||
|
userQuestion: string,
|
||||||
|
traceMetadata: Record<string, string> = {},
|
||||||
|
) {
|
||||||
|
const workspaceSchemaName =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
|
workspaceDataSource.setOptions({
|
||||||
|
schema: workspaceSchemaName,
|
||||||
|
});
|
||||||
|
|
||||||
|
const workspaceSchemaDescription =
|
||||||
|
await this.getWorkspaceSchemaDescription(workspaceDataSource);
|
||||||
|
|
||||||
|
const llmOutputSchema = z.object({
|
||||||
|
sqlQuery: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const llmOutputJsonSchema = JSON.stringify(
|
||||||
|
zodToJsonSchema(llmOutputSchema),
|
||||||
|
);
|
||||||
|
|
||||||
|
const structuredOutputParser =
|
||||||
|
StructuredOutputParser.fromZodSchema(llmOutputSchema);
|
||||||
|
|
||||||
|
const sqlQueryGeneratorChain = RunnableSequence.from([
|
||||||
|
sqlGenerationPromptTemplate,
|
||||||
|
this.llmChatModelService.getJSONChatModel(),
|
||||||
|
structuredOutputParser,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const metadata = {
|
||||||
|
workspaceId,
|
||||||
|
...traceMetadata,
|
||||||
|
};
|
||||||
|
const tracingCallbackHandler =
|
||||||
|
this.llmTracingService.getCallbackHandler(metadata);
|
||||||
|
|
||||||
|
const { sqlQuery } = await sqlQueryGeneratorChain.invoke(
|
||||||
|
{
|
||||||
|
llmOutputJsonSchema,
|
||||||
|
sqlCreateTableStatements: workspaceSchemaDescription,
|
||||||
|
userQuestion,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
callbacks: [tracingCallbackHandler],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return sqlQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
async generate(
|
||||||
|
workspaceId: string,
|
||||||
|
userQuestion: string,
|
||||||
|
traceMetadata: Record<string, string> = {},
|
||||||
|
) {
|
||||||
|
const workspaceDataSource =
|
||||||
|
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.generateWithDataSource(
|
||||||
|
workspaceId,
|
||||||
|
workspaceDataSource,
|
||||||
|
userQuestion,
|
||||||
|
traceMetadata,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async generateAndExecute(
|
||||||
|
workspaceId: string,
|
||||||
|
userQuestion: string,
|
||||||
|
traceMetadata: Record<string, string> = {},
|
||||||
|
): Promise<AISQLQueryResult> {
|
||||||
|
const workspaceDataSource =
|
||||||
|
await this.workspaceDataSourceService.connectToWorkspaceDataSource(
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const sqlQuery = await this.generateWithDataSource(
|
||||||
|
workspaceId,
|
||||||
|
workspaceDataSource,
|
||||||
|
userQuestion,
|
||||||
|
traceMetadata,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const sqlQueryResult: Record<string, any>[] =
|
||||||
|
await this.workspaceQueryRunnerService.executeSQL(
|
||||||
|
workspaceDataSource,
|
||||||
|
workspaceId,
|
||||||
|
sqlQuery,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
sqlQuery,
|
||||||
|
sqlQueryResult: JSON.stringify(sqlQueryResult),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof QueryFailedError) {
|
||||||
|
return {
|
||||||
|
sqlQuery,
|
||||||
|
queryFailedErrorMessage: error.message,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.error(error.message, error.stack);
|
||||||
|
|
||||||
|
return {
|
||||||
|
sqlQuery,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
import { Field, ObjectType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { IsOptional } from 'class-validator';
|
||||||
|
|
||||||
|
@ObjectType('AISQLQueryResult')
|
||||||
|
export class AISQLQueryResult {
|
||||||
|
@Field(() => String)
|
||||||
|
sqlQuery: string;
|
||||||
|
|
||||||
|
@Field(() => String, { nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
sqlQueryResult?: string;
|
||||||
|
|
||||||
|
@Field(() => String, { nullable: true })
|
||||||
|
@IsOptional()
|
||||||
|
queryFailedErrorMessage?: string;
|
||||||
|
}
|
@ -10,6 +10,7 @@ import { TimelineMessagingModule } from 'src/engine/core-modules/messaging/timel
|
|||||||
import { TimelineCalendarEventModule } from 'src/engine/core-modules/calendar/timeline-calendar-event.module';
|
import { TimelineCalendarEventModule } from 'src/engine/core-modules/calendar/timeline-calendar-event.module';
|
||||||
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
|
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
|
||||||
import { HealthModule } from 'src/engine/core-modules/health/health.module';
|
import { HealthModule } from 'src/engine/core-modules/health/health.module';
|
||||||
|
import { AISQLQueryModule } from 'src/engine/core-modules/ai-sql-query/ai-sql-query.module';
|
||||||
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
|
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
|
||||||
|
|
||||||
import { AnalyticsModule } from './analytics/analytics.module';
|
import { AnalyticsModule } from './analytics/analytics.module';
|
||||||
@ -31,6 +32,7 @@ import { ClientConfigModule } from './client-config/client-config.module';
|
|||||||
TimelineCalendarEventModule,
|
TimelineCalendarEventModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
WorkspaceModule,
|
WorkspaceModule,
|
||||||
|
AISQLQueryModule,
|
||||||
PostgresCredentialsModule,
|
PostgresCredentialsModule,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
@ -22,6 +22,7 @@ export enum FeatureFlagKeys {
|
|||||||
IsPostgreSQLIntegrationEnabled = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
|
IsPostgreSQLIntegrationEnabled = 'IS_POSTGRESQL_INTEGRATION_ENABLED',
|
||||||
IsStripeIntegrationEnabled = 'IS_STRIPE_INTEGRATION_ENABLED',
|
IsStripeIntegrationEnabled = 'IS_STRIPE_INTEGRATION_ENABLED',
|
||||||
IsContactCreationForSentAndReceivedEmailsEnabled = 'IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED',
|
IsContactCreationForSentAndReceivedEmailsEnabled = 'IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED',
|
||||||
|
IsCopilotEnabled = 'IS_COPILOT_ENABLED',
|
||||||
IsMessagingAliasFetchingEnabled = 'IS_MESSAGING_ALIAS_FETCHING_ENABLED',
|
IsMessagingAliasFetchingEnabled = 'IS_MESSAGING_ALIAS_FETCHING_ENABLED',
|
||||||
IsGoogleCalendarSyncV2Enabled = 'IS_GOOGLE_CALENDAR_SYNC_V2_ENABLED',
|
IsGoogleCalendarSyncV2Enabled = 'IS_GOOGLE_CALENDAR_SYNC_V2_ENABLED',
|
||||||
IsFreeAccessEnabled = 'IS_FREE_ACCESS_ENABLED',
|
IsFreeAccessEnabled = 'IS_FREE_ACCESS_ENABLED',
|
||||||
|
@ -17,6 +17,8 @@ import {
|
|||||||
|
|
||||||
import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface';
|
import { EmailDriver } from 'src/engine/integrations/email/interfaces/email.interface';
|
||||||
import { NodeEnvironment } from 'src/engine/integrations/environment/interfaces/node-environment.interface';
|
import { NodeEnvironment } from 'src/engine/integrations/environment/interfaces/node-environment.interface';
|
||||||
|
import { LLMChatModelDriver } from 'src/engine/integrations/llm-chat-model/interfaces/llm-chat-model.interface';
|
||||||
|
import { LLMTracingDriver } from 'src/engine/integrations/llm-tracing/interfaces/llm-tracing.interface';
|
||||||
|
|
||||||
import { assert } from 'src/utils/assert';
|
import { assert } from 'src/utils/assert';
|
||||||
import { CastToStringArray } from 'src/engine/integrations/environment/decorators/cast-to-string-array.decorator';
|
import { CastToStringArray } from 'src/engine/integrations/environment/decorators/cast-to-string-array.decorator';
|
||||||
@ -369,6 +371,16 @@ export class EnvironmentVariables {
|
|||||||
|
|
||||||
OPENROUTER_API_KEY: string;
|
OPENROUTER_API_KEY: string;
|
||||||
|
|
||||||
|
LLM_CHAT_MODEL_DRIVER: LLMChatModelDriver = LLMChatModelDriver.OpenAI;
|
||||||
|
|
||||||
|
OPENAI_API_KEY: string;
|
||||||
|
|
||||||
|
LANGFUSE_SECRET_KEY: string;
|
||||||
|
|
||||||
|
LANGFUSE_PUBLIC_KEY: string;
|
||||||
|
|
||||||
|
LLM_TRACING_DRIVER: LLMTracingDriver = LLMTracingDriver.Console;
|
||||||
|
|
||||||
@CastToPositiveNumber()
|
@CastToPositiveNumber()
|
||||||
API_RATE_LIMITING_TTL = 100;
|
API_RATE_LIMITING_TTL = 100;
|
||||||
|
|
||||||
|
@ -12,6 +12,10 @@ import { emailModuleFactory } from 'src/engine/integrations/email/email.module-f
|
|||||||
import { CacheStorageModule } from 'src/engine/integrations/cache-storage/cache-storage.module';
|
import { CacheStorageModule } from 'src/engine/integrations/cache-storage/cache-storage.module';
|
||||||
import { CaptchaModule } from 'src/engine/integrations/captcha/captcha.module';
|
import { CaptchaModule } from 'src/engine/integrations/captcha/captcha.module';
|
||||||
import { captchaModuleFactory } from 'src/engine/integrations/captcha/captcha.module-factory';
|
import { captchaModuleFactory } from 'src/engine/integrations/captcha/captcha.module-factory';
|
||||||
|
import { LLMChatModelModule } from 'src/engine/integrations/llm-chat-model/llm-chat-model.module';
|
||||||
|
import { llmChatModelModuleFactory } from 'src/engine/integrations/llm-chat-model/llm-chat-model.module-factory';
|
||||||
|
import { LLMTracingModule } from 'src/engine/integrations/llm-tracing/llm-tracing.module';
|
||||||
|
import { llmTracingModuleFactory } from 'src/engine/integrations/llm-tracing/llm-tracing.module-factory';
|
||||||
|
|
||||||
import { EnvironmentModule } from './environment/environment.module';
|
import { EnvironmentModule } from './environment/environment.module';
|
||||||
import { EnvironmentService } from './environment/environment.service';
|
import { EnvironmentService } from './environment/environment.service';
|
||||||
@ -50,6 +54,14 @@ import { MessageQueueModule } from './message-queue/message-queue.module';
|
|||||||
wildcard: true,
|
wildcard: true,
|
||||||
}),
|
}),
|
||||||
CacheStorageModule,
|
CacheStorageModule,
|
||||||
|
LLMChatModelModule.forRoot({
|
||||||
|
useFactory: llmChatModelModuleFactory,
|
||||||
|
inject: [EnvironmentService],
|
||||||
|
}),
|
||||||
|
LLMTracingModule.forRoot({
|
||||||
|
useFactory: llmTracingModuleFactory,
|
||||||
|
inject: [EnvironmentService],
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
exports: [],
|
exports: [],
|
||||||
providers: [],
|
providers: [],
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
|
||||||
|
export interface LLMChatModelDriver {
|
||||||
|
getJSONChatModel(): BaseChatModel;
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
||||||
|
import { ChatOpenAI } from '@langchain/openai';
|
||||||
|
|
||||||
|
import { LLMChatModelDriver } from 'src/engine/integrations/llm-chat-model/drivers/interfaces/llm-prompt-template-driver.interface';
|
||||||
|
|
||||||
|
export class OpenAIDriver implements LLMChatModelDriver {
|
||||||
|
private chatModel: BaseChatModel;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.chatModel = new ChatOpenAI({
|
||||||
|
model: 'gpt-4o',
|
||||||
|
}).bind({
|
||||||
|
response_format: {
|
||||||
|
type: 'json_object',
|
||||||
|
},
|
||||||
|
}) as unknown as BaseChatModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
getJSONChatModel() {
|
||||||
|
return this.chatModel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import { ModuleMetadata, FactoryProvider } from '@nestjs/common';
|
||||||
|
|
||||||
|
export enum LLMChatModelDriver {
|
||||||
|
OpenAI = 'openai',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLMChatModelModuleOptions {
|
||||||
|
type: LLMChatModelDriver;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LLMChatModelModuleAsyncOptions = {
|
||||||
|
useFactory: (...args: any[]) => LLMChatModelModuleOptions;
|
||||||
|
} & Pick<ModuleMetadata, 'imports'> &
|
||||||
|
Pick<FactoryProvider, 'inject'>;
|
@ -0,0 +1 @@
|
|||||||
|
export const LLM_CHAT_MODEL_DRIVER = Symbol('LLM_CHAT_MODEL_DRIVER');
|
@ -0,0 +1,19 @@
|
|||||||
|
import { LLMChatModelDriver } from 'src/engine/integrations/llm-chat-model/interfaces/llm-chat-model.interface';
|
||||||
|
|
||||||
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
|
||||||
|
export const llmChatModelModuleFactory = (
|
||||||
|
environmentService: EnvironmentService,
|
||||||
|
) => {
|
||||||
|
const driver = environmentService.get('LLM_CHAT_MODEL_DRIVER');
|
||||||
|
|
||||||
|
switch (driver) {
|
||||||
|
case LLMChatModelDriver.OpenAI: {
|
||||||
|
return { type: LLMChatModelDriver.OpenAI };
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error(
|
||||||
|
`Invalid LLM chat model driver (${driver}), check your .env file`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,35 @@
|
|||||||
|
import { DynamicModule, Global } from '@nestjs/common';
|
||||||
|
|
||||||
|
import {
|
||||||
|
LLMChatModelDriver,
|
||||||
|
LLMChatModelModuleAsyncOptions,
|
||||||
|
} from 'src/engine/integrations/llm-chat-model/interfaces/llm-chat-model.interface';
|
||||||
|
|
||||||
|
import { LLM_CHAT_MODEL_DRIVER } from 'src/engine/integrations/llm-chat-model/llm-chat-model.constants';
|
||||||
|
import { OpenAIDriver } from 'src/engine/integrations/llm-chat-model/drivers/openai.driver';
|
||||||
|
import { LLMChatModelService } from 'src/engine/integrations/llm-chat-model/llm-chat-model.service';
|
||||||
|
|
||||||
|
@Global()
|
||||||
|
export class LLMChatModelModule {
|
||||||
|
static forRoot(options: LLMChatModelModuleAsyncOptions): DynamicModule {
|
||||||
|
const provider = {
|
||||||
|
provide: LLM_CHAT_MODEL_DRIVER,
|
||||||
|
useFactory: (...args: any[]) => {
|
||||||
|
const config = options.useFactory(...args);
|
||||||
|
|
||||||
|
switch (config.type) {
|
||||||
|
case LLMChatModelDriver.OpenAI: {
|
||||||
|
return new OpenAIDriver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inject: options.inject || [],
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
module: LLMChatModelModule,
|
||||||
|
providers: [LLMChatModelService, provider],
|
||||||
|
exports: [LLMChatModelService],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import { Injectable, Inject } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { LLMChatModelDriver } from 'src/engine/integrations/llm-chat-model/drivers/interfaces/llm-prompt-template-driver.interface';
|
||||||
|
|
||||||
|
import { LLM_CHAT_MODEL_DRIVER } from 'src/engine/integrations/llm-chat-model/llm-chat-model.constants';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LLMChatModelService {
|
||||||
|
constructor(
|
||||||
|
@Inject(LLM_CHAT_MODEL_DRIVER) private driver: LLMChatModelDriver,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
getJSONChatModel() {
|
||||||
|
return this.driver.getJSONChatModel();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
||||||
|
import { ConsoleCallbackHandler } from '@langchain/core/tracers/console';
|
||||||
|
import { Run } from '@langchain/core/tracers/base';
|
||||||
|
|
||||||
|
import { LLMTracingDriver } from 'src/engine/integrations/llm-tracing/drivers/interfaces/llm-tracing-driver.interface';
|
||||||
|
|
||||||
|
class WithMetadataConsoleCallbackHandler extends ConsoleCallbackHandler {
|
||||||
|
private metadata: Record<string, unknown>;
|
||||||
|
|
||||||
|
constructor(metadata: Record<string, unknown>) {
|
||||||
|
super();
|
||||||
|
this.metadata = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
onChainStart(run: Run) {
|
||||||
|
console.log(`Chain metadata: ${JSON.stringify(this.metadata)}`);
|
||||||
|
super.onChainStart(run);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ConsoleDriver implements LLMTracingDriver {
|
||||||
|
getCallbackHandler(metadata: Record<string, unknown>): BaseCallbackHandler {
|
||||||
|
return new WithMetadataConsoleCallbackHandler(metadata);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
||||||
|
|
||||||
|
export interface LLMTracingDriver {
|
||||||
|
getCallbackHandler(metadata: Record<string, unknown>): BaseCallbackHandler;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
||||||
|
import CallbackHandler from 'langfuse-langchain';
|
||||||
|
|
||||||
|
import { LLMTracingDriver } from 'src/engine/integrations/llm-tracing/drivers/interfaces/llm-tracing-driver.interface';
|
||||||
|
|
||||||
|
export interface LangfuseDriverOptions {
|
||||||
|
secretKey: string;
|
||||||
|
publicKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LangfuseDriver implements LLMTracingDriver {
|
||||||
|
private options: LangfuseDriverOptions;
|
||||||
|
|
||||||
|
constructor(options: LangfuseDriverOptions) {
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCallbackHandler(metadata: Record<string, unknown>): BaseCallbackHandler {
|
||||||
|
return new CallbackHandler({
|
||||||
|
secretKey: this.options.secretKey,
|
||||||
|
publicKey: this.options.publicKey,
|
||||||
|
baseUrl: 'https://cloud.langfuse.com',
|
||||||
|
metadata: metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { ModuleMetadata, FactoryProvider } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { LangfuseDriverOptions } from 'src/engine/integrations/llm-tracing/drivers/langfuse.driver';
|
||||||
|
|
||||||
|
export enum LLMTracingDriver {
|
||||||
|
Langfuse = 'langfuse',
|
||||||
|
Console = 'console',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LangfuseDriverFactoryOptions {
|
||||||
|
type: LLMTracingDriver.Langfuse;
|
||||||
|
options: LangfuseDriverOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConsoleDriverFactoryOptions {
|
||||||
|
type: LLMTracingDriver.Console;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LLMTracingModuleOptions =
|
||||||
|
| LangfuseDriverFactoryOptions
|
||||||
|
| ConsoleDriverFactoryOptions;
|
||||||
|
|
||||||
|
export type LLMTracingModuleAsyncOptions = {
|
||||||
|
useFactory: (...args: any[]) => LLMTracingModuleOptions;
|
||||||
|
} & Pick<ModuleMetadata, 'imports'> &
|
||||||
|
Pick<FactoryProvider, 'inject'>;
|
@ -0,0 +1 @@
|
|||||||
|
export const LLM_TRACING_DRIVER = Symbol('LLM_TRACING_DRIVER');
|
@ -0,0 +1,34 @@
|
|||||||
|
import { LLMTracingDriver } from 'src/engine/integrations/llm-tracing/interfaces/llm-tracing.interface';
|
||||||
|
|
||||||
|
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
|
||||||
|
|
||||||
|
export const llmTracingModuleFactory = (
|
||||||
|
environmentService: EnvironmentService,
|
||||||
|
) => {
|
||||||
|
const driver = environmentService.get('LLM_TRACING_DRIVER');
|
||||||
|
|
||||||
|
switch (driver) {
|
||||||
|
case LLMTracingDriver.Console: {
|
||||||
|
return { type: LLMTracingDriver.Console as const };
|
||||||
|
}
|
||||||
|
case LLMTracingDriver.Langfuse: {
|
||||||
|
const secretKey = environmentService.get('LANGFUSE_SECRET_KEY');
|
||||||
|
const publicKey = environmentService.get('LANGFUSE_PUBLIC_KEY');
|
||||||
|
|
||||||
|
if (!(secretKey && publicKey)) {
|
||||||
|
throw new Error(
|
||||||
|
`${driver} LLM tracing driver requires LANGFUSE_SECRET_KEY and LANGFUSE_PUBLIC_KEY to be defined, check your .env file`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: LLMTracingDriver.Langfuse as const,
|
||||||
|
options: { secretKey, publicKey },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error(
|
||||||
|
`Invalid LLM tracing driver (${driver}), check your .env file`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,39 @@
|
|||||||
|
import { Global, DynamicModule } from '@nestjs/common';
|
||||||
|
|
||||||
|
import {
|
||||||
|
LLMTracingModuleAsyncOptions,
|
||||||
|
LLMTracingDriver,
|
||||||
|
} from 'src/engine/integrations/llm-tracing/interfaces/llm-tracing.interface';
|
||||||
|
|
||||||
|
import { LangfuseDriver } from 'src/engine/integrations/llm-tracing/drivers/langfuse.driver';
|
||||||
|
import { ConsoleDriver } from 'src/engine/integrations/llm-tracing/drivers/console.driver';
|
||||||
|
import { LLMTracingService } from 'src/engine/integrations/llm-tracing/llm-tracing.service';
|
||||||
|
import { LLM_TRACING_DRIVER } from 'src/engine/integrations/llm-tracing/llm-tracing.constants';
|
||||||
|
|
||||||
|
@Global()
|
||||||
|
export class LLMTracingModule {
|
||||||
|
static forRoot(options: LLMTracingModuleAsyncOptions): DynamicModule {
|
||||||
|
const provider = {
|
||||||
|
provide: LLM_TRACING_DRIVER,
|
||||||
|
useFactory: (...args: any[]) => {
|
||||||
|
const config = options.useFactory(...args);
|
||||||
|
|
||||||
|
switch (config.type) {
|
||||||
|
case LLMTracingDriver.Langfuse: {
|
||||||
|
return new LangfuseDriver(config.options);
|
||||||
|
}
|
||||||
|
case LLMTracingDriver.Console: {
|
||||||
|
return new ConsoleDriver();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inject: options.inject || [],
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
module: LLMTracingModule,
|
||||||
|
providers: [LLMTracingService, provider],
|
||||||
|
exports: [LLMTracingService],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
import { Injectable, Inject } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
||||||
|
|
||||||
|
import { LLMTracingDriver } from 'src/engine/integrations/llm-tracing/drivers/interfaces/llm-tracing-driver.interface';
|
||||||
|
|
||||||
|
import { LLM_TRACING_DRIVER } from 'src/engine/integrations/llm-tracing/llm-tracing.constants';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LLMTracingService {
|
||||||
|
constructor(@Inject(LLM_TRACING_DRIVER) private driver: LLMTracingDriver) {}
|
||||||
|
|
||||||
|
getCallbackHandler(metadata: Record<string, unknown>): BaseCallbackHandler {
|
||||||
|
return this.driver.getCallbackHandler(metadata);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export const DEFAULT_LABEL_IDENTIFIER_FIELD_NAME = 'name';
|
@ -59,6 +59,7 @@ export class AddStandardIdCommand extends CommandRunner {
|
|||||||
IS_POSTGRESQL_INTEGRATION_ENABLED: true,
|
IS_POSTGRESQL_INTEGRATION_ENABLED: true,
|
||||||
IS_STRIPE_INTEGRATION_ENABLED: false,
|
IS_STRIPE_INTEGRATION_ENABLED: false,
|
||||||
IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED: true,
|
IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED: true,
|
||||||
|
IS_COPILOT_ENABLED: false,
|
||||||
IS_MESSAGING_ALIAS_FETCHING_ENABLED: true,
|
IS_MESSAGING_ALIAS_FETCHING_ENABLED: true,
|
||||||
IS_GOOGLE_CALENDAR_SYNC_V2_ENABLED: true,
|
IS_GOOGLE_CALENDAR_SYNC_V2_ENABLED: true,
|
||||||
IS_FREE_ACCESS_ENABLED: false,
|
IS_FREE_ACCESS_ENABLED: false,
|
||||||
@ -77,6 +78,7 @@ export class AddStandardIdCommand extends CommandRunner {
|
|||||||
IS_POSTGRESQL_INTEGRATION_ENABLED: true,
|
IS_POSTGRESQL_INTEGRATION_ENABLED: true,
|
||||||
IS_STRIPE_INTEGRATION_ENABLED: false,
|
IS_STRIPE_INTEGRATION_ENABLED: false,
|
||||||
IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED: true,
|
IS_CONTACT_CREATION_FOR_SENT_AND_RECEIVED_EMAILS_ENABLED: true,
|
||||||
|
IS_COPILOT_ENABLED: false,
|
||||||
IS_MESSAGING_ALIAS_FETCHING_ENABLED: true,
|
IS_MESSAGING_ALIAS_FETCHING_ENABLED: true,
|
||||||
IS_GOOGLE_CALENDAR_SYNC_V2_ENABLED: true,
|
IS_GOOGLE_CALENDAR_SYNC_V2_ENABLED: true,
|
||||||
IS_FREE_ACCESS_ENABLED: false,
|
IS_FREE_ACCESS_ENABLED: false,
|
||||||
|
@ -33,6 +33,7 @@ export {
|
|||||||
IconCalendarEvent,
|
IconCalendarEvent,
|
||||||
IconCalendarTime,
|
IconCalendarTime,
|
||||||
IconCalendarX,
|
IconCalendarX,
|
||||||
|
IconChartCandle,
|
||||||
IconCheck,
|
IconCheck,
|
||||||
IconCheckbox,
|
IconCheckbox,
|
||||||
IconChevronDown,
|
IconChevronDown,
|
||||||
@ -137,10 +138,13 @@ export {
|
|||||||
IconReload,
|
IconReload,
|
||||||
IconRepeat,
|
IconRepeat,
|
||||||
IconRocket,
|
IconRocket,
|
||||||
|
IconRotate,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
IconSend,
|
IconSend,
|
||||||
IconSettings,
|
IconSettings,
|
||||||
IconSortDescending,
|
IconSortDescending,
|
||||||
|
IconSparkles,
|
||||||
|
IconSql,
|
||||||
IconSquareRoundedCheck,
|
IconSquareRoundedCheck,
|
||||||
IconTable,
|
IconTable,
|
||||||
IconTag,
|
IconTag,
|
||||||
|
@ -170,8 +170,13 @@ yarn command:prod cron:calendar:google-calendar-sync
|
|||||||
### Data enrichment and AI
|
### Data enrichment and AI
|
||||||
|
|
||||||
<ArticleTable options={[
|
<ArticleTable options={[
|
||||||
['OPENROUTER_API_KEY', '', "The API key for openrouter.ai, an abstraction layer over models from Mistral, OpenAI and more"]
|
['OPENROUTER_API_KEY', '', "The API key for openrouter.ai, an abstraction layer over models from Mistral, OpenAI and more"],
|
||||||
]}></ArticleTable>
|
['OPENAI_API_KEY', 'sk-proj-abcdabcd...', "OpenAI API key"],
|
||||||
|
['LLM_CHAT_MODEL_DRIVER', 'openai', "LLM provider"],
|
||||||
|
['LLM_TRACING_DRIVER', 'langfuse', "Where to output LangChain logs. 'langfuse' or 'console'."],
|
||||||
|
['LANGFUSE_SECRET_KEY', 'sk-lf-abcdabcd-abcd...', "Langfuse secret key"],
|
||||||
|
['LANGFUSE_PUBLIC_KEY', 'pk-lf-abcdabcd-abcd...', "Langfuse public key"],
|
||||||
|
]}></ArticleTable>
|
||||||
|
|
||||||
|
|
||||||
### Support Chat
|
### Support Chat
|
||||||
|
536
yarn.lock
536
yarn.lock
@ -7695,6 +7695,95 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@langchain/core@npm:>0.1.56 <0.3.0, @langchain/core@npm:>=0.2.5 <0.3.0":
|
||||||
|
version: 0.2.6
|
||||||
|
resolution: "@langchain/core@npm:0.2.6"
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: "npm:^5.0.0"
|
||||||
|
camelcase: "npm:6"
|
||||||
|
decamelize: "npm:1.2.0"
|
||||||
|
js-tiktoken: "npm:^1.0.12"
|
||||||
|
langsmith: "npm:~0.1.30"
|
||||||
|
ml-distance: "npm:^4.0.0"
|
||||||
|
mustache: "npm:^4.2.0"
|
||||||
|
p-queue: "npm:^6.6.2"
|
||||||
|
p-retry: "npm:4"
|
||||||
|
uuid: "npm:^9.0.0"
|
||||||
|
zod: "npm:^3.22.4"
|
||||||
|
zod-to-json-schema: "npm:^3.22.3"
|
||||||
|
checksum: 4ae46528854f9dfc9e6e91c9351275cecc5cb4d246c8a2ae1326fbe046bb8637e5e26743e1ebd86f06f2ef12dc1741ea3f4480701be1e89ceecc5146b8c873b1
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@langchain/core@npm:>0.2.0 <0.3.0, @langchain/core@npm:>=0.2.8 <0.3.0, @langchain/core@npm:~0.2.0":
|
||||||
|
version: 0.2.9
|
||||||
|
resolution: "@langchain/core@npm:0.2.9"
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: "npm:^5.0.0"
|
||||||
|
camelcase: "npm:6"
|
||||||
|
decamelize: "npm:1.2.0"
|
||||||
|
js-tiktoken: "npm:^1.0.12"
|
||||||
|
langsmith: "npm:~0.1.30"
|
||||||
|
ml-distance: "npm:^4.0.0"
|
||||||
|
mustache: "npm:^4.2.0"
|
||||||
|
p-queue: "npm:^6.6.2"
|
||||||
|
p-retry: "npm:4"
|
||||||
|
uuid: "npm:^9.0.0"
|
||||||
|
zod: "npm:^3.22.4"
|
||||||
|
zod-to-json-schema: "npm:^3.22.3"
|
||||||
|
checksum: e336b2c90d4955cc522f3295b1f2b09e89b88d483108ca89af20c88ee41f815b91a307a193d0359e5012fb348022dcafa43a7ed28a195ae74ef4ec6a59678e4d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@langchain/mistralai@npm:^0.0.24":
|
||||||
|
version: 0.0.24
|
||||||
|
resolution: "@langchain/mistralai@npm:0.0.24"
|
||||||
|
dependencies:
|
||||||
|
"@langchain/core": "npm:>0.1.56 <0.3.0"
|
||||||
|
"@mistralai/mistralai": "npm:^0.4.0"
|
||||||
|
uuid: "npm:^9.0.0"
|
||||||
|
zod: "npm:^3.22.4"
|
||||||
|
zod-to-json-schema: "npm:^3.22.4"
|
||||||
|
checksum: abbc862685dfa48e9f4418ff94843b38d779514f46d5a971dc0c98b55a44d6fe91f3610432ccc0af39496ef075fbffd3e514e4104af5968938e0270e1a07716d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@langchain/openai@npm:>=0.1.0 <0.3.0":
|
||||||
|
version: 0.2.0
|
||||||
|
resolution: "@langchain/openai@npm:0.2.0"
|
||||||
|
dependencies:
|
||||||
|
"@langchain/core": "npm:>=0.2.8 <0.3.0"
|
||||||
|
js-tiktoken: "npm:^1.0.12"
|
||||||
|
openai: "npm:^4.49.1"
|
||||||
|
zod: "npm:^3.22.4"
|
||||||
|
zod-to-json-schema: "npm:^3.22.3"
|
||||||
|
checksum: a55cf7f42f4df901049b98e592bde9ee3e4a027635b07697110f511d2ccb4118ea562cd9c9d0de0e43efe291ed18425d6f6dea47447b27ba35e756c9b969fba0
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@langchain/openai@npm:^0.1.3":
|
||||||
|
version: 0.1.3
|
||||||
|
resolution: "@langchain/openai@npm:0.1.3"
|
||||||
|
dependencies:
|
||||||
|
"@langchain/core": "npm:>=0.2.5 <0.3.0"
|
||||||
|
js-tiktoken: "npm:^1.0.12"
|
||||||
|
openai: "npm:^4.49.1"
|
||||||
|
zod: "npm:^3.22.4"
|
||||||
|
zod-to-json-schema: "npm:^3.22.3"
|
||||||
|
checksum: b693bd9d5ec118136f99279c50b531865702d0fa41479cde4ced05bb20b487cc75656761e491b380e69ff191b38b8a41e4573a485b4da42f57061adb7aa692eb
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@langchain/textsplitters@npm:~0.0.0":
|
||||||
|
version: 0.0.3
|
||||||
|
resolution: "@langchain/textsplitters@npm:0.0.3"
|
||||||
|
dependencies:
|
||||||
|
"@langchain/core": "npm:>0.2.0 <0.3.0"
|
||||||
|
js-tiktoken: "npm:^1.0.12"
|
||||||
|
checksum: 3297b48f636a8a6acbd65f1465624741e6d557512ea8020a208cc6b2aa6e8d752cd08511a92ef980a06ed95858b7750a1126a4e6acfbb75fd4733e050651f405
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@leichtgewicht/ip-codec@npm:^2.0.1":
|
"@leichtgewicht/ip-codec@npm:^2.0.1":
|
||||||
version: 2.0.4
|
version: 2.0.4
|
||||||
resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
|
resolution: "@leichtgewicht/ip-codec@npm:2.0.4"
|
||||||
@ -7991,6 +8080,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@mistralai/mistralai@npm:^0.4.0":
|
||||||
|
version: 0.4.0
|
||||||
|
resolution: "@mistralai/mistralai@npm:0.4.0"
|
||||||
|
dependencies:
|
||||||
|
node-fetch: "npm:^2.6.7"
|
||||||
|
checksum: 1857ceb56f9119e8248ebb3947f8ee1da6e0731aeced38e1de44823448376ddc733182dd782e50a0e448ddd6b01789bd9dc622e0594e7a354af302a06ced77e7
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@mole-inc/bin-wrapper@npm:^8.0.1":
|
"@mole-inc/bin-wrapper@npm:^8.0.1":
|
||||||
version: 8.0.1
|
version: 8.0.1
|
||||||
resolution: "@mole-inc/bin-wrapper@npm:8.0.1"
|
resolution: "@mole-inc/bin-wrapper@npm:8.0.1"
|
||||||
@ -17632,6 +17730,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/node@npm:^18.11.18":
|
||||||
|
version: 18.19.34
|
||||||
|
resolution: "@types/node@npm:18.19.34"
|
||||||
|
dependencies:
|
||||||
|
undici-types: "npm:~5.26.4"
|
||||||
|
checksum: e985f50684def801801069e236165ee511f9195fc04ad4a2af7642d86aeaeaf7bfe34c147f894a48618a5c71c15b388ca91341a244792149543a712e38351988
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/nodemailer@npm:^6.4.14":
|
"@types/nodemailer@npm:^6.4.14":
|
||||||
version: 6.4.14
|
version: 6.4.14
|
||||||
resolution: "@types/nodemailer@npm:6.4.14"
|
resolution: "@types/nodemailer@npm:6.4.14"
|
||||||
@ -19189,6 +19296,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"abort-controller@npm:^3.0.0":
|
||||||
|
version: 3.0.0
|
||||||
|
resolution: "abort-controller@npm:3.0.0"
|
||||||
|
dependencies:
|
||||||
|
event-target-shim: "npm:^5.0.0"
|
||||||
|
checksum: 90ccc50f010250152509a344eb2e71977fbf8db0ab8f1061197e3275ddf6c61a41a6edfd7b9409c664513131dd96e962065415325ef23efa5db931b382d24ca5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"accepts@npm:^1.3.5, accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8":
|
"accepts@npm:^1.3.5, accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8":
|
||||||
version: 1.3.8
|
version: 1.3.8
|
||||||
resolution: "accepts@npm:1.3.8"
|
resolution: "accepts@npm:1.3.8"
|
||||||
@ -21513,7 +21629,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1":
|
"base64-js@npm:^1.0.2, base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1":
|
||||||
version: 1.5.1
|
version: 1.5.1
|
||||||
resolution: "base64-js@npm:1.5.1"
|
resolution: "base64-js@npm:1.5.1"
|
||||||
checksum: f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf
|
checksum: f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf
|
||||||
@ -21662,6 +21778,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"binary-extensions@npm:^2.2.0":
|
||||||
|
version: 2.3.0
|
||||||
|
resolution: "binary-extensions@npm:2.3.0"
|
||||||
|
checksum: 75a59cafc10fb12a11d510e77110c6c7ae3f4ca22463d52487709ca7f18f69d886aa387557cc9864fbdb10153d0bdb4caacabf11541f55e89ed6e18d12ece2b5
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"binary-search@npm:^1.3.5":
|
||||||
|
version: 1.3.6
|
||||||
|
resolution: "binary-search@npm:1.3.6"
|
||||||
|
checksum: 786a770e3411cf563c9c7829e2854d79583a207b8faaa5022f93352893e1d06035ae5d80de1b168dcbd9d346fdb0dd2e3d7fcdf309b3a63dc027e92624da32a0
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"binaryextensions@npm:^4.15.0, binaryextensions@npm:^4.16.0":
|
"binaryextensions@npm:^4.15.0, binaryextensions@npm:^4.16.0":
|
||||||
version: 4.19.0
|
version: 4.19.0
|
||||||
resolution: "binaryextensions@npm:4.19.0"
|
resolution: "binaryextensions@npm:4.19.0"
|
||||||
@ -22494,6 +22624,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"camelcase@npm:6, camelcase@npm:^6.2.0":
|
||||||
|
version: 6.3.0
|
||||||
|
resolution: "camelcase@npm:6.3.0"
|
||||||
|
checksum: 0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1":
|
"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1":
|
||||||
version: 5.3.1
|
version: 5.3.1
|
||||||
resolution: "camelcase@npm:5.3.1"
|
resolution: "camelcase@npm:5.3.1"
|
||||||
@ -22501,13 +22638,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"camelcase@npm:^6.2.0":
|
|
||||||
version: 6.3.0
|
|
||||||
resolution: "camelcase@npm:6.3.0"
|
|
||||||
checksum: 0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"camelcase@npm:^7.0.1":
|
"camelcase@npm:^7.0.1":
|
||||||
version: 7.0.1
|
version: 7.0.1
|
||||||
resolution: "camelcase@npm:7.0.1"
|
resolution: "camelcase@npm:7.0.1"
|
||||||
@ -23577,7 +23707,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"commander@npm:^10.0.0":
|
"commander@npm:^10.0.0, commander@npm:^10.0.1":
|
||||||
version: 10.0.1
|
version: 10.0.1
|
||||||
resolution: "commander@npm:10.0.1"
|
resolution: "commander@npm:10.0.1"
|
||||||
checksum: 53f33d8927758a911094adadda4b2cbac111a5b377d8706700587650fd8f45b0bbe336de4b5c3fe47fd61f420a3d9bd452b6e0e6e5600a7e74d7bf0174f6efe3
|
checksum: 53f33d8927758a911094adadda4b2cbac111a5b377d8706700587650fd8f45b0bbe336de4b5c3fe47fd61f420a3d9bd452b6e0e6e5600a7e74d7bf0174f6efe3
|
||||||
@ -25100,7 +25230,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"decamelize@npm:^1.2.0":
|
"decamelize@npm:1.2.0, decamelize@npm:^1.2.0":
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
resolution: "decamelize@npm:1.2.0"
|
resolution: "decamelize@npm:1.2.0"
|
||||||
checksum: 85c39fe8fbf0482d4a1e224ef0119db5c1897f8503bcef8b826adff7a1b11414972f6fef2d7dec2ee0b4be3863cf64ac1439137ae9e6af23a3d8dcbe26a5b4b2
|
checksum: 85c39fe8fbf0482d4a1e224ef0119db5c1897f8503bcef8b826adff7a1b11414972f6fef2d7dec2ee0b4be3863cf64ac1439137ae9e6af23a3d8dcbe26a5b4b2
|
||||||
@ -27557,6 +27687,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"event-target-shim@npm:^5.0.0":
|
||||||
|
version: 5.0.1
|
||||||
|
resolution: "event-target-shim@npm:5.0.1"
|
||||||
|
checksum: 0255d9f936215fd206156fd4caa9e8d35e62075d720dc7d847e89b417e5e62cf1ce6c9b4e0a1633a9256de0efefaf9f8d26924b1f3c8620cffb9db78e7d3076b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"eventemitter2@npm:6.4.9":
|
"eventemitter2@npm:6.4.9":
|
||||||
version: 6.4.9
|
version: 6.4.9
|
||||||
resolution: "eventemitter2@npm:6.4.9"
|
resolution: "eventemitter2@npm:6.4.9"
|
||||||
@ -28657,6 +28794,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"form-data-encoder@npm:1.7.2":
|
||||||
|
version: 1.7.2
|
||||||
|
resolution: "form-data-encoder@npm:1.7.2"
|
||||||
|
checksum: 56553768037b6d55d9de524f97fe70555f0e415e781cb56fc457a68263de3d40fadea2304d4beef2d40b1a851269bd7854e42c362107071892cb5238debe9464
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"form-data-encoder@npm:^2.1.2":
|
"form-data-encoder@npm:^2.1.2":
|
||||||
version: 2.1.4
|
version: 2.1.4
|
||||||
resolution: "form-data-encoder@npm:2.1.4"
|
resolution: "form-data-encoder@npm:2.1.4"
|
||||||
@ -28693,7 +28837,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"formdata-node@npm:^4.4.1":
|
"formdata-node@npm:^4.3.2, formdata-node@npm:^4.4.1":
|
||||||
version: 4.4.1
|
version: 4.4.1
|
||||||
resolution: "formdata-node@npm:4.4.1"
|
resolution: "formdata-node@npm:4.4.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -31807,6 +31951,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"is-any-array@npm:^2.0.0":
|
||||||
|
version: 2.0.1
|
||||||
|
resolution: "is-any-array@npm:2.0.1"
|
||||||
|
checksum: f9807458a51e63ca1ac27fd6f3a3ace8200f077094e00d9b05b24cfbc9d5594d586d6ecf3416271f26939d5cb93fc52ca869cb5744e77318c3f53ec70b08d61f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1":
|
"is-arguments@npm:^1.0.4, is-arguments@npm:^1.1.1":
|
||||||
version: 1.1.1
|
version: 1.1.1
|
||||||
resolution: "is-arguments@npm:1.1.1"
|
resolution: "is-arguments@npm:1.1.1"
|
||||||
@ -33556,6 +33707,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"js-tiktoken@npm:^1.0.12":
|
||||||
|
version: 1.0.12
|
||||||
|
resolution: "js-tiktoken@npm:1.0.12"
|
||||||
|
dependencies:
|
||||||
|
base64-js: "npm:^1.5.1"
|
||||||
|
checksum: 7afb4826e21342386a1884754fbc1c1828f948c4dd0ab093bf778d1323e65343bd5343d15f7cda46af396f1fe4a0297739936149b7c40a0601eefe3fcaef8727
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
|
"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
resolution: "js-tokens@npm:4.0.0"
|
resolution: "js-tokens@npm:4.0.0"
|
||||||
@ -34032,7 +34192,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"jsonpointer@npm:^5.0.0":
|
"jsonpointer@npm:^5.0.0, jsonpointer@npm:^5.0.1":
|
||||||
version: 5.0.1
|
version: 5.0.1
|
||||||
resolution: "jsonpointer@npm:5.0.1"
|
resolution: "jsonpointer@npm:5.0.1"
|
||||||
checksum: 89929e58b400fcb96928c0504fcf4fc3f919d81e9543ceb055df125538470ee25290bb4984251e172e6ef8fcc55761eb998c118da763a82051ad89d4cb073fe7
|
checksum: 89929e58b400fcb96928c0504fcf4fc3f919d81e9543ceb055df125538470ee25290bb4984251e172e6ef8fcc55761eb998c118da763a82051ad89d4cb073fe7
|
||||||
@ -34232,6 +34392,242 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"langchain@npm:^0.2.6":
|
||||||
|
version: 0.2.6
|
||||||
|
resolution: "langchain@npm:0.2.6"
|
||||||
|
dependencies:
|
||||||
|
"@langchain/core": "npm:~0.2.0"
|
||||||
|
"@langchain/openai": "npm:>=0.1.0 <0.3.0"
|
||||||
|
"@langchain/textsplitters": "npm:~0.0.0"
|
||||||
|
binary-extensions: "npm:^2.2.0"
|
||||||
|
js-tiktoken: "npm:^1.0.12"
|
||||||
|
js-yaml: "npm:^4.1.0"
|
||||||
|
jsonpointer: "npm:^5.0.1"
|
||||||
|
langchainhub: "npm:~0.0.8"
|
||||||
|
langsmith: "npm:~0.1.30"
|
||||||
|
ml-distance: "npm:^4.0.0"
|
||||||
|
openapi-types: "npm:^12.1.3"
|
||||||
|
p-retry: "npm:4"
|
||||||
|
uuid: "npm:^9.0.0"
|
||||||
|
yaml: "npm:^2.2.1"
|
||||||
|
zod: "npm:^3.22.4"
|
||||||
|
zod-to-json-schema: "npm:^3.22.3"
|
||||||
|
peerDependencies:
|
||||||
|
"@aws-sdk/client-s3": ^3.310.0
|
||||||
|
"@aws-sdk/client-sagemaker-runtime": ^3.310.0
|
||||||
|
"@aws-sdk/client-sfn": ^3.310.0
|
||||||
|
"@aws-sdk/credential-provider-node": ^3.388.0
|
||||||
|
"@azure/storage-blob": ^12.15.0
|
||||||
|
"@browserbasehq/sdk": "*"
|
||||||
|
"@gomomento/sdk": ^1.51.1
|
||||||
|
"@gomomento/sdk-core": ^1.51.1
|
||||||
|
"@gomomento/sdk-web": ^1.51.1
|
||||||
|
"@mendable/firecrawl-js": ^0.0.13
|
||||||
|
"@notionhq/client": ^2.2.10
|
||||||
|
"@pinecone-database/pinecone": "*"
|
||||||
|
"@supabase/supabase-js": ^2.10.0
|
||||||
|
"@vercel/kv": ^0.2.3
|
||||||
|
"@xata.io/client": ^0.28.0
|
||||||
|
apify-client: ^2.7.1
|
||||||
|
assemblyai: ^4.0.0
|
||||||
|
axios: "*"
|
||||||
|
cheerio: ^1.0.0-rc.12
|
||||||
|
chromadb: "*"
|
||||||
|
convex: ^1.3.1
|
||||||
|
couchbase: ^4.3.0
|
||||||
|
d3-dsv: ^2.0.0
|
||||||
|
epub2: ^3.0.1
|
||||||
|
fast-xml-parser: "*"
|
||||||
|
handlebars: ^4.7.8
|
||||||
|
html-to-text: ^9.0.5
|
||||||
|
ignore: ^5.2.0
|
||||||
|
ioredis: ^5.3.2
|
||||||
|
jsdom: "*"
|
||||||
|
mammoth: ^1.6.0
|
||||||
|
mongodb: ">=5.2.0"
|
||||||
|
node-llama-cpp: "*"
|
||||||
|
notion-to-md: ^3.1.0
|
||||||
|
officeparser: ^4.0.4
|
||||||
|
pdf-parse: 1.1.1
|
||||||
|
peggy: ^3.0.2
|
||||||
|
playwright: ^1.32.1
|
||||||
|
puppeteer: ^19.7.2
|
||||||
|
pyodide: ^0.24.1
|
||||||
|
redis: ^4.6.4
|
||||||
|
sonix-speech-recognition: ^2.1.1
|
||||||
|
srt-parser-2: ^1.2.3
|
||||||
|
typeorm: ^0.3.20
|
||||||
|
weaviate-ts-client: "*"
|
||||||
|
web-auth-library: ^1.0.3
|
||||||
|
ws: ^8.14.2
|
||||||
|
youtube-transcript: ^1.0.6
|
||||||
|
youtubei.js: ^9.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
"@aws-sdk/client-s3":
|
||||||
|
optional: true
|
||||||
|
"@aws-sdk/client-sagemaker-runtime":
|
||||||
|
optional: true
|
||||||
|
"@aws-sdk/client-sfn":
|
||||||
|
optional: true
|
||||||
|
"@aws-sdk/credential-provider-node":
|
||||||
|
optional: true
|
||||||
|
"@azure/storage-blob":
|
||||||
|
optional: true
|
||||||
|
"@browserbasehq/sdk":
|
||||||
|
optional: true
|
||||||
|
"@gomomento/sdk":
|
||||||
|
optional: true
|
||||||
|
"@gomomento/sdk-core":
|
||||||
|
optional: true
|
||||||
|
"@gomomento/sdk-web":
|
||||||
|
optional: true
|
||||||
|
"@mendable/firecrawl-js":
|
||||||
|
optional: true
|
||||||
|
"@notionhq/client":
|
||||||
|
optional: true
|
||||||
|
"@pinecone-database/pinecone":
|
||||||
|
optional: true
|
||||||
|
"@supabase/supabase-js":
|
||||||
|
optional: true
|
||||||
|
"@vercel/kv":
|
||||||
|
optional: true
|
||||||
|
"@xata.io/client":
|
||||||
|
optional: true
|
||||||
|
apify-client:
|
||||||
|
optional: true
|
||||||
|
assemblyai:
|
||||||
|
optional: true
|
||||||
|
axios:
|
||||||
|
optional: true
|
||||||
|
cheerio:
|
||||||
|
optional: true
|
||||||
|
chromadb:
|
||||||
|
optional: true
|
||||||
|
convex:
|
||||||
|
optional: true
|
||||||
|
couchbase:
|
||||||
|
optional: true
|
||||||
|
d3-dsv:
|
||||||
|
optional: true
|
||||||
|
epub2:
|
||||||
|
optional: true
|
||||||
|
faiss-node:
|
||||||
|
optional: true
|
||||||
|
fast-xml-parser:
|
||||||
|
optional: true
|
||||||
|
handlebars:
|
||||||
|
optional: true
|
||||||
|
html-to-text:
|
||||||
|
optional: true
|
||||||
|
ignore:
|
||||||
|
optional: true
|
||||||
|
ioredis:
|
||||||
|
optional: true
|
||||||
|
jsdom:
|
||||||
|
optional: true
|
||||||
|
mammoth:
|
||||||
|
optional: true
|
||||||
|
mongodb:
|
||||||
|
optional: true
|
||||||
|
node-llama-cpp:
|
||||||
|
optional: true
|
||||||
|
notion-to-md:
|
||||||
|
optional: true
|
||||||
|
officeparser:
|
||||||
|
optional: true
|
||||||
|
pdf-parse:
|
||||||
|
optional: true
|
||||||
|
peggy:
|
||||||
|
optional: true
|
||||||
|
playwright:
|
||||||
|
optional: true
|
||||||
|
puppeteer:
|
||||||
|
optional: true
|
||||||
|
pyodide:
|
||||||
|
optional: true
|
||||||
|
redis:
|
||||||
|
optional: true
|
||||||
|
sonix-speech-recognition:
|
||||||
|
optional: true
|
||||||
|
srt-parser-2:
|
||||||
|
optional: true
|
||||||
|
typeorm:
|
||||||
|
optional: true
|
||||||
|
weaviate-ts-client:
|
||||||
|
optional: true
|
||||||
|
web-auth-library:
|
||||||
|
optional: true
|
||||||
|
ws:
|
||||||
|
optional: true
|
||||||
|
youtube-transcript:
|
||||||
|
optional: true
|
||||||
|
youtubei.js:
|
||||||
|
optional: true
|
||||||
|
checksum: c267d618f20b75eeba0c13b3ee9aaa8e7a57d87d64344c4360d7332bdda82c6976c80c705a81a0be02006f350b2f42142ca98a7b71148ee0aa934a592ddbc47a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"langchainhub@npm:~0.0.8":
|
||||||
|
version: 0.0.11
|
||||||
|
resolution: "langchainhub@npm:0.0.11"
|
||||||
|
checksum: 6ed781b9e8165bfb5cedc822a25bc70df0f3fc02662061d19a5e2044243cfae797857a05d139de8f326539b1f3fe03f2662060eed82669e405181f1f0f435c47
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"langfuse-core@npm:^3.11.2":
|
||||||
|
version: 3.11.2
|
||||||
|
resolution: "langfuse-core@npm:3.11.2"
|
||||||
|
dependencies:
|
||||||
|
mustache: "npm:^4.2.0"
|
||||||
|
checksum: 341cddedf16cf0c4b980989c4ee4daa6be0dad7a37349d86ff7b3fcf4e2e35e25318fb9ec6e4c9d27023031c7e780d50d75493f7cf9911938b6581ee2c1728c6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"langfuse-langchain@npm:^3.11.2":
|
||||||
|
version: 3.11.2
|
||||||
|
resolution: "langfuse-langchain@npm:3.11.2"
|
||||||
|
dependencies:
|
||||||
|
langfuse: "npm:^3.11.2"
|
||||||
|
langfuse-core: "npm:^3.11.2"
|
||||||
|
peerDependencies:
|
||||||
|
langchain: ">=0.0.157 <0.3.0"
|
||||||
|
checksum: ec57481128b4b738ee4e146b0f0c42e94d0f75d5a525a031407d7ecd8ffcd50dc9730f580901ed2432694555e544459e032e9181af9d853a156aef42c3ef9b41
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"langfuse@npm:^3.11.2":
|
||||||
|
version: 3.11.2
|
||||||
|
resolution: "langfuse@npm:3.11.2"
|
||||||
|
dependencies:
|
||||||
|
langfuse-core: "npm:^3.11.2"
|
||||||
|
checksum: e74053aa5bb3e62a91d3c7a5f95c86f9808342ca9a0dcda5c5a33bf8abf8ace70357f84db7fae36e93d722e9aa383b55ced785e6d6cbf23d47d0252b1fef57b0
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"langsmith@npm:~0.1.30":
|
||||||
|
version: 0.1.30
|
||||||
|
resolution: "langsmith@npm:0.1.30"
|
||||||
|
dependencies:
|
||||||
|
"@types/uuid": "npm:^9.0.1"
|
||||||
|
commander: "npm:^10.0.1"
|
||||||
|
p-queue: "npm:^6.6.2"
|
||||||
|
p-retry: "npm:4"
|
||||||
|
uuid: "npm:^9.0.0"
|
||||||
|
peerDependencies:
|
||||||
|
"@langchain/core": "*"
|
||||||
|
langchain: "*"
|
||||||
|
openai: "*"
|
||||||
|
peerDependenciesMeta:
|
||||||
|
"@langchain/core":
|
||||||
|
optional: true
|
||||||
|
langchain:
|
||||||
|
optional: true
|
||||||
|
openai:
|
||||||
|
optional: true
|
||||||
|
checksum: 181719d73bd89918f0ab60768f824449e2bfd5a691242c3540291114053ba6e49ce4670bfa0abd129dd7556f80b3025371ba9cd1884090dc1941fdf39850545c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"language-subtag-registry@npm:^0.3.20":
|
"language-subtag-registry@npm:^0.3.20":
|
||||||
version: 0.3.22
|
version: 0.3.22
|
||||||
resolution: "language-subtag-registry@npm:0.3.22"
|
resolution: "language-subtag-registry@npm:0.3.22"
|
||||||
@ -37622,6 +38018,52 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"ml-array-mean@npm:^1.1.6":
|
||||||
|
version: 1.1.6
|
||||||
|
resolution: "ml-array-mean@npm:1.1.6"
|
||||||
|
dependencies:
|
||||||
|
ml-array-sum: "npm:^1.1.6"
|
||||||
|
checksum: 41ab68308e3472702f775a49c8ab9ee1e678e01cd59dbc59424c0f1017a37df1bb638e702831305f0e6366300eca48353f526773ab8f4d8d142a64d0461f9944
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"ml-array-sum@npm:^1.1.6":
|
||||||
|
version: 1.1.6
|
||||||
|
resolution: "ml-array-sum@npm:1.1.6"
|
||||||
|
dependencies:
|
||||||
|
is-any-array: "npm:^2.0.0"
|
||||||
|
checksum: fb3973ce2bfa19ab4f5e657f722494425b57025547657d332bf5bafe3e4e7e4bd1e082dfb970bcc0bfa87efa345b80a20a596dbb204be7b4802b52c35fd6cf77
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"ml-distance-euclidean@npm:^2.0.0":
|
||||||
|
version: 2.0.0
|
||||||
|
resolution: "ml-distance-euclidean@npm:2.0.0"
|
||||||
|
checksum: 877aef472e134f79be9540b02f889b2a27976ca45d77f5d4ef7d8dd24058a60cf4637365b40a5aba1ab5490348a0fb1b3803143b25af88cdc66137fbfd665442
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"ml-distance@npm:^4.0.0":
|
||||||
|
version: 4.0.1
|
||||||
|
resolution: "ml-distance@npm:4.0.1"
|
||||||
|
dependencies:
|
||||||
|
ml-array-mean: "npm:^1.1.6"
|
||||||
|
ml-distance-euclidean: "npm:^2.0.0"
|
||||||
|
ml-tree-similarity: "npm:^1.0.0"
|
||||||
|
checksum: 8c2eb077d2ba61437f2414f3b9ca1091c43fcabe2282ecc31d8ebf9e083c1df068e43c67f59a4674e7c8f473201ace4f02779b446427d6169a5d669cae94c816
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"ml-tree-similarity@npm:^1.0.0":
|
||||||
|
version: 1.0.0
|
||||||
|
resolution: "ml-tree-similarity@npm:1.0.0"
|
||||||
|
dependencies:
|
||||||
|
binary-search: "npm:^1.3.5"
|
||||||
|
num-sort: "npm:^2.0.0"
|
||||||
|
checksum: e3ecd07bead5d18bc7b6fed1dfefbe65aea4008d5556181b94b7d70550fba543d2501b224f12a9f5197c1d23d95faef2accc7fd265c5afd15ef55a38190ffc6e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"mlly@npm:^1.2.0, mlly@npm:^1.4.2":
|
"mlly@npm:^1.2.0, mlly@npm:^1.4.2":
|
||||||
version: 1.6.1
|
version: 1.6.1
|
||||||
resolution: "mlly@npm:1.6.1"
|
resolution: "mlly@npm:1.6.1"
|
||||||
@ -37848,6 +38290,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"mustache@npm:^4.2.0":
|
||||||
|
version: 4.2.0
|
||||||
|
resolution: "mustache@npm:4.2.0"
|
||||||
|
bin:
|
||||||
|
mustache: bin/mustache
|
||||||
|
checksum: 1f8197e8a19e63645a786581d58c41df7853da26702dbc005193e2437c98ca49b255345c173d50c08fe4b4dbb363e53cb655ecc570791f8deb09887248dd34a2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"mute-stream@npm:0.0.8":
|
"mute-stream@npm:0.0.8":
|
||||||
version: 0.0.8
|
version: 0.0.8
|
||||||
resolution: "mute-stream@npm:0.0.8"
|
resolution: "mute-stream@npm:0.0.8"
|
||||||
@ -38715,6 +39166,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"num-sort@npm:^2.0.0":
|
||||||
|
version: 2.1.0
|
||||||
|
resolution: "num-sort@npm:2.1.0"
|
||||||
|
checksum: cc1d43adbc9adfd5d208a8eb653827277376ff2e6eb75379f96e6a23d481040e317e63505e075b84ce49e19b9d960570646096428a715d12c5ef1381504d5135
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"number-is-nan@npm:^1.0.0":
|
"number-is-nan@npm:^1.0.0":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "number-is-nan@npm:1.0.1"
|
resolution: "number-is-nan@npm:1.0.1"
|
||||||
@ -39107,6 +39565,24 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"openai@npm:^4.49.1":
|
||||||
|
version: 4.51.0
|
||||||
|
resolution: "openai@npm:4.51.0"
|
||||||
|
dependencies:
|
||||||
|
"@types/node": "npm:^18.11.18"
|
||||||
|
"@types/node-fetch": "npm:^2.6.4"
|
||||||
|
abort-controller: "npm:^3.0.0"
|
||||||
|
agentkeepalive: "npm:^4.2.1"
|
||||||
|
form-data-encoder: "npm:1.7.2"
|
||||||
|
formdata-node: "npm:^4.3.2"
|
||||||
|
node-fetch: "npm:^2.6.7"
|
||||||
|
web-streams-polyfill: "npm:^3.2.1"
|
||||||
|
bin:
|
||||||
|
openai: bin/cli
|
||||||
|
checksum: c9adcca092aa528fe3556d9e91e022f67515e76c31ee6899d781b5bf17fbfd783e7aca15da4b6dca4bed53d12da021973789f5ae584d2769c5c560976939c45b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"openapi-types@npm:^12.1.3":
|
"openapi-types@npm:^12.1.3":
|
||||||
version: 12.1.3
|
version: 12.1.3
|
||||||
resolution: "openapi-types@npm:12.1.3"
|
resolution: "openapi-types@npm:12.1.3"
|
||||||
@ -39421,7 +39897,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"p-retry@npm:^4.5.0":
|
"p-retry@npm:4, p-retry@npm:^4.5.0":
|
||||||
version: 4.6.2
|
version: 4.6.2
|
||||||
resolution: "p-retry@npm:4.6.2"
|
resolution: "p-retry@npm:4.6.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -47183,6 +47659,8 @@ __metadata:
|
|||||||
resolution: "twenty-server@workspace:packages/twenty-server"
|
resolution: "twenty-server@workspace:packages/twenty-server"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga-nestjs-npm-2.1.0-cb509e6047.patch"
|
"@graphql-yoga/nestjs": "patch:@graphql-yoga/nestjs@2.1.0#./patches/@graphql-yoga-nestjs-npm-2.1.0-cb509e6047.patch"
|
||||||
|
"@langchain/mistralai": "npm:^0.0.24"
|
||||||
|
"@langchain/openai": "npm:^0.1.3"
|
||||||
"@nestjs/cache-manager": "npm:^2.2.1"
|
"@nestjs/cache-manager": "npm:^2.2.1"
|
||||||
"@nestjs/cli": "npm:10.3.0"
|
"@nestjs/cli": "npm:10.3.0"
|
||||||
"@nestjs/devtools-integration": "npm:^0.1.6"
|
"@nestjs/devtools-integration": "npm:^0.1.6"
|
||||||
@ -47206,6 +47684,8 @@ __metadata:
|
|||||||
graphql-middleware: "npm:^6.1.35"
|
graphql-middleware: "npm:^6.1.35"
|
||||||
jsdom: "npm:~22.1.0"
|
jsdom: "npm:~22.1.0"
|
||||||
jwt-decode: "npm:^4.0.0"
|
jwt-decode: "npm:^4.0.0"
|
||||||
|
langchain: "npm:^0.2.6"
|
||||||
|
langfuse-langchain: "npm:^3.11.2"
|
||||||
lodash.differencewith: "npm:^4.5.0"
|
lodash.differencewith: "npm:^4.5.0"
|
||||||
lodash.omitby: "npm:^4.6.0"
|
lodash.omitby: "npm:^4.6.0"
|
||||||
lodash.uniq: "npm:^4.5.0"
|
lodash.uniq: "npm:^4.5.0"
|
||||||
@ -47215,6 +47695,7 @@ __metadata:
|
|||||||
rimraf: "npm:^5.0.5"
|
rimraf: "npm:^5.0.5"
|
||||||
tsconfig-paths: "npm:^4.2.0"
|
tsconfig-paths: "npm:^4.2.0"
|
||||||
typescript: "npm:5.3.3"
|
typescript: "npm:5.3.3"
|
||||||
|
zod-to-json-schema: "npm:^3.23.1"
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
@ -50324,6 +50805,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"yaml@npm:^2.2.1":
|
||||||
|
version: 2.4.5
|
||||||
|
resolution: "yaml@npm:2.4.5"
|
||||||
|
bin:
|
||||||
|
yaml: bin.mjs
|
||||||
|
checksum: e1ee78b381e5c710f715cc4082fd10fc82f7f5c92bd6f075771d20559e175616f56abf1c411f545ea0e9e16e4f84a83a50b42764af5f16ec006328ba9476bb31
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"yaml@npm:^2.2.2, yaml@npm:^2.3.4":
|
"yaml@npm:^2.2.2, yaml@npm:^2.3.4":
|
||||||
version: 2.3.4
|
version: 2.3.4
|
||||||
resolution: "yaml@npm:2.3.4"
|
resolution: "yaml@npm:2.3.4"
|
||||||
@ -50656,7 +51146,25 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"zod@npm:3.23.8":
|
"zod-to-json-schema@npm:^3.22.3, zod-to-json-schema@npm:^3.22.4":
|
||||||
|
version: 3.23.0
|
||||||
|
resolution: "zod-to-json-schema@npm:3.23.0"
|
||||||
|
peerDependencies:
|
||||||
|
zod: ^3.23.3
|
||||||
|
checksum: bcd966fa040765d7170a89c0c5f1717575e7d8823b84cbbb606689d494ae308c9eaadd4b71a74752e3170deef64c1f1bb2985f4663c44a0ed2e7854ff6fda724
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"zod-to-json-schema@npm:^3.23.1":
|
||||||
|
version: 3.23.1
|
||||||
|
resolution: "zod-to-json-schema@npm:3.23.1"
|
||||||
|
peerDependencies:
|
||||||
|
zod: ^3.23.3
|
||||||
|
checksum: d48d733f7cba9fdc631ebe3dada3f48b820a16e49f7ded9f363cccafa42461ff95cc7afcf974c27af7cd6d5fa5191212bb7ec15ec203bcb61f829a6d0d3e192f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"zod@npm:3.23.8, zod@npm:^3.22.4":
|
||||||
version: 3.23.8
|
version: 3.23.8
|
||||||
resolution: "zod@npm:3.23.8"
|
resolution: "zod@npm:3.23.8"
|
||||||
checksum: 8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69
|
checksum: 8f14c87d6b1b53c944c25ce7a28616896319d95bc46a9660fe441adc0ed0a81253b02b5abdaeffedbeb23bdd25a0bf1c29d2c12dd919aef6447652dd295e3e69
|
||||||
|
Loading…
Reference in New Issue
Block a user