import type { AgentDefinition, AgentToolConfig } from '@services/agentDefinition/interface'; import type { AgentInstance, AgentInstanceLatestStatus, AgentInstanceMessage } from '@services/agentInstance/interface'; import type { AiAPIConfig } from '@services/agentInstance/promptConcat/promptConcatSchema'; import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, OneToMany, PrimaryColumn, UpdateDateColumn } from 'typeorm'; /** * Database entity: Stores user modifications to predefined Agents * Note: AgentDefinition typically comes from downloaded JSON or app-defined templates, * we only store the user's customizations, not the complete definition * This saves space and makes it easier to track user personalization */ @Entity('agent_definitions') export class AgentDefinitionEntity implements Partial { /** Unique identifier for the agent */ @PrimaryColumn() id!: string; /** Agent name, nullable indicates using default name */ @Column({ nullable: true }) name?: string; /** Detailed agent description, nullable indicates using default description */ @Column({ type: 'text', nullable: true }) description?: string; /** Agent avatar or icon URL, nullable indicates using default avatar */ @Column({ nullable: true }) avatarUrl?: string; /** Agent handler function ID, nullable indicates using default handler */ @Column({ nullable: true }) handlerID?: string; /** Agent handler configuration parameters, stored as JSON */ @Column({ type: 'simple-json', nullable: true }) handlerConfig?: Record; /** Agent's AI API configuration, can override global default config */ @Column({ type: 'simple-json', nullable: true }) aiApiConfig?: Partial; /** Tools available to this agent */ @Column({ type: 'simple-json', nullable: true }) agentTools?: AgentToolConfig[]; /** Creation timestamp */ @CreateDateColumn() createdAt!: Date; /** Last update timestamp */ @UpdateDateColumn() updatedAt!: Date; // One AgentDefinition can have multiple AgentInstances @OneToMany(() => AgentInstanceEntity, instance => instance.agentDefinition) instances?: AgentInstanceEntity[]; } /** * Stores user chat sessions with Agents */ @Entity('agent_instances') export class AgentInstanceEntity implements Partial { @PrimaryColumn() id!: string; @Column() @Index() agentDefId!: string; @Column({ nullable: true }) name?: string; @Column({ type: 'simple-json' }) status!: AgentInstanceLatestStatus; @CreateDateColumn() created!: Date; @UpdateDateColumn() modified?: Date; @Column({ type: 'simple-json', nullable: true }) aiApiConfig?: Partial; @Column({ nullable: true }) avatarUrl?: string; /** Agent handler configuration parameters, inherited from AgentDefinition */ @Column({ type: 'simple-json', nullable: true }) handlerConfig?: Record; @Column({ default: false }) closed: boolean = false; /** Indicate this agent instance is temporary, like forked instance to do sub-jobs, or for preview when editing agent definitions. */ @Column({ default: false }) volatile: boolean = false; // Relation to AgentDefinition @ManyToOne(() => AgentDefinitionEntity, definition => definition.instances) @JoinColumn({ name: 'agentDefId' }) agentDefinition?: AgentDefinitionEntity; // One AgentInstance can have multiple Messages @OneToMany(() => AgentInstanceMessageEntity, message => message.agentInstance, { cascade: ['insert', 'update'], }) messages?: AgentInstanceMessageEntity[]; } /** * Stores conversation messages between users and Agents */ @Entity('agent_instance_messages') export class AgentInstanceMessageEntity implements AgentInstanceMessage { @PrimaryColumn() id!: string; @Column() @Index() agentId!: string; @Column({ type: 'varchar', enum: ['user', 'assistant', 'agent', 'tool', 'error'], default: 'user', }) role!: 'user' | 'assistant' | 'agent' | 'tool' | 'error'; @Column({ type: 'text' }) content!: string; @Column({ type: 'varchar', nullable: true, default: 'text/plain', }) contentType?: string; @CreateDateColumn({ type: 'datetime' }) created!: Date; @UpdateDateColumn() modified?: Date; @Column({ type: 'simple-json', nullable: true, name: 'meta_data' }) metadata?: Record; @Column({ type: 'integer', nullable: true }) duration?: number; // Relation to AgentInstance @ManyToOne(() => AgentInstanceEntity, instance => instance.messages) @JoinColumn({ name: 'agentId' }) agentInstance?: AgentInstanceEntity; }