ideaco 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +33 -0
- package/.nvmrc +1 -0
- package/ARCHITECTURE.md +394 -0
- package/Dockerfile +50 -0
- package/LICENSE +29 -0
- package/README.md +206 -0
- package/bin/i18n.js +46 -0
- package/bin/ideaco.js +494 -0
- package/deploy.sh +15 -0
- package/docker-compose.yml +30 -0
- package/electron/main.cjs +986 -0
- package/electron/preload.cjs +14 -0
- package/electron/web-backends.cjs +854 -0
- package/jsconfig.json +8 -0
- package/next.config.mjs +34 -0
- package/package.json +134 -0
- package/postcss.config.mjs +6 -0
- package/public/demo/dashboard.png +0 -0
- package/public/demo/employee.png +0 -0
- package/public/demo/messages.png +0 -0
- package/public/demo/office.png +0 -0
- package/public/demo/requirement.png +0 -0
- package/public/logo.jpeg +0 -0
- package/public/logo.png +0 -0
- package/scripts/prepare-electron.js +67 -0
- package/scripts/release.js +76 -0
- package/src/app/api/agents/[agentId]/chat/route.js +70 -0
- package/src/app/api/agents/[agentId]/conversations/route.js +35 -0
- package/src/app/api/agents/[agentId]/route.js +106 -0
- package/src/app/api/avatar/route.js +104 -0
- package/src/app/api/browse-dir/route.js +44 -0
- package/src/app/api/chat/route.js +265 -0
- package/src/app/api/company/factory-reset/route.js +43 -0
- package/src/app/api/company/route.js +82 -0
- package/src/app/api/departments/[deptId]/agents/[agentId]/dismiss/route.js +19 -0
- package/src/app/api/departments/route.js +92 -0
- package/src/app/api/group-chat-loop/events/route.js +70 -0
- package/src/app/api/group-chat-loop/route.js +94 -0
- package/src/app/api/mailbox/route.js +100 -0
- package/src/app/api/messages/route.js +14 -0
- package/src/app/api/providers/[id]/configure/route.js +21 -0
- package/src/app/api/providers/[id]/refresh-cookie/route.js +38 -0
- package/src/app/api/providers/[id]/test-cookie/route.js +28 -0
- package/src/app/api/providers/route.js +11 -0
- package/src/app/api/requirements/route.js +242 -0
- package/src/app/api/secretary/route.js +65 -0
- package/src/app/api/system/cli-backends/route.js +91 -0
- package/src/app/api/system/cron/route.js +110 -0
- package/src/app/api/system/knowledge/route.js +104 -0
- package/src/app/api/system/plugins/route.js +40 -0
- package/src/app/api/system/skills/route.js +46 -0
- package/src/app/api/system/status/route.js +46 -0
- package/src/app/api/talent-market/[profileId]/recall/route.js +22 -0
- package/src/app/api/talent-market/[profileId]/route.js +17 -0
- package/src/app/api/talent-market/route.js +26 -0
- package/src/app/api/teams/route.js +773 -0
- package/src/app/api/ws-files/[departmentId]/file/route.js +27 -0
- package/src/app/api/ws-files/[departmentId]/files/route.js +22 -0
- package/src/app/globals.css +130 -0
- package/src/app/layout.jsx +40 -0
- package/src/app/page.jsx +97 -0
- package/src/components/AgentChatModal.jsx +164 -0
- package/src/components/AgentDetailModal.jsx +425 -0
- package/src/components/AgentSpyModal.jsx +481 -0
- package/src/components/AvatarGrid.jsx +29 -0
- package/src/components/BossProfileModal.jsx +162 -0
- package/src/components/CachedAvatar.jsx +77 -0
- package/src/components/ChatPanel.jsx +219 -0
- package/src/components/ChatShared.jsx +255 -0
- package/src/components/DepartmentDetail.jsx +842 -0
- package/src/components/DepartmentView.jsx +367 -0
- package/src/components/FileReference.jsx +260 -0
- package/src/components/FilesView.jsx +465 -0
- package/src/components/GroupChatView.jsx +799 -0
- package/src/components/Mailbox.jsx +926 -0
- package/src/components/MessagesView.jsx +112 -0
- package/src/components/OnboardingGuide.jsx +209 -0
- package/src/components/OrgTree.jsx +151 -0
- package/src/components/Overview.jsx +391 -0
- package/src/components/PixelOffice.jsx +2281 -0
- package/src/components/ProviderGrid.jsx +551 -0
- package/src/components/ProvidersBoard.jsx +16 -0
- package/src/components/RequirementDetail.jsx +1279 -0
- package/src/components/RequirementsBoard.jsx +187 -0
- package/src/components/SecretarySettings.jsx +295 -0
- package/src/components/SetupWizard.jsx +388 -0
- package/src/components/Sidebar.jsx +169 -0
- package/src/components/SystemMonitor.jsx +808 -0
- package/src/components/TalentMarket.jsx +183 -0
- package/src/components/TeamDetail.jsx +697 -0
- package/src/core/agent/base-agent.js +104 -0
- package/src/core/agent/chat-store.js +602 -0
- package/src/core/agent/cli-agent/backends/claude-code/README.md +52 -0
- package/src/core/agent/cli-agent/backends/claude-code/config.js +27 -0
- package/src/core/agent/cli-agent/backends/codebuddy/README.md +236 -0
- package/src/core/agent/cli-agent/backends/codebuddy/config.js +27 -0
- package/src/core/agent/cli-agent/backends/codex/README.md +51 -0
- package/src/core/agent/cli-agent/backends/codex/config.js +27 -0
- package/src/core/agent/cli-agent/backends/index.js +27 -0
- package/src/core/agent/cli-agent/backends/registry.js +580 -0
- package/src/core/agent/cli-agent/index.js +154 -0
- package/src/core/agent/index.js +60 -0
- package/src/core/agent/llm-agent/client.js +320 -0
- package/src/core/agent/llm-agent/index.js +97 -0
- package/src/core/agent/message-bus.js +211 -0
- package/src/core/agent/session.js +608 -0
- package/src/core/agent/tools.js +596 -0
- package/src/core/agent/web-agent/backends/base-backend.js +180 -0
- package/src/core/agent/web-agent/backends/chatgpt/client.js +146 -0
- package/src/core/agent/web-agent/backends/chatgpt/config.js +148 -0
- package/src/core/agent/web-agent/backends/chatgpt/dom-scripts.js +303 -0
- package/src/core/agent/web-agent/backends/index.js +91 -0
- package/src/core/agent/web-agent/index.js +278 -0
- package/src/core/agent/web-agent/web-client.js +407 -0
- package/src/core/employee/base-employee.js +1088 -0
- package/src/core/employee/index.js +35 -0
- package/src/core/employee/knowledge.js +327 -0
- package/src/core/employee/lifecycle.js +990 -0
- package/src/core/employee/memory/index.js +642 -0
- package/src/core/employee/memory/store.js +143 -0
- package/src/core/employee/performance.js +224 -0
- package/src/core/employee/secretary.js +625 -0
- package/src/core/employee/skills.js +398 -0
- package/src/core/index.js +38 -0
- package/src/core/organization/company.js +2600 -0
- package/src/core/organization/department.js +737 -0
- package/src/core/organization/group-chat-loop.js +264 -0
- package/src/core/organization/index.js +8 -0
- package/src/core/organization/persistence.js +111 -0
- package/src/core/organization/team.js +267 -0
- package/src/core/organization/workforce/hr.js +377 -0
- package/src/core/organization/workforce/providers.js +468 -0
- package/src/core/organization/workforce/role-archetypes.js +805 -0
- package/src/core/organization/workforce/talent-market.js +205 -0
- package/src/core/prompts.js +532 -0
- package/src/core/requirement.js +1789 -0
- package/src/core/system/audit.js +483 -0
- package/src/core/system/cron.js +449 -0
- package/src/core/system/index.js +7 -0
- package/src/core/system/plugin.js +2183 -0
- package/src/core/utils/json-parse.js +188 -0
- package/src/core/workspace.js +239 -0
- package/src/lib/api-i18n.js +211 -0
- package/src/lib/avatar.js +268 -0
- package/src/lib/client-store.js +1025 -0
- package/src/lib/config-validator.js +483 -0
- package/src/lib/format-time.js +22 -0
- package/src/lib/hooks.js +414 -0
- package/src/lib/i18n.js +134 -0
- package/src/lib/paths.js +23 -0
- package/src/lib/store.js +72 -0
- package/src/locales/de.js +393 -0
- package/src/locales/en.js +1054 -0
- package/src/locales/es.js +393 -0
- package/src/locales/fr.js +393 -0
- package/src/locales/ja.js +501 -0
- package/src/locales/ko.js +513 -0
- package/src/locales/zh.js +828 -0
- package/tailwind.config.mjs +11 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Independent Memory File Management Module
|
|
3
|
+
*
|
|
4
|
+
* Each Employee's memory is stored in a separate JSON file (data/memories/{employeeId}.json),
|
|
5
|
+
* preventing all memories from being stuffed into company-state.json causing file bloat.
|
|
6
|
+
*
|
|
7
|
+
* Workflow:
|
|
8
|
+
* 1. When saving company state, memory only serializes a summary (counts); full memory goes to separate files
|
|
9
|
+
* 2. When restoring company state, load each Employee's full memory from separate files
|
|
10
|
+
* 3. When memory changes, save only that Employee's memory file (no need to rewrite entire company state)
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'fs';
|
|
13
|
+
import path from 'path';
|
|
14
|
+
import { MEMORY_DIR } from '../../../lib/paths.js';
|
|
15
|
+
|
|
16
|
+
// Ensure directory exists
|
|
17
|
+
if (!fs.existsSync(MEMORY_DIR)) {
|
|
18
|
+
fs.mkdirSync(MEMORY_DIR, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Save a single Employee's memory to a separate file
|
|
23
|
+
* @param {string} agentId - Employee ID
|
|
24
|
+
* @param {object} memoryData - Serialized memory data { shortTerm, longTerm }
|
|
25
|
+
* @param {object} meta - Metadata { name, role, department }
|
|
26
|
+
*/
|
|
27
|
+
export function saveAgentMemory(agentId, memoryData, meta = {}) {
|
|
28
|
+
if (!agentId || !memoryData) return;
|
|
29
|
+
try {
|
|
30
|
+
const filePath = path.join(MEMORY_DIR, `${agentId}.json`);
|
|
31
|
+
const data = {
|
|
32
|
+
agentId,
|
|
33
|
+
name: meta.name || 'unknown',
|
|
34
|
+
role: meta.role || 'unknown',
|
|
35
|
+
department: meta.department || 'unknown',
|
|
36
|
+
shortTerm: memoryData.shortTerm || [],
|
|
37
|
+
longTerm: memoryData.longTerm || [],
|
|
38
|
+
historySummary: memoryData.historySummary || {},
|
|
39
|
+
relationships: memoryData.relationships || {},
|
|
40
|
+
savedAt: new Date().toISOString(),
|
|
41
|
+
};
|
|
42
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.error(`ā Failed to save memory [${agentId}]:`, e.message);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Load a single Employee's memory
|
|
50
|
+
* @param {string} agentId - Employee ID
|
|
51
|
+
* @returns {object|null} { shortTerm, longTerm } or null
|
|
52
|
+
*/
|
|
53
|
+
export function loadAgentMemory(agentId) {
|
|
54
|
+
if (!agentId) return null;
|
|
55
|
+
try {
|
|
56
|
+
const filePath = path.join(MEMORY_DIR, `${agentId}.json`);
|
|
57
|
+
if (!fs.existsSync(filePath)) return null;
|
|
58
|
+
const json = fs.readFileSync(filePath, 'utf-8');
|
|
59
|
+
const data = JSON.parse(json);
|
|
60
|
+
return {
|
|
61
|
+
shortTerm: data.shortTerm || [],
|
|
62
|
+
longTerm: data.longTerm || [],
|
|
63
|
+
historySummary: data.historySummary || {},
|
|
64
|
+
relationships: data.relationships || {},
|
|
65
|
+
};
|
|
66
|
+
} catch (e) {
|
|
67
|
+
console.error(`ā Failed to load memory [${agentId}]:`, e.message);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Batch save multiple Employees' memories
|
|
74
|
+
* @param {Array<{agentId, memoryData, meta}>} agents - Employee memory array
|
|
75
|
+
*/
|
|
76
|
+
export function saveAllAgentMemories(agents) {
|
|
77
|
+
let saved = 0;
|
|
78
|
+
for (const { agentId, memoryData, meta } of agents) {
|
|
79
|
+
saveAgentMemory(agentId, memoryData, meta);
|
|
80
|
+
saved++;
|
|
81
|
+
}
|
|
82
|
+
if (saved > 0) {
|
|
83
|
+
console.log(`š§ Saved ${saved} Employee memory files`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Delete an Employee's memory file
|
|
89
|
+
* @param {string} agentId - Employee ID
|
|
90
|
+
*/
|
|
91
|
+
export function deleteAgentMemory(agentId) {
|
|
92
|
+
try {
|
|
93
|
+
const filePath = path.join(MEMORY_DIR, `${agentId}.json`);
|
|
94
|
+
if (fs.existsSync(filePath)) {
|
|
95
|
+
fs.unlinkSync(filePath);
|
|
96
|
+
console.log(`šļø Deleted Employee [${agentId}] memory file`);
|
|
97
|
+
}
|
|
98
|
+
} catch (e) {
|
|
99
|
+
console.error(`ā Failed to delete memory file [${agentId}]:`, e.message);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* List all saved memory files
|
|
105
|
+
* @returns {Array<{agentId, name, role, shortTermCount, longTermCount, savedAt}>}
|
|
106
|
+
*/
|
|
107
|
+
export function listMemoryFiles() {
|
|
108
|
+
try {
|
|
109
|
+
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
110
|
+
return files.map(f => {
|
|
111
|
+
try {
|
|
112
|
+
const json = fs.readFileSync(path.join(MEMORY_DIR, f), 'utf-8');
|
|
113
|
+
const data = JSON.parse(json);
|
|
114
|
+
return {
|
|
115
|
+
agentId: data.agentId,
|
|
116
|
+
name: data.name,
|
|
117
|
+
role: data.role,
|
|
118
|
+
department: data.department,
|
|
119
|
+
shortTermCount: data.shortTerm?.length || 0,
|
|
120
|
+
longTermCount: data.longTerm?.length || 0,
|
|
121
|
+
savedAt: data.savedAt,
|
|
122
|
+
};
|
|
123
|
+
} catch {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}).filter(Boolean);
|
|
127
|
+
} catch {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Clear all memory files
|
|
134
|
+
*/
|
|
135
|
+
export function clearAllMemories() {
|
|
136
|
+
try {
|
|
137
|
+
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
138
|
+
files.forEach(f => fs.unlinkSync(path.join(MEMORY_DIR, f)));
|
|
139
|
+
console.log(`šļø Cleared ${files.length} memory files`);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
console.error('ā Failed to clear memory files:', e.message);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Performance Evaluation System
|
|
5
|
+
* Supervisors evaluate employees' work results; employees provide self-feedback based on scores
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Performance scoring dimensions */
|
|
9
|
+
export const PerformanceDimensions = {
|
|
10
|
+
QUALITY: 'quality', // Work quality
|
|
11
|
+
EFFICIENCY: 'efficiency', // Work efficiency
|
|
12
|
+
COLLABORATION: 'collaboration', // Collaboration ability
|
|
13
|
+
INNOVATION: 'innovation', // Innovation ability
|
|
14
|
+
COMMUNICATION: 'communication', // Communication skills
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** Performance levels */
|
|
18
|
+
export const PerformanceLevel = {
|
|
19
|
+
EXCELLENT: { label: 'Excellent', minScore: 90, emoji: 'š' },
|
|
20
|
+
GOOD: { label: 'Good', minScore: 75, emoji: 'ā' },
|
|
21
|
+
AVERAGE: { label: 'Average', minScore: 60, emoji: 'š' },
|
|
22
|
+
BELOW_AVERAGE: { label: 'Needs Improvement', minScore: 40, emoji: 'ā ļø' },
|
|
23
|
+
POOR: { label: 'Poor', minScore: 0, emoji: 'ā' },
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get performance level
|
|
28
|
+
*/
|
|
29
|
+
export function getPerformanceLevel(score) {
|
|
30
|
+
if (score >= 90) return PerformanceLevel.EXCELLENT;
|
|
31
|
+
if (score >= 75) return PerformanceLevel.GOOD;
|
|
32
|
+
if (score >= 60) return PerformanceLevel.AVERAGE;
|
|
33
|
+
if (score >= 40) return PerformanceLevel.BELOW_AVERAGE;
|
|
34
|
+
return PerformanceLevel.POOR;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Single performance review record
|
|
39
|
+
*/
|
|
40
|
+
export class PerformanceReview {
|
|
41
|
+
constructor({ agentId, agentName, reviewerId, reviewerName, taskTitle, scores, comment }) {
|
|
42
|
+
this.id = uuidv4();
|
|
43
|
+
this.agentId = agentId; // Reviewee
|
|
44
|
+
this.agentName = agentName;
|
|
45
|
+
this.reviewerId = reviewerId; // Reviewer (supervisor)
|
|
46
|
+
this.reviewerName = reviewerName;
|
|
47
|
+
this.taskTitle = taskTitle; // Associated task
|
|
48
|
+
this.scores = scores; // Dimension scores { quality: 85, efficiency: 90, ... }
|
|
49
|
+
this.overallScore = this._calcOverall(scores); // Overall score
|
|
50
|
+
this.level = getPerformanceLevel(this.overallScore); // Performance level
|
|
51
|
+
this.comment = comment || ''; // Supervisor's comment
|
|
52
|
+
this.selfReflection = null; // Employee's self-feedback (filled later)
|
|
53
|
+
this.createdAt = new Date();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Calculate overall score (weighted average) */
|
|
57
|
+
_calcOverall(scores) {
|
|
58
|
+
const weights = {
|
|
59
|
+
[PerformanceDimensions.QUALITY]: 0.3,
|
|
60
|
+
[PerformanceDimensions.EFFICIENCY]: 0.25,
|
|
61
|
+
[PerformanceDimensions.COLLABORATION]: 0.15,
|
|
62
|
+
[PerformanceDimensions.INNOVATION]: 0.15,
|
|
63
|
+
[PerformanceDimensions.COMMUNICATION]: 0.15,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
let total = 0;
|
|
67
|
+
let weightSum = 0;
|
|
68
|
+
for (const [dim, score] of Object.entries(scores)) {
|
|
69
|
+
const weight = weights[dim] || 0.2;
|
|
70
|
+
total += score * weight;
|
|
71
|
+
weightSum += weight;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return Math.round(total / (weightSum || 1));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Employee fills in self-feedback */
|
|
78
|
+
addSelfReflection(reflection) {
|
|
79
|
+
this.selfReflection = reflection;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Get summary */
|
|
83
|
+
getSummary() {
|
|
84
|
+
return {
|
|
85
|
+
id: this.id,
|
|
86
|
+
agent: this.agentName,
|
|
87
|
+
reviewer: this.reviewerName,
|
|
88
|
+
task: this.taskTitle,
|
|
89
|
+
overallScore: this.overallScore,
|
|
90
|
+
level: `${this.level.emoji} ${this.level.label}`,
|
|
91
|
+
scores: this.scores,
|
|
92
|
+
comment: this.comment,
|
|
93
|
+
selfReflection: this.selfReflection,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Performance Management System - Manages all Agent performance records
|
|
100
|
+
*/
|
|
101
|
+
export class PerformanceSystem {
|
|
102
|
+
constructor() {
|
|
103
|
+
this.reviews = new Map(); // agentId => PerformanceReview[]
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Supervisor evaluates an employee
|
|
108
|
+
* @param {object} params
|
|
109
|
+
* @param {Agent} params.agent - Employee being evaluated
|
|
110
|
+
* @param {Agent} params.reviewer - Evaluator (supervisor)
|
|
111
|
+
* @param {string} params.taskTitle - Task name
|
|
112
|
+
* @param {object} params.scores - Dimension scores
|
|
113
|
+
* @param {string} [params.comment] - Comment
|
|
114
|
+
* @returns {PerformanceReview}
|
|
115
|
+
*/
|
|
116
|
+
evaluate({ agent, reviewer, taskTitle, scores, comment }) {
|
|
117
|
+
const review = new PerformanceReview({
|
|
118
|
+
agentId: agent.id,
|
|
119
|
+
agentName: agent.name,
|
|
120
|
+
reviewerId: reviewer.id,
|
|
121
|
+
reviewerName: reviewer.name,
|
|
122
|
+
taskTitle,
|
|
123
|
+
scores,
|
|
124
|
+
comment,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if (!this.reviews.has(agent.id)) {
|
|
128
|
+
this.reviews.set(agent.id, []);
|
|
129
|
+
}
|
|
130
|
+
this.reviews.get(agent.id).push(review);
|
|
131
|
+
|
|
132
|
+
console.log(` š Performance review: [${reviewer.name}] evaluated [${agent.name}]`);
|
|
133
|
+
console.log(` Task: "${taskTitle}"`);
|
|
134
|
+
console.log(` Overall score: ${review.overallScore} ${review.level.emoji} ${review.level.label}`);
|
|
135
|
+
Object.entries(scores).forEach(([dim, score]) => {
|
|
136
|
+
console.log(` - ${dim}: ${score}`);
|
|
137
|
+
});
|
|
138
|
+
if (comment) {
|
|
139
|
+
console.log(` Comment: "${comment}"`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return review;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Simulated auto-evaluation by supervisor (generate scores based on task results)
|
|
147
|
+
*/
|
|
148
|
+
autoEvaluate({ agent, reviewer, taskTitle }) {
|
|
149
|
+
// Simulated scoring: base score 60-95 random + some variance
|
|
150
|
+
const baseScore = 60 + Math.floor(Math.random() * 35);
|
|
151
|
+
const scores = {
|
|
152
|
+
[PerformanceDimensions.QUALITY]: Math.min(100, baseScore + Math.floor(Math.random() * 10 - 5)),
|
|
153
|
+
[PerformanceDimensions.EFFICIENCY]: Math.min(100, baseScore + Math.floor(Math.random() * 10 - 5)),
|
|
154
|
+
[PerformanceDimensions.COLLABORATION]: Math.min(100, baseScore + Math.floor(Math.random() * 10 - 5)),
|
|
155
|
+
[PerformanceDimensions.INNOVATION]: Math.min(100, baseScore + Math.floor(Math.random() * 10 - 5)),
|
|
156
|
+
[PerformanceDimensions.COMMUNICATION]: Math.min(100, baseScore + Math.floor(Math.random() * 10 - 5)),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const comments = {
|
|
160
|
+
90: 'Outstanding performance, exceeded expectations, a benchmark for the team!',
|
|
161
|
+
75: 'Excellent work quality, keep it up.',
|
|
162
|
+
60: 'Task completed adequately, but there is room for improvement.',
|
|
163
|
+
40: 'Performance was not ideal, improvement needed.',
|
|
164
|
+
0: 'Work output fell below standards, needs serious attention.',
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const overallScore = Object.values(scores).reduce((a, b) => a + b, 0) / Object.values(scores).length;
|
|
168
|
+
let comment = comments[0];
|
|
169
|
+
for (const [threshold, c] of Object.entries(comments).sort((a, b) => b[0] - a[0])) {
|
|
170
|
+
if (overallScore >= Number(threshold)) {
|
|
171
|
+
comment = c;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return this.evaluate({ agent, reviewer, taskTitle, scores, comment });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Get all performance records for an employee
|
|
181
|
+
*/
|
|
182
|
+
getReviews(agentId) {
|
|
183
|
+
return this.reviews.get(agentId) || [];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Get an employee's average performance score
|
|
188
|
+
*/
|
|
189
|
+
getAverageScore(agentId) {
|
|
190
|
+
const reviews = this.getReviews(agentId);
|
|
191
|
+
if (reviews.length === 0) return null;
|
|
192
|
+
const total = reviews.reduce((sum, r) => sum + r.overallScore, 0);
|
|
193
|
+
return Math.round(total / reviews.length);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Get an employee's latest review
|
|
198
|
+
*/
|
|
199
|
+
getLatestReview(agentId) {
|
|
200
|
+
const reviews = this.getReviews(agentId);
|
|
201
|
+
return reviews.length > 0 ? reviews[reviews.length - 1] : null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Print employee performance report
|
|
206
|
+
*/
|
|
207
|
+
printReport(agentId, agentName = '') {
|
|
208
|
+
const reviews = this.getReviews(agentId);
|
|
209
|
+
const avg = this.getAverageScore(agentId);
|
|
210
|
+
const level = avg !== null ? getPerformanceLevel(avg) : null;
|
|
211
|
+
|
|
212
|
+
console.log(`\nš ${agentName ? `[${agentName}]` : ''} Performance Report:`);
|
|
213
|
+
console.log(` Review count: ${reviews.length}`);
|
|
214
|
+
if (avg !== null) {
|
|
215
|
+
console.log(` Average score: ${avg} ${level.emoji} ${level.label}`);
|
|
216
|
+
}
|
|
217
|
+
reviews.forEach((r, i) => {
|
|
218
|
+
console.log(` #${i + 1}: "${r.taskTitle}" - ${r.overallScore} pts ${r.level.emoji}`);
|
|
219
|
+
if (r.selfReflection) {
|
|
220
|
+
console.log(` Self-reflection: "${r.selfReflection}"`);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|