Skip to content

Commit

Permalink
feat: add assistants
Browse files Browse the repository at this point in the history
  • Loading branch information
marian2js committed Dec 13, 2023
1 parent b7a1a51 commit 0ae7fb2
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 38 deletions.
10 changes: 10 additions & 0 deletions apps/api/src/chat/chat.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ import { ChatbotConsumer } from '../workflow-triggers/services/chatbot.consumer'
import { WorkflowTriggersModule } from '../workflow-triggers/workflow-triggers.module'
import { WorkflowsModule } from '../workflows/workflows.module'
import { ContactSubscriptionController } from './controllers/contact-subscription.controller'
import { Assistant, AssistantAuthorizer } from './entities/assistant'
import { Campaign, CampaignAuthorizer } from './entities/campaign'
import { CampaignMessage } from './entities/campaign-message'
import { Contact, ContactAuthorizer } from './entities/contact'
import { Menu, MenuAuthorizer } from './entities/menu'
import { Order, OrderAuthorizer } from './entities/order'
import { AssistantResolver } from './resolvers/assistant.resolver'
import { CampaignResolver } from './resolvers/campaign.resolver'
import { ContactResolver } from './resolvers/contact.resolver'
import { MenuResolver } from './resolvers/menu.resolver'
import { OrderResolver } from './resolvers/order.resolver'
import { AssistantService } from './services/assistant.service'
import { BroadcastConsumer } from './services/broadcast.consumer'
import { CampaignMessageService } from './services/campaign-message.service'
import { CampaignService } from './services/campaign.service'
Expand Down Expand Up @@ -55,6 +58,10 @@ import { OrderService } from './services/order.service'
imports: [NestjsQueryTypegooseModule.forFeature([Order])],
dtos: [{ DTOClass: Order }],
}),
NestjsQueryGraphQLModule.forFeature({
imports: [NestjsQueryTypegooseModule.forFeature([Assistant])],
dtos: [{ DTOClass: Assistant }],
}),
BullModule.registerQueue({
name: 'chatbotMessage',
settings: {
Expand Down Expand Up @@ -106,19 +113,22 @@ import { OrderService } from './services/order.service'
CampaignResolver,
MenuResolver,
OrderResolver,
AssistantResolver,

// Services
ContactService,
CampaignService,
CampaignMessageService,
MenuService,
OrderService,
AssistantService,

// Authorizers
ContactAuthorizer,
CampaignAuthorizer,
MenuAuthorizer,
OrderAuthorizer,
AssistantAuthorizer,

// Consumers
ChatbotConsumer,
Expand Down
45 changes: 45 additions & 0 deletions apps/api/src/chat/entities/assistant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { BaseEntity } from '@app/common/base/base-entity'
import { OwnedAuthorizer } from '@app/common/base/owned.authorizer'
import { OwnedEntity } from '@app/common/decorators/owned-entity.decorator'
import { Reference } from '@app/common/typings/mongodb'
import { Injectable } from '@nestjs/common'
import { Field, InputType, ObjectType } from '@nestjs/graphql'
import { Authorize } from '@ptc-org/nestjs-query-graphql'
import { prop } from '@typegoose/typegoose'
import { User } from '../../users/entities/user'

@Injectable()
export class AssistantAuthorizer extends OwnedAuthorizer<Assistant> {}

@ObjectType()
@OwnedEntity()
@Authorize<Assistant>(AssistantAuthorizer)
export class Assistant extends BaseEntity {
@prop({ ref: User, required: true })
readonly owner!: Reference<User>

@Field()
@prop({ required: true })
instructions: string

@Field({ nullable: true })
enabled?: boolean
}

@InputType()
export class CreateAssistantInput {
@Field()
instructions: string

@Field({ nullable: true })
enabled?: boolean
}

@InputType()
export class UpdateAssistantInput {
@Field({ nullable: true })
instructions: string

@Field({ nullable: true })
enabled?: boolean
}
23 changes: 23 additions & 0 deletions apps/api/src/chat/resolvers/assistant.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { BaseResolver } from '@app/common/base/base.resolver'
import { UseGuards, UseInterceptors } from '@nestjs/common'
import { Resolver } from '@nestjs/graphql'
import { Authorizer, AuthorizerInterceptor, InjectAuthorizer } from '@ptc-org/nestjs-query-graphql'
import { GraphqlGuard } from '../../auth/guards/graphql.guard'
import { Assistant, CreateAssistantInput, UpdateAssistantInput } from '../entities/assistant'
import { AssistantService } from '../services/assistant.service'

@Resolver(() => Assistant)
@UseGuards(GraphqlGuard)
@UseInterceptors(AuthorizerInterceptor(Assistant))
export class AssistantResolver extends BaseResolver(Assistant, {
CreateDTOClass: CreateAssistantInput,
UpdateDTOClass: UpdateAssistantInput,
guards: [GraphqlGuard],
}) {
constructor(
protected assistantService: AssistantService,
@InjectAuthorizer(Assistant) readonly authorizer: Authorizer<Assistant>,
) {
super(assistantService)
}
}
16 changes: 16 additions & 0 deletions apps/api/src/chat/services/assistant.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { BaseService } from '@app/common/base/base.service'
import { Injectable, Logger } from '@nestjs/common'
import { ReturnModelType } from '@typegoose/typegoose'
import { InjectModel } from 'nestjs-typegoose'
import { Assistant } from '../entities/assistant'

@Injectable()
export class AssistantService extends BaseService<Assistant> {
protected readonly logger = new Logger(AssistantService.name)
static instance: AssistantService

constructor(@InjectModel(Assistant) protected readonly model: ReturnModelType<typeof Assistant>) {
super(model)
AssistantService.instance = this
}
}
4 changes: 2 additions & 2 deletions apps/runner/src/services/operation-runner.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { UserEventService } from '@app/common/metrics/user-event.service'
import { convertObservableToRunResponse, wait } from '@app/common/utils/async.utils'
import { OperationTrigger } from '@app/definitions/operation-trigger'
import { OperationType } from '@app/definitions/types/OperationType'
import { Inject, Injectable, InternalServerErrorException, Logger, NotFoundException, forwardRef } from '@nestjs/common'
import { forwardRef, Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'
import { PlanConfig } from 'apps/api/src/users/config/plans.config'
import { WorkflowAction } from 'apps/api/src/workflow-actions/entities/workflow-action'
import { WorkflowTrigger } from 'apps/api/src/workflow-triggers/entities/workflow-trigger'
Expand Down Expand Up @@ -130,7 +130,7 @@ export class OperationRunnerService {
}

const limits = definition.limits(opts)
if (limits?.daily && opts.user) {
if (limits?.daily && opts.user && opts.user.planConfig.key === 'free') {
const usedToday = await this.userEventService.findOne({
user: opts.user.id,
key: `run-${opts.operation._id.toString()}`,
Expand Down
83 changes: 66 additions & 17 deletions generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ export enum OrderSortFields {
address = "address"
}

export enum AssistantSortFields {
id = "id",
createdAt = "createdAt"
}

export enum UserDatabaseSortFields {
id = "id",
createdAt = "createdAt"
Expand Down Expand Up @@ -574,6 +579,19 @@ export interface OrderSort {
nulls?: Nullable<SortNulls>;
}

export interface AssistantFilter {
and?: Nullable<AssistantFilter[]>;
or?: Nullable<AssistantFilter[]>;
id?: Nullable<IDFilterComparison>;
createdAt?: Nullable<DateFieldComparison>;
}

export interface AssistantSort {
field: AssistantSortFields;
direction: SortDirection;
nulls?: Nullable<SortNulls>;
}

export interface UserDatabaseFilter {
and?: Nullable<UserDatabaseFilter[]>;
or?: Nullable<UserDatabaseFilter[]>;
Expand Down Expand Up @@ -760,18 +778,6 @@ export interface DeleteOneContactInput {
id: string;
}

export interface DeleteManyContactsInput {
filter: ContactDeleteFilter;
}

export interface ContactDeleteFilter {
and?: Nullable<ContactDeleteFilter[]>;
or?: Nullable<ContactDeleteFilter[]>;
id?: Nullable<IDFilterComparison>;
createdAt?: Nullable<DateFieldComparison>;
address?: Nullable<StringFieldComparison>;
}

export interface CreateOneCampaignInput {
campaign: CreateCampaignInput;
}
Expand Down Expand Up @@ -876,6 +882,27 @@ export interface DeleteOneOrderInput {
id: string;
}

export interface CreateOneAssistantInput {
assistant: CreateAssistantInput;
}

export interface CreateAssistantInput {
instructions: string;
}

export interface UpdateOneAssistantInput {
id: string;
update: UpdateAssistantInput;
}

export interface UpdateAssistantInput {
instructions?: Nullable<string>;
}

export interface DeleteOneAssistantInput {
id: string;
}

export interface CreateOneUserDatabaseInput {
userDatabase: CreateUserDatabase;
}
Expand Down Expand Up @@ -948,10 +975,6 @@ export interface IntegrationAccount {
fieldsSchema?: Nullable<JSONObject>;
}

export interface DeleteManyResponse {
deletedCount: number;
}

export interface IntegrationAccountEdge {
node: IntegrationAccount;
cursor: ConnectionCursor;
Expand Down Expand Up @@ -1371,6 +1394,12 @@ export interface WorkflowRunActionConnection {
edges: WorkflowRunActionEdge[];
}

export interface Assistant {
id: string;
createdAt: DateTime;
instructions: string;
}

export interface Campaign {
id: string;
createdAt: DateTime;
Expand All @@ -1386,6 +1415,22 @@ export interface Campaign {
error?: Nullable<string>;
}

export interface AssistantDeleteResponse {
id?: Nullable<string>;
createdAt?: Nullable<DateTime>;
instructions?: Nullable<string>;
}

export interface AssistantEdge {
node: Assistant;
cursor: ConnectionCursor;
}

export interface AssistantConnection {
pageInfo: PageInfo;
edges: AssistantEdge[];
}

export interface CampaignDeleteResponse {
id?: Nullable<string>;
createdAt?: Nullable<DateTime>;
Expand Down Expand Up @@ -1676,6 +1721,8 @@ export interface IQuery {
order(id: string): Order | Promise<Order>;
orders(paging?: Nullable<CursorPaging>, filter?: Nullable<OrderFilter>, sorting?: Nullable<OrderSort[]>): OrderConnection | Promise<OrderConnection>;
orderSummary(from: DateTime, to: DateTime): OrderSummary | Promise<OrderSummary>;
assistant(id: string): Assistant | Promise<Assistant>;
assistants(paging?: Nullable<CursorPaging>, filter?: Nullable<AssistantFilter>, sorting?: Nullable<AssistantSort[]>): AssistantConnection | Promise<AssistantConnection>;
contractSchema(chainId: number, address: string, type: string): ContractSchema | Promise<ContractSchema>;
asyncSchemas(integrationId: string, accountCredentialId: string, names: string[], inputs?: Nullable<JSONObject>, integrationTriggerId?: Nullable<string>, integrationActionId?: Nullable<string>): AsyncSchema | Promise<AsyncSchema>;
manyAsyncSchemas(asyncSchemaInputs: JSONObject[]): AsyncSchema | Promise<AsyncSchema>;
Expand Down Expand Up @@ -1718,7 +1765,6 @@ export interface IMutation {
createOneContact(input: CreateOneContactInput): Contact | Promise<Contact>;
updateOneContact(input: UpdateOneContactInput): Contact | Promise<Contact>;
deleteOneContact(input: DeleteOneContactInput): ContactDeleteResponse | Promise<ContactDeleteResponse>;
deleteManyContacts(input: DeleteManyContactsInput): DeleteManyResponse | Promise<DeleteManyResponse>;
addContacts(addresses: string[], tags?: Nullable<string[]>, limitToPlan?: Nullable<boolean>): ResultPayload | Promise<ResultPayload>;
generateContactsPresignedUrl(id: string): string | Promise<string>;
addContactsFile(id: string, tags?: Nullable<string[]>, limitToPlan?: Nullable<boolean>): ResultPayload | Promise<ResultPayload>;
Expand All @@ -1735,6 +1781,9 @@ export interface IMutation {
createOneOrder(input: CreateOneOrderInput): Order | Promise<Order>;
updateOneOrder(input: UpdateOneOrderInput): Order | Promise<Order>;
deleteOneOrder(input: DeleteOneOrderInput): OrderDeleteResponse | Promise<OrderDeleteResponse>;
createOneAssistant(input: CreateOneAssistantInput): Assistant | Promise<Assistant>;
updateOneAssistant(input: UpdateOneAssistantInput): Assistant | Promise<Assistant>;
deleteOneAssistant(input: DeleteOneAssistantInput): AssistantDeleteResponse | Promise<AssistantDeleteResponse>;
createOneUserDatabase(input: CreateOneUserDatabaseInput): UserDatabase | Promise<UserDatabase>;
updateOneUserDatabase(input: UpdateOneUserDatabaseInput): UserDatabase | Promise<UserDatabase>;
deleteOneUserDatabase(input: DeleteOneUserDatabaseInput): UserDatabaseDeleteResponse | Promise<UserDatabaseDeleteResponse>;
Expand Down
Loading

0 comments on commit 0ae7fb2

Please sign in to comment.