File size: 4,604 Bytes
5da4770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import { IVersionRepository } from '../repositories/interfaces';
import {
  AgentVersion,
  CreateVersionRequest,
  UpdateVersionDetailsRequest,
  VersionComparison,
  VersionDifference
} from '../types';

export interface IVersionService {
  getAllVersions(agentId: string): Promise<AgentVersion[]>;
  getVersion(agentId: string, versionId: string): Promise<AgentVersion>;
  createVersion(agentId: string, request: CreateVersionRequest): Promise<AgentVersion>;
  activateVersion(agentId: string, versionId: string): Promise<void>;
  updateVersionDetails(agentId: string, versionId: string, request: UpdateVersionDetailsRequest): Promise<AgentVersion>;
  getActiveVersion(agentId: string): Promise<AgentVersion | null>;
  getVersionByNumber(agentId: string, versionNumber: number): Promise<AgentVersion | null>;
}

export class VersionService implements IVersionService {
  constructor(private repository: IVersionRepository) {}

  async getAllVersions(agentId: string): Promise<AgentVersion[]> {
    const versions = await this.repository.getAllVersions(agentId);
    return versions.sort((a, b) => b.versionNumber.value - a.versionNumber.value);
  }

  async getVersion(agentId: string, versionId: string): Promise<AgentVersion> {
    return this.repository.getVersion(agentId, versionId);
  }

  async createVersion(
    agentId: string,
    request: CreateVersionRequest
  ): Promise<AgentVersion> {
    if (!request.system_prompt?.trim()) {
      throw new Error('System prompt cannot be empty');
    }

    const newVersion = await this.repository.createVersion(agentId, request);
    console.log(`Created version ${newVersion.versionName} for agent ${agentId}`);
    return newVersion;
  }

  async activateVersion(agentId: string, versionId: string): Promise<void> {
    await this.repository.activateVersion(agentId, versionId);
    console.log(`Activated version ${versionId} for agent ${agentId}`);
  }

  async compareVersions(
    agentId: string,
    version1Id: string,
    version2Id: string
  ): Promise<VersionComparison> {
    return this.repository.compareVersions(agentId, version1Id, version2Id);
  }

  async rollbackToVersion(
    agentId: string,
    versionId: string
  ): Promise<AgentVersion> {
    const newVersion = await this.repository.rollbackToVersion(agentId, versionId);
    console.log(`Rolled back to version ${versionId} for agent ${agentId}`);
    return newVersion;
  }

  async updateVersionDetails(
    agentId: string,
    versionId: string,
    request: UpdateVersionDetailsRequest
  ): Promise<AgentVersion> {
    const updatedVersion = await this.repository.updateVersionDetails(agentId, versionId, request);
    console.log(`Updated version details for ${versionId} in agent ${agentId}`);
    return updatedVersion;
  }

  async getActiveVersion(agentId: string): Promise<AgentVersion | null> {
    const versions = await this.getAllVersions(agentId);
    return versions.find(v => v.isActive) || null;
  }

  async getVersionByNumber(
    agentId: string,
    versionNumber: number
  ): Promise<AgentVersion | null> {
    const versions = await this.getAllVersions(agentId);
    return versions.find(v => v.versionNumber.value === versionNumber) || null;
  }

  calculateDifferences(v1: AgentVersion, v2: AgentVersion): VersionDifference[] {
    const differences: VersionDifference[] = [];

    if (v1.systemPrompt !== v2.systemPrompt) {
      differences.push({
        field: 'systemPrompt',
        type: 'modified',
        oldValue: v1.systemPrompt,
        newValue: v2.systemPrompt
      });
    }

    const v1Tools = new Set(Object.keys(v1.toolConfiguration.tools));
    const v2Tools = new Set(Object.keys(v2.toolConfiguration.tools));

    for (const tool of v2Tools) {
      if (!v1Tools.has(tool)) {
        differences.push({
          field: `tool.${tool}`,
          type: 'added',
          newValue: v2.toolConfiguration.tools[tool]
        });
      }
    }

    for (const tool of v1Tools) {
      if (!v2Tools.has(tool)) {
        differences.push({
          field: `tool.${tool}`,
          type: 'removed',
          oldValue: v1.toolConfiguration.tools[tool]
        });
      }
    }

    for (const tool of v1Tools) {
      if (v2Tools.has(tool) &&
          JSON.stringify(v1.toolConfiguration.tools[tool]) !== 
          JSON.stringify(v2.toolConfiguration.tools[tool])) {
        differences.push({
          field: `tool.${tool}`,
          type: 'modified',
          oldValue: v1.toolConfiguration.tools[tool],
          newValue: v2.toolConfiguration.tools[tool]
        });
      }
    }

    return differences;
  }
}