diff --git a/packages/@n8n/api-types/src/chat-hub.ts b/packages/@n8n/api-types/src/chat-hub.ts index 6ba99c5ad98..286ffbce81c 100644 --- a/packages/@n8n/api-types/src/chat-hub.ts +++ b/packages/@n8n/api-types/src/chat-hub.ts @@ -459,7 +459,7 @@ export class ChatHubUpdateAgentRequest extends Z.class({ icon: agentIconOrEmojiSchema.optional(), systemPrompt: z.string().min(1).optional(), credentialId: z.string().optional(), - provider: chatHubProviderSchema.optional(), + provider: chatHubLLMProviderSchema.optional(), model: z.string().max(64).optional(), tools: z.array(INodeSchema).optional(), }) {} diff --git a/packages/cli/src/modules/chat-hub/chat-hub-agent.entity.ts b/packages/cli/src/modules/chat-hub/chat-hub-agent.entity.ts index 1435e935264..43408cded40 100644 --- a/packages/cli/src/modules/chat-hub/chat-hub-agent.entity.ts +++ b/packages/cli/src/modules/chat-hub/chat-hub-agent.entity.ts @@ -3,6 +3,21 @@ import { User, CredentialsEntity, JsonColumn, WithTimestamps } from '@n8n/db'; import { Column, Entity, ManyToOne, JoinColumn, PrimaryGeneratedColumn } from '@n8n/typeorm'; import { INode } from 'n8n-workflow'; +export interface IChatHubAgent { + id: string; + createdAt: Date; + updatedAt: Date; + name: string; + description: string | null; + icon: AgentIconOrEmoji | null; + systemPrompt: string; + ownerId: string; + credentialId: string | null; + provider: ChatHubLLMProvider; + model: string; + tools: INode[]; +} + @Entity({ name: 'chat_hub_agents' }) export class ChatHubAgent extends WithTimestamps { @PrimaryGeneratedColumn('uuid') diff --git a/packages/cli/src/modules/chat-hub/chat-hub-agent.repository.ts b/packages/cli/src/modules/chat-hub/chat-hub-agent.repository.ts index 5c117ff7eef..28eea18a0bb 100644 --- a/packages/cli/src/modules/chat-hub/chat-hub-agent.repository.ts +++ b/packages/cli/src/modules/chat-hub/chat-hub-agent.repository.ts @@ -2,7 +2,7 @@ import { withTransaction } from '@n8n/db'; import { Service } from '@n8n/di'; import { DataSource, EntityManager, Repository } from '@n8n/typeorm'; -import { ChatHubAgent } from './chat-hub-agent.entity'; +import { ChatHubAgent, IChatHubAgent } from './chat-hub-agent.entity'; @Service() export class ChatHubAgentRepository extends Repository { @@ -10,7 +10,10 @@ export class ChatHubAgentRepository extends Repository { super(ChatHubAgent, dataSource.manager); } - async createAgent(agent: Partial, trx?: EntityManager) { + async createAgent( + agent: Partial & Pick, + trx?: EntityManager, + ) { return await withTransaction(this.manager, trx, async (em) => { await em.insert(ChatHubAgent, agent); return await em.findOneOrFail(ChatHubAgent, { @@ -19,16 +22,7 @@ export class ChatHubAgentRepository extends Repository { }); } - async updateAgent( - id: string, - updates: Partial< - Pick< - ChatHubAgent, - 'name' | 'description' | 'systemPrompt' | 'provider' | 'model' | 'credentialId' - > - >, - trx?: EntityManager, - ) { + async updateAgent(id: string, updates: Partial, trx?: EntityManager) { return await withTransaction(this.manager, trx, async (em) => { await em.update(ChatHubAgent, { id }, updates); return await em.findOneOrFail(ChatHubAgent, { diff --git a/packages/cli/src/modules/chat-hub/chat-hub-agent.service.ts b/packages/cli/src/modules/chat-hub/chat-hub-agent.service.ts index dd93653391a..eee57e1270b 100644 --- a/packages/cli/src/modules/chat-hub/chat-hub-agent.service.ts +++ b/packages/cli/src/modules/chat-hub/chat-hub-agent.service.ts @@ -8,7 +8,7 @@ import type { User } from '@n8n/db'; import { Service } from '@n8n/di'; import { v4 as uuidv4 } from 'uuid'; -import type { ChatHubAgent } from './chat-hub-agent.entity'; +import type { ChatHubAgent, IChatHubAgent } from './chat-hub-agent.entity'; import { ChatHubAgentRepository } from './chat-hub-agent.repository'; import { ChatHubCredentialsService } from './chat-hub-credentials.service'; import { getModelMetadata } from './chat-hub.constants'; @@ -75,7 +75,7 @@ export class ChatHubAgentService { tools: data.tools, }); - this.logger.info(`Chat agent created: ${id} by user ${user.id}`); + this.logger.debug(`Chat agent created: ${id} by user ${user.id}`); return agent; } @@ -95,20 +95,20 @@ export class ChatHubAgentService { await this.chatHubCredentialsService.ensureCredentialById(user, updates.credentialId); } - const updateData: Partial = {}; + const updateData: Partial = {}; + if (updates.name !== undefined) updateData.name = updates.name; if (updates.description !== undefined) updateData.description = updates.description ?? null; if (updates.icon !== undefined) updateData.icon = updates.icon; if (updates.systemPrompt !== undefined) updateData.systemPrompt = updates.systemPrompt; if (updates.credentialId !== undefined) updateData.credentialId = updates.credentialId ?? null; - if (updates.provider !== undefined) - updateData.provider = updates.provider as ChatHubAgent['provider']; + if (updates.provider !== undefined) updateData.provider = updates.provider; if (updates.model !== undefined) updateData.model = updates.model ?? null; if (updates.tools !== undefined) updateData.tools = updates.tools; const agent = await this.chatAgentRepository.updateAgent(id, updateData); - this.logger.info(`Chat agent updated: ${id} by user ${user.id}`); + this.logger.debug(`Chat agent updated: ${id} by user ${user.id}`); return agent; } @@ -121,6 +121,6 @@ export class ChatHubAgentService { await this.chatAgentRepository.deleteAgent(id); - this.logger.info(`Chat agent deleted: ${id} by user ${userId}`); + this.logger.debug(`Chat agent deleted: ${id} by user ${userId}`); } } diff --git a/packages/cli/src/modules/chat-hub/chat-hub-session.entity.ts b/packages/cli/src/modules/chat-hub/chat-hub-session.entity.ts index fd61ec4b8c5..543bfcc0820 100644 --- a/packages/cli/src/modules/chat-hub/chat-hub-session.entity.ts +++ b/packages/cli/src/modules/chat-hub/chat-hub-session.entity.ts @@ -21,6 +21,22 @@ import type { INode } from 'n8n-workflow'; import type { ChatHubMessage } from './chat-hub-message.entity'; import type { ChatHubAgent } from './chat-hub-agent.entity'; +export interface IChatHubSession { + id: string; + createdAt: Date; + updatedAt: Date; + title: string; + ownerId: string; + lastMessageAt: Date | null; + credentialId: string | null; + provider: ChatHubProvider | null; + model: string | null; + workflowId: string | null; + agentId: string | null; + agentName: string | null; + tools: INode[]; +} + @Entity({ name: 'chat_hub_sessions' }) export class ChatHubSession extends WithTimestamps { @PrimaryGeneratedColumn('uuid') diff --git a/packages/cli/src/modules/chat-hub/chat-hub.service.ts b/packages/cli/src/modules/chat-hub/chat-hub.service.ts index 10bd9cb0b49..58014988b15 100644 --- a/packages/cli/src/modules/chat-hub/chat-hub.service.ts +++ b/packages/cli/src/modules/chat-hub/chat-hub.service.ts @@ -45,7 +45,7 @@ import { import { ChatHubAgentService } from './chat-hub-agent.service'; import { ChatHubCredentialsService } from './chat-hub-credentials.service'; import type { ChatHubMessage } from './chat-hub-message.entity'; -import type { ChatHubSession } from './chat-hub-session.entity'; +import type { ChatHubSession, IChatHubSession } from './chat-hub-session.entity'; import { ChatHubWorkflowService } from './chat-hub-workflow.service'; import { ChatHubAttachmentService } from './chat-hub.attachment.service'; import { @@ -1419,7 +1419,7 @@ export class ChatHubService { } // Prepare the actual updates to be sent to the repository - const sessionUpdates: Partial = {}; + const sessionUpdates: Partial = {}; if (updates.agent) { const model = updates.agent.model; diff --git a/packages/cli/src/modules/chat-hub/chat-session.repository.ts b/packages/cli/src/modules/chat-hub/chat-session.repository.ts index 8eb28891570..70feed1cedf 100644 --- a/packages/cli/src/modules/chat-hub/chat-session.repository.ts +++ b/packages/cli/src/modules/chat-hub/chat-session.repository.ts @@ -2,7 +2,7 @@ import { withTransaction } from '@n8n/db'; import { Service } from '@n8n/di'; import { DataSource, EntityManager, Repository } from '@n8n/typeorm'; -import { ChatHubSession } from './chat-hub-session.entity'; +import { ChatHubSession, IChatHubSession } from './chat-hub-session.entity'; import { NotFoundError } from '@/errors/response-errors/not-found.error'; @@ -12,7 +12,10 @@ export class ChatHubSessionRepository extends Repository { super(ChatHubSession, dataSource.manager); } - async createChatSession(session: Partial, trx?: EntityManager) { + async createChatSession( + session: Partial & Pick, + trx?: EntityManager, + ) { return await withTransaction(this.manager, trx, async (em) => { await em.insert(ChatHubSession, session); return await em.findOneOrFail(ChatHubSession, { @@ -42,7 +45,7 @@ export class ChatHubSessionRepository extends Repository { }); } - async updateChatSession(id: string, updates: Partial, trx?: EntityManager) { + async updateChatSession(id: string, updates: Partial, trx?: EntityManager) { return await withTransaction(this.manager, trx, async (em) => { await em.update(ChatHubSession, { id }, updates); return await em.findOneOrFail(ChatHubSession, {