hypercore-cli 1.1.2 → 1.4.0
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/LICENSE +92 -21
- package/README.md +8 -1
- package/dist/App-YMX7FSXR.js +1 -0
- package/dist/api-ELP6F4NC.js +1 -0
- package/dist/auth-SICBMA3P.js +1 -0
- package/dist/auth-X6CUT3DW.js +1 -0
- package/dist/background-ACODXSUG.js +1 -0
- package/dist/backlog-JD2IM336.js +1 -0
- package/dist/chunk-2QI2IU2V.js +1 -0
- package/dist/chunk-3KFRDIPQ.js +1 -0
- package/dist/chunk-42C5J7PN.js +1 -0
- package/dist/chunk-4D7XVJ7Q.js +1 -0
- package/dist/chunk-5KUSGQP2.js +1 -0
- package/dist/chunk-5OEFAGD5.js +1 -0
- package/dist/chunk-AUQ64BK2.js +1 -0
- package/dist/chunk-AV244H5C.js +1 -0
- package/dist/chunk-BQVBEFS4.js +1 -0
- package/dist/chunk-BYWQLFP2.js +1 -0
- package/dist/chunk-C6YL7UHE.js +1 -0
- package/dist/chunk-COITWWZJ.js +1 -0
- package/dist/chunk-CR7UUJVX.js +1 -0
- package/dist/chunk-E3MULLBX.js +1 -0
- package/dist/chunk-EZHYVJGQ.js +1 -0
- package/dist/chunk-FAMURNNH.js +1 -0
- package/dist/chunk-FGP56E4W.js +1 -0
- package/dist/chunk-FHGATV5B.js +1 -0
- package/dist/chunk-I2G27Y5P.js +1 -0
- package/dist/chunk-IKF43TX2.js +1 -0
- package/dist/chunk-INSPHCBN.js +1 -0
- package/dist/chunk-JHMV366T.js +1 -0
- package/dist/chunk-L52HX5SX.js +1 -0
- package/dist/chunk-LQMDUKIE.js +1 -0
- package/dist/chunk-M3MTKGA5.js +1 -0
- package/dist/chunk-MPO54FU3.js +1 -0
- package/dist/chunk-PVKCZI6A.js +1 -0
- package/dist/chunk-Q7KEPCYL.js +1 -0
- package/dist/chunk-ROBZ6PAL.js +1 -0
- package/dist/chunk-RXB5BS2N.js +1 -0
- package/dist/chunk-RZ3HNYMT.js +1 -0
- package/dist/chunk-UCGLRMTG.js +1 -0
- package/dist/chunk-UEHJVRKB.js +1 -0
- package/dist/chunk-UZYX5GGF.js +1 -0
- package/dist/chunk-XQJBB725.js +1 -0
- package/dist/chunk-YXCRL6K3.js +1 -0
- package/dist/claude-US2QPRBA.js +1 -0
- package/dist/commands-EKPWCB3T.js +1 -0
- package/dist/commands-GYNKP5WV.js +1 -0
- package/dist/commands-QHJLREPM.js +1 -0
- package/dist/config-2OUL5FLS.js +1 -0
- package/dist/config-loader-N7IBWN2P.js +1 -0
- package/dist/diagnose-NLHN4SAJ.js +1 -0
- package/dist/display-RYAW2GFB.js +1 -0
- package/dist/extractor-3KTM2IUL.js +1 -0
- package/dist/feature-flag-VVIF5FJG.js +1 -0
- package/dist/history-3R2UHRDQ.js +1 -0
- package/dist/index.js +1 -402
- package/dist/instance-registry-I5AIVJE2.js +1 -0
- package/dist/keybindings-RN3A7CRW.js +1 -0
- package/dist/loader-3IKPXP4R.js +1 -0
- package/dist/network-K5HRJE44.js +1 -0
- package/dist/notify-O6FNVHC4.js +1 -0
- package/dist/openai-compat-IPCMINVF.js +1 -0
- package/dist/panels-2R5YEFXH.js +1 -0
- package/dist/permissions-5O7KVAXU.js +1 -0
- package/dist/prompt-VWFPFM4N.js +1 -0
- package/dist/quality-GPQD25UL.js +1 -0
- package/dist/repl-CL4SYHU4.js +1 -0
- package/dist/roadmap-QRZODSNJ.js +1 -0
- package/dist/server-PKOHK5M2.js +1 -0
- package/dist/session-5HDDQQP6.js +1 -0
- package/dist/skills-DXWSVJSU.js +1 -0
- package/dist/store-WXXTKTTL.js +1 -0
- package/dist/team-N2GF4YYS.js +1 -0
- package/dist/telemetry-NT4UZLBS.js +1 -0
- package/dist/test-runner-F6B6RH3S.js +1 -0
- package/dist/theme-JJJ6ABR2.js +1 -0
- package/dist/upgrade-RUG3R7R5.js +1 -0
- package/dist/verify-6OGRY2PR.js +1 -0
- package/dist/version-4RHTDUNQ.js +1 -0
- package/dist/web/static/app.js +1 -562
- package/dist/web/static/index.html +114 -126
- package/dist/web/static/mirror.css +1 -1001
- package/dist/web/static/mirror.html +155 -178
- package/dist/web/static/mirror.js +1 -1125
- package/dist/web/static/onboard.css +1 -302
- package/dist/web/static/onboard.html +121 -145
- package/dist/web/static/onboard.js +1 -300
- package/dist/web/static/style.css +1 -602
- package/dist/web/static/utils.js +1 -0
- package/dist/web/static/workspace.css +1 -1568
- package/dist/web/static/workspace.html +369 -402
- package/dist/web/static/workspace.js +1 -1683
- package/dist/web-CIC7ZKBM.js +1 -0
- package/package.json +26 -4
- package/dist/api-JHHOZTL6.js +0 -162
- package/dist/auth-5QFJLW7J.js +0 -21
- package/dist/background-2EGCAAQH.js +0 -14
- package/dist/backlog-Q2NZCLNY.js +0 -24
- package/dist/chunk-2CMSCWQW.js +0 -162
- package/dist/chunk-4DVYJAJL.js +0 -57
- package/dist/chunk-5GDYH676.js +0 -271
- package/dist/chunk-5NLVGLD7.js +0 -66
- package/dist/chunk-6XTEAFZQ.js +0 -575
- package/dist/chunk-AQBSMYLT.js +0 -2025
- package/dist/chunk-BE46C7JW.js +0 -46
- package/dist/chunk-CLKIMCXZ.js +0 -139
- package/dist/chunk-DN4ASQ26.js +0 -167
- package/dist/chunk-DUWREZXK.js +0 -173
- package/dist/chunk-FCW3K6F2.js +0 -263
- package/dist/chunk-GFORWAMW.js +0 -251
- package/dist/chunk-GH7E2OJE.js +0 -223
- package/dist/chunk-GU2FZQ6A.js +0 -69
- package/dist/chunk-I7WI3BMB.js +0 -161
- package/dist/chunk-IOPKN5GD.js +0 -190
- package/dist/chunk-LBVHDGZE.js +0 -133
- package/dist/chunk-MGLJ53QN.js +0 -219
- package/dist/chunk-NETIY5UB.js +0 -134
- package/dist/chunk-NP47L7LG.js +0 -288
- package/dist/chunk-O6MG7TOH.js +0 -58
- package/dist/chunk-OPZYEVYR.js +0 -150
- package/dist/chunk-R3GPQC7I.js +0 -393
- package/dist/chunk-R5T3A2NQ.js +0 -166
- package/dist/chunk-RKB2JOV2.js +0 -43
- package/dist/chunk-RNG3K465.js +0 -80
- package/dist/chunk-TGTYKBGC.js +0 -86
- package/dist/chunk-UCX4VZCT.js +0 -681
- package/dist/chunk-WHLVZCQY.js +0 -245
- package/dist/chunk-Y6HMJZDJ.js +0 -1505
- package/dist/chunk-ZSBHUGWR.js +0 -262
- package/dist/claude-4BX3MJSK.js +0 -12
- package/dist/commands-2X4OB5RF.js +0 -128
- package/dist/commands-GLBCEVQK.js +0 -1044
- package/dist/commands-IINRNBYX.js +0 -232
- package/dist/config-RSNQJQPS.js +0 -8
- package/dist/config-loader-SXO674TF.js +0 -24
- package/dist/diagnose-7UPLS7I4.js +0 -12
- package/dist/display-IIUBEYWN.js +0 -58
- package/dist/extractor-D3XWOAXI.js +0 -129
- package/dist/history-6I6FADAU.js +0 -180
- package/dist/index.d.ts +0 -1
- package/dist/instance-registry-J7UJ7U4Z.js +0 -15
- package/dist/keybindings-PDXIOV3O.js +0 -15
- package/dist/loader-GKEYT6Y7.js +0 -58
- package/dist/network-JYGHQXAR.js +0 -279
- package/dist/notify-HPTALZDC.js +0 -14
- package/dist/openai-compat-R7EKWG6Z.js +0 -12
- package/dist/permissions-JUKXMNDH.js +0 -10
- package/dist/prompt-UWHSZU4P.js +0 -166
- package/dist/quality-ST7PPNFR.js +0 -16
- package/dist/repl-QHIZ2JGF.js +0 -3374
- package/dist/roadmap-5OBEKROY.js +0 -17
- package/dist/server-HCNIP7ZQ.js +0 -57
- package/dist/session-5EBECDUP.js +0 -21
- package/dist/skills-HBQQTYO4.js +0 -175
- package/dist/store-FKUTR7GW.js +0 -25
- package/dist/team-7BBBP5YQ.js +0 -385
- package/dist/telemetry-6R4EIE6O.js +0 -30
- package/dist/test-runner-AUAGIBNM.js +0 -619
- package/dist/theme-3SYJ3UQA.js +0 -14
- package/dist/upgrade-MZFH7OCN.js +0 -83
- package/dist/verify-JUDKTPKZ.js +0 -14
- package/dist/web-KS3FUGJA.js +0 -39
package/dist/chunk-UCX4VZCT.js
DELETED
|
@@ -1,681 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
broadcastToTeam,
|
|
3
|
-
sendToMember
|
|
4
|
-
} from "./chunk-DN4ASQ26.js";
|
|
5
|
-
import {
|
|
6
|
-
listTasks,
|
|
7
|
-
loadTeam
|
|
8
|
-
} from "./chunk-DUWREZXK.js";
|
|
9
|
-
import {
|
|
10
|
-
generateId
|
|
11
|
-
} from "./chunk-5NLVGLD7.js";
|
|
12
|
-
import {
|
|
13
|
-
callLLM,
|
|
14
|
-
createLLMClient
|
|
15
|
-
} from "./chunk-FCW3K6F2.js";
|
|
16
|
-
import {
|
|
17
|
-
callOpenAILLM
|
|
18
|
-
} from "./chunk-5GDYH676.js";
|
|
19
|
-
import {
|
|
20
|
-
MODEL_ALIASES,
|
|
21
|
-
MODEL_PROVIDERS
|
|
22
|
-
} from "./chunk-I7WI3BMB.js";
|
|
23
|
-
|
|
24
|
-
// src/network/store.ts
|
|
25
|
-
import fs from "fs/promises";
|
|
26
|
-
import path from "path";
|
|
27
|
-
import os from "os";
|
|
28
|
-
|
|
29
|
-
// src/network/types.ts
|
|
30
|
-
var DEFAULT_NETWORK_CONFIG = {
|
|
31
|
-
autoEnabled: false,
|
|
32
|
-
autoIntervalMs: 4 * 60 * 60 * 1e3,
|
|
33
|
-
// 4 小时
|
|
34
|
-
budgetPerRoundUSD: 0.5,
|
|
35
|
-
matchmakerModel: "flash",
|
|
36
|
-
dialogueModel: "flash",
|
|
37
|
-
maxDialogueTurns: 3,
|
|
38
|
-
maxMatchPairs: 5
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// src/network/store.ts
|
|
42
|
-
function networkDir(teamId) {
|
|
43
|
-
return path.join(os.homedir(), ".hypercore", "teams", teamId, "network");
|
|
44
|
-
}
|
|
45
|
-
function profilesDir(teamId) {
|
|
46
|
-
return path.join(networkDir(teamId), "profiles");
|
|
47
|
-
}
|
|
48
|
-
function roundsDir(teamId) {
|
|
49
|
-
return path.join(networkDir(teamId), "rounds");
|
|
50
|
-
}
|
|
51
|
-
function configPath(teamId) {
|
|
52
|
-
return path.join(networkDir(teamId), "config.json");
|
|
53
|
-
}
|
|
54
|
-
async function ensureDir(dir) {
|
|
55
|
-
await fs.mkdir(dir, { recursive: true });
|
|
56
|
-
}
|
|
57
|
-
async function saveProfile(teamId, profile) {
|
|
58
|
-
const dir = profilesDir(teamId);
|
|
59
|
-
await ensureDir(dir);
|
|
60
|
-
await fs.writeFile(
|
|
61
|
-
path.join(dir, `${profile.memberId}.json`),
|
|
62
|
-
JSON.stringify(profile, null, 2),
|
|
63
|
-
"utf-8"
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
async function loadProfile(teamId, memberId) {
|
|
67
|
-
try {
|
|
68
|
-
const data = await fs.readFile(
|
|
69
|
-
path.join(profilesDir(teamId), `${memberId}.json`),
|
|
70
|
-
"utf-8"
|
|
71
|
-
);
|
|
72
|
-
return JSON.parse(data);
|
|
73
|
-
} catch {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
async function loadAllProfiles(teamId) {
|
|
78
|
-
const dir = profilesDir(teamId);
|
|
79
|
-
try {
|
|
80
|
-
const files = await fs.readdir(dir);
|
|
81
|
-
const profiles = [];
|
|
82
|
-
for (const file of files) {
|
|
83
|
-
if (file.endsWith(".json")) {
|
|
84
|
-
const data = await fs.readFile(path.join(dir, file), "utf-8");
|
|
85
|
-
profiles.push(JSON.parse(data));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return profiles;
|
|
89
|
-
} catch {
|
|
90
|
-
return [];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
async function saveRound(teamId, round) {
|
|
94
|
-
const dir = roundsDir(teamId);
|
|
95
|
-
await ensureDir(dir);
|
|
96
|
-
await fs.writeFile(
|
|
97
|
-
path.join(dir, `${round.id}.json`),
|
|
98
|
-
JSON.stringify(round, null, 2),
|
|
99
|
-
"utf-8"
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
async function loadRound(teamId, roundId) {
|
|
103
|
-
try {
|
|
104
|
-
const data = await fs.readFile(
|
|
105
|
-
path.join(roundsDir(teamId), `${roundId}.json`),
|
|
106
|
-
"utf-8"
|
|
107
|
-
);
|
|
108
|
-
return JSON.parse(data);
|
|
109
|
-
} catch {
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function listRounds(teamId) {
|
|
114
|
-
const dir = roundsDir(teamId);
|
|
115
|
-
try {
|
|
116
|
-
const files = await fs.readdir(dir);
|
|
117
|
-
const rounds = [];
|
|
118
|
-
for (const file of files) {
|
|
119
|
-
if (file.endsWith(".json")) {
|
|
120
|
-
const data = await fs.readFile(path.join(dir, file), "utf-8");
|
|
121
|
-
rounds.push(JSON.parse(data));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
rounds.sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
|
|
125
|
-
return rounds;
|
|
126
|
-
} catch {
|
|
127
|
-
return [];
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async function getLatestRound(teamId) {
|
|
131
|
-
const rounds = await listRounds(teamId);
|
|
132
|
-
return rounds[0] || null;
|
|
133
|
-
}
|
|
134
|
-
async function loadNetworkConfig(teamId) {
|
|
135
|
-
try {
|
|
136
|
-
const data = await fs.readFile(configPath(teamId), "utf-8");
|
|
137
|
-
return { ...DEFAULT_NETWORK_CONFIG, ...JSON.parse(data) };
|
|
138
|
-
} catch {
|
|
139
|
-
return { ...DEFAULT_NETWORK_CONFIG };
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
async function saveNetworkConfig(teamId, config) {
|
|
143
|
-
await ensureDir(networkDir(teamId));
|
|
144
|
-
await fs.writeFile(configPath(teamId), JSON.stringify(config, null, 2), "utf-8");
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// src/network/profile.ts
|
|
148
|
-
async function gatherProfile(teamId, memberId, memberName) {
|
|
149
|
-
const existing = await loadProfile(teamId, memberId);
|
|
150
|
-
const tasks = await listTasks(teamId);
|
|
151
|
-
const myTasks = tasks.filter((t) => t.assignee === memberId || t.createdBy === memberId);
|
|
152
|
-
const currentTasks = myTasks.filter((t) => t.status !== "done").map((t) => ({ title: t.title, status: t.status, priority: t.priority }));
|
|
153
|
-
const recentContext = buildRecentContext(myTasks);
|
|
154
|
-
const profile = {
|
|
155
|
-
memberId,
|
|
156
|
-
memberName,
|
|
157
|
-
currentTasks,
|
|
158
|
-
skills: existing?.skills || [],
|
|
159
|
-
needs: existing?.needs || [],
|
|
160
|
-
offerings: existing?.offerings || [],
|
|
161
|
-
recentContext,
|
|
162
|
-
customNote: existing?.customNote,
|
|
163
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
164
|
-
};
|
|
165
|
-
await saveProfile(teamId, profile);
|
|
166
|
-
return profile;
|
|
167
|
-
}
|
|
168
|
-
async function updateProfileField(teamId, memberId, field, value) {
|
|
169
|
-
const profile = await loadProfile(teamId, memberId);
|
|
170
|
-
if (!profile) return null;
|
|
171
|
-
if (field === "customNote") {
|
|
172
|
-
profile.customNote = value;
|
|
173
|
-
} else {
|
|
174
|
-
profile[field] = value;
|
|
175
|
-
}
|
|
176
|
-
profile.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
177
|
-
await saveProfile(teamId, profile);
|
|
178
|
-
return profile;
|
|
179
|
-
}
|
|
180
|
-
function buildRecentContext(tasks) {
|
|
181
|
-
if (tasks.length === 0) return "\u6682\u65E0\u4EFB\u52A1";
|
|
182
|
-
const doing = tasks.filter((t) => t.status === "doing");
|
|
183
|
-
const todo = tasks.filter((t) => t.status === "todo");
|
|
184
|
-
const done = tasks.filter((t) => t.status === "done").slice(0, 3);
|
|
185
|
-
const parts = [];
|
|
186
|
-
if (doing.length > 0) {
|
|
187
|
-
parts.push(`\u6B63\u5728\u505A: ${doing.map((t) => t.title).join(", ")}`);
|
|
188
|
-
}
|
|
189
|
-
if (todo.length > 0) {
|
|
190
|
-
parts.push(`\u8BA1\u5212\u505A: ${todo.map((t) => t.title).join(", ")}`);
|
|
191
|
-
}
|
|
192
|
-
if (done.length > 0) {
|
|
193
|
-
parts.push(`\u5DF2\u5B8C\u6210: ${done.map((t) => t.title).join(", ")}`);
|
|
194
|
-
}
|
|
195
|
-
return parts.join("\uFF1B") || "\u6682\u65E0\u4EFB\u52A1";
|
|
196
|
-
}
|
|
197
|
-
async function gatherAllProfiles(teamId) {
|
|
198
|
-
const team = await loadTeam(teamId);
|
|
199
|
-
if (!team) return [];
|
|
200
|
-
const profiles = [];
|
|
201
|
-
for (const member of team.members) {
|
|
202
|
-
const profile = await gatherProfile(teamId, member.id, member.name);
|
|
203
|
-
profiles.push(profile);
|
|
204
|
-
}
|
|
205
|
-
return profiles;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// src/network/runner.ts
|
|
209
|
-
import chalk from "chalk";
|
|
210
|
-
|
|
211
|
-
// src/network/matchmaker.ts
|
|
212
|
-
import OpenAI from "openai";
|
|
213
|
-
var MATCHMAKER_SYSTEM = `\u4F60\u662F Hyper Network \u7684\u5339\u914D\u5F15\u64CE\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u5206\u6790\u56E2\u961F\u6210\u5458\u7684 Profile\uFF0C\u627E\u51FA\u6700\u5177\u4E92\u8865\u4EF7\u503C\u7684\u914D\u5BF9\u3002
|
|
214
|
-
|
|
215
|
-
\u5339\u914D\u539F\u5219\uFF1A
|
|
216
|
-
1. A \u7684 needs \u5339\u914D B \u7684 offerings\uFF08\u6216\u53CD\u4E4B\uFF09
|
|
217
|
-
2. \u4EFB\u52A1\u6709\u534F\u540C\u7A7A\u95F4\uFF08\u6B63\u5728\u505A\u7C7B\u4F3C\u6216\u76F8\u5173\u7684\u4E8B\uFF09
|
|
218
|
-
3. \u6280\u80FD\u4E92\u8865\uFF08A\u64C5\u957F\u7684\u6070\u597D\u662FB\u9700\u8981\u7684\uFF09
|
|
219
|
-
4. \u7ECF\u9A8C\u4E92\u6362\uFF08\u53CC\u65B9\u90FD\u80FD\u4ECE\u4EA4\u6D41\u4E2D\u83B7\u76CA\uFF09
|
|
220
|
-
|
|
221
|
-
\u8BC4\u5206\u6807\u51C6\uFF080-100\uFF09\uFF1A
|
|
222
|
-
- 90+\uFF1A\u5F3A\u4E92\u8865\uFF0C\u53CC\u65B9\u90FD\u6709\u660E\u786E\u7684\u7ED9\u4E88\u548C\u83B7\u53D6
|
|
223
|
-
- 70-89\uFF1A\u4E2D\u5EA6\u4E92\u8865\uFF0C\u81F3\u5C11\u4E00\u65B9\u80FD\u660E\u663E\u53D7\u76CA
|
|
224
|
-
- 50-69\uFF1A\u8F7B\u5EA6\u5173\u8054\uFF0C\u53EF\u4EE5\u4EA4\u6D41\u4F46\u4EF7\u503C\u6709\u9650
|
|
225
|
-
- <50\uFF1A\u4E0D\u63A8\u8350\u914D\u5BF9
|
|
226
|
-
|
|
227
|
-
\u4E25\u683C\u8F93\u51FA JSON \u6570\u7EC4\uFF0C\u6BCF\u9879\u5305\u542B\uFF1AmemberA_id, memberB_id, reason, score, suggestedTopic
|
|
228
|
-
\u4E0D\u8981\u914D\u5BF9 score < 50 \u7684\u3002\u4E0D\u8981\u8F93\u51FA\u591A\u4F59\u6587\u5B57\uFF0C\u53EA\u8F93\u51FA JSON\u3002`;
|
|
229
|
-
function buildMatchPrompt(profiles, maxPairs) {
|
|
230
|
-
const profilesText = profiles.map((p, i) => {
|
|
231
|
-
const skills = p.skills.length > 0 ? p.skills.join(", ") : "\u672A\u8BBE\u7F6E";
|
|
232
|
-
const needs = p.needs.length > 0 ? p.needs.join(", ") : "\u672A\u8BBE\u7F6E";
|
|
233
|
-
const offerings = p.offerings.length > 0 ? p.offerings.join(", ") : "\u672A\u8BBE\u7F6E";
|
|
234
|
-
const tasks = p.currentTasks.length > 0 ? p.currentTasks.map((t) => `${t.title}(${t.status}/${t.priority})`).join(", ") : "\u65E0";
|
|
235
|
-
return `## \u6210\u5458${i + 1}: ${p.memberName} (ID: ${p.memberId})
|
|
236
|
-
- \u6280\u80FD: ${skills}
|
|
237
|
-
- \u9700\u6C42: ${needs}
|
|
238
|
-
- \u53EF\u63D0\u4F9B: ${offerings}
|
|
239
|
-
- \u5F53\u524D\u4EFB\u52A1: ${tasks}
|
|
240
|
-
- \u8FD1\u671F\u5DE5\u4F5C: ${p.recentContext}
|
|
241
|
-
${p.customNote ? `- \u5907\u6CE8: ${p.customNote}` : ""}`;
|
|
242
|
-
}).join("\n\n");
|
|
243
|
-
return `\u4EE5\u4E0B\u662F\u56E2\u961F\u6210\u5458\u7684 Profile\uFF0C\u8BF7\u627E\u51FA\u6700\u591A ${maxPairs} \u5BF9\u4E92\u8865\u914D\u5BF9\u3002
|
|
244
|
-
|
|
245
|
-
${profilesText}
|
|
246
|
-
|
|
247
|
-
\u8BF7\u8F93\u51FA JSON \u6570\u7EC4\uFF08\u65E0\u591A\u4F59\u6587\u5B57\uFF09:
|
|
248
|
-
[{"memberA_id":"...","memberB_id":"...","reason":"\u5339\u914D\u539F\u56E0","score":85,"suggestedTopic":"\u5EFA\u8BAE\u5BF9\u8BDD\u4E3B\u9898"}, ...]`;
|
|
249
|
-
}
|
|
250
|
-
function parseMatches(output, profiles) {
|
|
251
|
-
const jsonMatch = output.match(/\[[\s\S]*\]/);
|
|
252
|
-
if (!jsonMatch) return [];
|
|
253
|
-
try {
|
|
254
|
-
const raw = JSON.parse(jsonMatch[0]);
|
|
255
|
-
const profileMap = new Map(profiles.map((p) => [p.memberId, p]));
|
|
256
|
-
return raw.filter((m) => m.score >= 50 && profileMap.has(m.memberA_id) && profileMap.has(m.memberB_id)).map((m) => ({
|
|
257
|
-
id: generateId(),
|
|
258
|
-
memberA: { id: m.memberA_id, name: profileMap.get(m.memberA_id).memberName },
|
|
259
|
-
memberB: { id: m.memberB_id, name: profileMap.get(m.memberB_id).memberName },
|
|
260
|
-
reason: m.reason,
|
|
261
|
-
score: m.score,
|
|
262
|
-
suggestedTopic: m.suggestedTopic
|
|
263
|
-
}));
|
|
264
|
-
} catch {
|
|
265
|
-
return [];
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
function resolveModel(modelAlias, config) {
|
|
269
|
-
const alias = MODEL_ALIASES[modelAlias.toLowerCase()];
|
|
270
|
-
if (alias) {
|
|
271
|
-
const providerInfo = MODEL_PROVIDERS[alias.provider];
|
|
272
|
-
const apiKey = config.providerKeys[alias.provider] || config.modelConfig.apiKey;
|
|
273
|
-
return { model: alias.model, sdkType: providerInfo.sdkType, baseURL: providerInfo.baseURL, apiKey };
|
|
274
|
-
}
|
|
275
|
-
return {
|
|
276
|
-
model: config.modelConfig.model,
|
|
277
|
-
sdkType: config.modelConfig.sdkType,
|
|
278
|
-
baseURL: config.modelConfig.baseURL,
|
|
279
|
-
apiKey: config.modelConfig.apiKey
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
async function runMatchmaker(profiles, netConfig, config) {
|
|
283
|
-
if (profiles.length < 2) {
|
|
284
|
-
return { matches: [], tokenUsage: { inputTokens: 0, outputTokens: 0 } };
|
|
285
|
-
}
|
|
286
|
-
const userPrompt = buildMatchPrompt(profiles, netConfig.maxMatchPairs);
|
|
287
|
-
const resolved = resolveModel(netConfig.matchmakerModel, config);
|
|
288
|
-
if (resolved.sdkType === "openai") {
|
|
289
|
-
const client = new OpenAI({ apiKey: resolved.apiKey, baseURL: resolved.baseURL });
|
|
290
|
-
const result = await callOpenAILLM(client, {
|
|
291
|
-
systemPrompt: MATCHMAKER_SYSTEM,
|
|
292
|
-
userPrompt,
|
|
293
|
-
tools: [],
|
|
294
|
-
model: resolved.model,
|
|
295
|
-
maxTokens: 4096
|
|
296
|
-
});
|
|
297
|
-
const matches = parseMatches(result.output, profiles);
|
|
298
|
-
return { matches, tokenUsage: result.tokenUsage };
|
|
299
|
-
} else {
|
|
300
|
-
const client = createLLMClient({
|
|
301
|
-
provider: "anthropic",
|
|
302
|
-
model: resolved.model,
|
|
303
|
-
apiKey: resolved.apiKey,
|
|
304
|
-
sdkType: "anthropic"
|
|
305
|
-
});
|
|
306
|
-
const result = await callLLM(client, {
|
|
307
|
-
systemPrompt: MATCHMAKER_SYSTEM,
|
|
308
|
-
userPrompt,
|
|
309
|
-
tools: [],
|
|
310
|
-
model: resolved.model,
|
|
311
|
-
maxTokens: 4096
|
|
312
|
-
});
|
|
313
|
-
const matches = parseMatches(result.output, profiles);
|
|
314
|
-
return { matches, tokenUsage: result.tokenUsage };
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// src/network/dialogue.ts
|
|
319
|
-
import OpenAI2 from "openai";
|
|
320
|
-
function avatarSystemPrompt(profile, partner, match) {
|
|
321
|
-
const tasks = profile.currentTasks.map((t) => `${t.title}(${t.status})`).join(", ") || "\u65E0";
|
|
322
|
-
const skills = profile.skills.join(", ") || "\u672A\u8BBE\u7F6E";
|
|
323
|
-
const needs = profile.needs.join(", ") || "\u672A\u8BBE\u7F6E";
|
|
324
|
-
const offerings = profile.offerings.join(", ") || "\u672A\u8BBE\u7F6E";
|
|
325
|
-
return `\u4F60\u662F ${profile.memberName} \u7684 AI Agent Avatar\uFF0C\u4EE3\u8868\u4ED6\u4E0E ${partner.memberName} \u7684 Avatar \u4EA4\u6D41\u3002
|
|
326
|
-
|
|
327
|
-
\u4F60\u4EE3\u8868\u7684\u7528\u6237\u4FE1\u606F\uFF1A
|
|
328
|
-
- \u5F53\u524D\u4EFB\u52A1: ${tasks}
|
|
329
|
-
- \u6280\u80FD: ${skills}
|
|
330
|
-
- \u9700\u8981\u5E2E\u52A9: ${needs}
|
|
331
|
-
- \u53EF\u63D0\u4F9B: ${offerings}
|
|
332
|
-
- \u8FD1\u671F\u5DE5\u4F5C: ${profile.recentContext}
|
|
333
|
-
|
|
334
|
-
\u5339\u914D\u539F\u56E0\uFF1A${match.reason}
|
|
335
|
-
\u5EFA\u8BAE\u4E3B\u9898\uFF1A${match.suggestedTopic}
|
|
336
|
-
|
|
337
|
-
\u89C4\u5219\uFF1A
|
|
338
|
-
1. \u7AD9\u5728\u4F60\u4EE3\u8868\u7684\u7528\u6237\u7ACB\u573A\uFF0C\u4E3B\u52A8\u4EA4\u6362\u5177\u4F53\u4FE1\u606F
|
|
339
|
-
2. \u6BCF\u8F6E 2-4 \u53E5\u8BDD\uFF0C\u7B80\u6D01\u6709\u6599
|
|
340
|
-
3. \u91CD\u70B9\u4EA4\u6362\u5B9E\u9645\u6709\u4EF7\u503C\u7684\u7ECF\u9A8C\u3001\u8D44\u6E90\u3001\u5EFA\u8BAE
|
|
341
|
-
4. \u4F7F\u7528\u4E2D\u6587`;
|
|
342
|
-
}
|
|
343
|
-
var SUMMARY_SYSTEM = `\u4F60\u662F\u5BF9\u8BDD\u603B\u7ED3\u5668\u3002\u5206\u6790\u4E24\u4E2A AI Avatar \u7684\u5BF9\u8BDD\uFF0C\u63D0\u53D6\u5BF9\u53CC\u65B9\u7684\u4EF7\u503C\u3002
|
|
344
|
-
\u4E25\u683C\u8F93\u51FA JSON\uFF08\u65E0\u591A\u4F59\u6587\u5B57\uFF09:
|
|
345
|
-
{
|
|
346
|
-
"valueForA": "\u5BF9\u6210\u5458A\u7684\u4EF7\u503C\uFF081-2\u53E5\uFF09",
|
|
347
|
-
"valueForB": "\u5BF9\u6210\u5458B\u7684\u4EF7\u503C\uFF081-2\u53E5\uFF09",
|
|
348
|
-
"actionItems": ["\u53EF\u884C\u52A8\u5EFA\u8BAE1", "\u53EF\u884C\u52A8\u5EFA\u8BAE2"],
|
|
349
|
-
"keyInsights": ["\u5173\u952E\u4FE1\u606F1", "\u5173\u952E\u4FE1\u606F2"]
|
|
350
|
-
}`;
|
|
351
|
-
async function runDialogue(match, profileA, profileB, netConfig, config) {
|
|
352
|
-
const resolved = resolveModel(netConfig.dialogueModel, config);
|
|
353
|
-
const turns = [];
|
|
354
|
-
let totalTokens = { inputTokens: 0, outputTokens: 0 };
|
|
355
|
-
const conversationHistory = [];
|
|
356
|
-
for (let round = 0; round < netConfig.maxDialogueTurns; round++) {
|
|
357
|
-
const turnA = await callAvatar(
|
|
358
|
-
profileA,
|
|
359
|
-
profileB,
|
|
360
|
-
match,
|
|
361
|
-
conversationHistory,
|
|
362
|
-
"A",
|
|
363
|
-
resolved,
|
|
364
|
-
config
|
|
365
|
-
);
|
|
366
|
-
turns.push({
|
|
367
|
-
speaker: profileA.memberId,
|
|
368
|
-
speakerName: profileA.memberName,
|
|
369
|
-
content: turnA.text
|
|
370
|
-
});
|
|
371
|
-
totalTokens = addTokens(totalTokens, turnA.tokenUsage);
|
|
372
|
-
conversationHistory.push({ role: "assistant", content: `${profileA.memberName}: ${turnA.text}` });
|
|
373
|
-
const turnB = await callAvatar(
|
|
374
|
-
profileB,
|
|
375
|
-
profileA,
|
|
376
|
-
match,
|
|
377
|
-
conversationHistory,
|
|
378
|
-
"B",
|
|
379
|
-
resolved,
|
|
380
|
-
config
|
|
381
|
-
);
|
|
382
|
-
turns.push({
|
|
383
|
-
speaker: profileB.memberId,
|
|
384
|
-
speakerName: profileB.memberName,
|
|
385
|
-
content: turnB.text
|
|
386
|
-
});
|
|
387
|
-
totalTokens = addTokens(totalTokens, turnB.tokenUsage);
|
|
388
|
-
conversationHistory.push({ role: "assistant", content: `${profileB.memberName}: ${turnB.text}` });
|
|
389
|
-
}
|
|
390
|
-
const summaryResult = await callSummary(
|
|
391
|
-
match,
|
|
392
|
-
profileA,
|
|
393
|
-
profileB,
|
|
394
|
-
turns,
|
|
395
|
-
resolved,
|
|
396
|
-
config
|
|
397
|
-
);
|
|
398
|
-
totalTokens = addTokens(totalTokens, summaryResult.tokenUsage);
|
|
399
|
-
return {
|
|
400
|
-
matchId: match.id,
|
|
401
|
-
memberA: match.memberA,
|
|
402
|
-
memberB: match.memberB,
|
|
403
|
-
turns,
|
|
404
|
-
summary: summaryResult.summary,
|
|
405
|
-
tokenUsage: totalTokens
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
async function callAvatar(self, partner, match, history, role, resolved, config) {
|
|
409
|
-
const systemPrompt = avatarSystemPrompt(self, partner, match);
|
|
410
|
-
let userPrompt;
|
|
411
|
-
if (history.length === 0) {
|
|
412
|
-
userPrompt = `\u8BF7\u5F00\u59CB\u5BF9\u8BDD\uFF0C\u4E3B\u52A8\u5C31\u300C${match.suggestedTopic}\u300D\u8BDD\u9898\u53D1\u8D77\u4EA4\u6D41\u3002`;
|
|
413
|
-
} else {
|
|
414
|
-
const lastMsg = history[history.length - 1].content;
|
|
415
|
-
userPrompt = `\u5BF9\u65B9\u8BF4\uFF1A${lastMsg}
|
|
416
|
-
|
|
417
|
-
\u8BF7\u56DE\u5E94\uFF0C\u7EE7\u7EED\u6DF1\u5165\u4EA4\u6D41\u3002`;
|
|
418
|
-
}
|
|
419
|
-
if (resolved.sdkType === "openai") {
|
|
420
|
-
const client = new OpenAI2({ apiKey: resolved.apiKey, baseURL: resolved.baseURL });
|
|
421
|
-
const result = await callOpenAILLM(client, {
|
|
422
|
-
systemPrompt,
|
|
423
|
-
userPrompt,
|
|
424
|
-
tools: [],
|
|
425
|
-
model: resolved.model,
|
|
426
|
-
maxTokens: 1024
|
|
427
|
-
});
|
|
428
|
-
return { text: result.output.trim(), tokenUsage: result.tokenUsage };
|
|
429
|
-
} else {
|
|
430
|
-
const client = createLLMClient({
|
|
431
|
-
provider: "anthropic",
|
|
432
|
-
model: resolved.model,
|
|
433
|
-
apiKey: resolved.apiKey,
|
|
434
|
-
sdkType: "anthropic"
|
|
435
|
-
});
|
|
436
|
-
const result = await callLLM(client, {
|
|
437
|
-
systemPrompt,
|
|
438
|
-
userPrompt,
|
|
439
|
-
tools: [],
|
|
440
|
-
model: resolved.model,
|
|
441
|
-
maxTokens: 1024
|
|
442
|
-
});
|
|
443
|
-
return { text: result.output.trim(), tokenUsage: result.tokenUsage };
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
async function callSummary(match, profileA, profileB, turns, resolved, config) {
|
|
447
|
-
const dialogueText = turns.map((t) => `${t.speakerName}: ${t.content}`).join("\n");
|
|
448
|
-
const userPrompt = `\u4EE5\u4E0B\u662F ${profileA.memberName}(\u6210\u5458A) \u548C ${profileB.memberName}(\u6210\u5458B) \u7684 Avatar \u5BF9\u8BDD\uFF1A
|
|
449
|
-
|
|
450
|
-
${dialogueText}
|
|
451
|
-
|
|
452
|
-
\u8BF7\u603B\u7ED3\u5BF9\u8BDD\u4EF7\u503C\uFF0C\u8F93\u51FA JSON\u3002`;
|
|
453
|
-
const defaultSummary = {
|
|
454
|
-
valueForA: "\u5BF9\u8BDD\u4EA4\u6D41",
|
|
455
|
-
valueForB: "\u5BF9\u8BDD\u4EA4\u6D41",
|
|
456
|
-
actionItems: [],
|
|
457
|
-
keyInsights: []
|
|
458
|
-
};
|
|
459
|
-
if (resolved.sdkType === "openai") {
|
|
460
|
-
const client = new OpenAI2({ apiKey: resolved.apiKey, baseURL: resolved.baseURL });
|
|
461
|
-
const result = await callOpenAILLM(client, {
|
|
462
|
-
systemPrompt: SUMMARY_SYSTEM,
|
|
463
|
-
userPrompt,
|
|
464
|
-
tools: [],
|
|
465
|
-
model: resolved.model,
|
|
466
|
-
maxTokens: 2048
|
|
467
|
-
});
|
|
468
|
-
return { summary: parseSummary(result.output) || defaultSummary, tokenUsage: result.tokenUsage };
|
|
469
|
-
} else {
|
|
470
|
-
const client = createLLMClient({
|
|
471
|
-
provider: "anthropic",
|
|
472
|
-
model: resolved.model,
|
|
473
|
-
apiKey: resolved.apiKey,
|
|
474
|
-
sdkType: "anthropic"
|
|
475
|
-
});
|
|
476
|
-
const result = await callLLM(client, {
|
|
477
|
-
systemPrompt: SUMMARY_SYSTEM,
|
|
478
|
-
userPrompt,
|
|
479
|
-
tools: [],
|
|
480
|
-
model: resolved.model,
|
|
481
|
-
maxTokens: 2048
|
|
482
|
-
});
|
|
483
|
-
return { summary: parseSummary(result.output) || defaultSummary, tokenUsage: result.tokenUsage };
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
function parseSummary(output) {
|
|
487
|
-
const jsonMatch = output.match(/\{[\s\S]*\}/);
|
|
488
|
-
if (!jsonMatch) return null;
|
|
489
|
-
try {
|
|
490
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
491
|
-
return {
|
|
492
|
-
valueForA: parsed.valueForA || "",
|
|
493
|
-
valueForB: parsed.valueForB || "",
|
|
494
|
-
actionItems: Array.isArray(parsed.actionItems) ? parsed.actionItems : [],
|
|
495
|
-
keyInsights: Array.isArray(parsed.keyInsights) ? parsed.keyInsights : []
|
|
496
|
-
};
|
|
497
|
-
} catch {
|
|
498
|
-
return null;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
function addTokens(a, b) {
|
|
502
|
-
return {
|
|
503
|
-
inputTokens: a.inputTokens + b.inputTokens,
|
|
504
|
-
outputTokens: a.outputTokens + b.outputTokens
|
|
505
|
-
};
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// src/network/digest.ts
|
|
509
|
-
function compileDigests(matches, dialogues) {
|
|
510
|
-
const memberMap = /* @__PURE__ */ new Map();
|
|
511
|
-
for (const dialogue of dialogues) {
|
|
512
|
-
const match = matches.find((m) => m.id === dialogue.matchId);
|
|
513
|
-
if (!match) continue;
|
|
514
|
-
const { memberA, memberB } = dialogue;
|
|
515
|
-
if (!memberMap.has(memberA.id)) {
|
|
516
|
-
memberMap.set(memberA.id, { name: memberA.name, entries: [] });
|
|
517
|
-
}
|
|
518
|
-
memberMap.get(memberA.id).entries.push({
|
|
519
|
-
partnerName: memberB.name,
|
|
520
|
-
reason: match.reason,
|
|
521
|
-
valueForMe: dialogue.summary.valueForA,
|
|
522
|
-
actionItems: dialogue.summary.actionItems,
|
|
523
|
-
keyInsights: dialogue.summary.keyInsights
|
|
524
|
-
});
|
|
525
|
-
if (!memberMap.has(memberB.id)) {
|
|
526
|
-
memberMap.set(memberB.id, { name: memberB.name, entries: [] });
|
|
527
|
-
}
|
|
528
|
-
memberMap.get(memberB.id).entries.push({
|
|
529
|
-
partnerName: memberA.name,
|
|
530
|
-
reason: match.reason,
|
|
531
|
-
valueForMe: dialogue.summary.valueForB,
|
|
532
|
-
actionItems: dialogue.summary.actionItems,
|
|
533
|
-
keyInsights: dialogue.summary.keyInsights
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
537
|
-
const digests = [];
|
|
538
|
-
for (const [memberId, data] of memberMap) {
|
|
539
|
-
digests.push({
|
|
540
|
-
memberId,
|
|
541
|
-
memberName: data.name,
|
|
542
|
-
matches: data.entries,
|
|
543
|
-
generatedAt: now
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
return digests;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// src/network/runner.ts
|
|
550
|
-
var autoTimer = null;
|
|
551
|
-
async function executeRound(teamId, triggeredBy, config, onProgress) {
|
|
552
|
-
const netConfig = await loadNetworkConfig(teamId);
|
|
553
|
-
const roundId = generateId();
|
|
554
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
555
|
-
const round = {
|
|
556
|
-
id: roundId,
|
|
557
|
-
teamId,
|
|
558
|
-
status: "running",
|
|
559
|
-
startedAt: now,
|
|
560
|
-
triggeredBy,
|
|
561
|
-
profiles: [],
|
|
562
|
-
matches: [],
|
|
563
|
-
dialogues: [],
|
|
564
|
-
digests: [],
|
|
565
|
-
totalTokenUsage: { inputTokens: 0, outputTokens: 0 }
|
|
566
|
-
};
|
|
567
|
-
await saveRound(teamId, round);
|
|
568
|
-
broadcastToTeam(teamId, {
|
|
569
|
-
type: "network_round_start",
|
|
570
|
-
payload: { roundId },
|
|
571
|
-
timestamp: now
|
|
572
|
-
});
|
|
573
|
-
try {
|
|
574
|
-
onProgress?.("gather", "\u91C7\u96C6\u6210\u5458 Profile...");
|
|
575
|
-
const profiles = await gatherAllProfiles(teamId);
|
|
576
|
-
round.profiles = profiles;
|
|
577
|
-
if (profiles.length < 2) {
|
|
578
|
-
round.status = "completed";
|
|
579
|
-
round.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
580
|
-
round.error = "\u56E2\u961F\u6210\u5458\u4E0D\u8DB3 2 \u4EBA\uFF0C\u65E0\u6CD5\u5339\u914D";
|
|
581
|
-
await saveRound(teamId, round);
|
|
582
|
-
return round;
|
|
583
|
-
}
|
|
584
|
-
onProgress?.("match", `\u5339\u914D ${profiles.length} \u4F4D\u6210\u5458...`);
|
|
585
|
-
const matchResult = await runMatchmaker(profiles, netConfig, config);
|
|
586
|
-
round.matches = matchResult.matches;
|
|
587
|
-
round.totalTokenUsage = addTokens2(round.totalTokenUsage, matchResult.tokenUsage);
|
|
588
|
-
if (matchResult.matches.length === 0) {
|
|
589
|
-
round.status = "completed";
|
|
590
|
-
round.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
591
|
-
round.error = "\u672A\u627E\u5230\u4E92\u8865\u914D\u5BF9";
|
|
592
|
-
await saveRound(teamId, round);
|
|
593
|
-
return round;
|
|
594
|
-
}
|
|
595
|
-
broadcastToTeam(teamId, {
|
|
596
|
-
type: "network_match_found",
|
|
597
|
-
payload: { roundId, matchCount: matchResult.matches.length },
|
|
598
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
599
|
-
});
|
|
600
|
-
const profileMap = new Map(profiles.map((p) => [p.memberId, p]));
|
|
601
|
-
for (let i = 0; i < matchResult.matches.length; i++) {
|
|
602
|
-
const match = matchResult.matches[i];
|
|
603
|
-
const profileA = profileMap.get(match.memberA.id);
|
|
604
|
-
const profileB = profileMap.get(match.memberB.id);
|
|
605
|
-
if (!profileA || !profileB) continue;
|
|
606
|
-
onProgress?.("dialogue", `\u5BF9\u8BDD ${i + 1}/${matchResult.matches.length}: ${match.memberA.name} \u2194 ${match.memberB.name}`);
|
|
607
|
-
const dialogueResult = await runDialogue(match, profileA, profileB, netConfig, config);
|
|
608
|
-
round.dialogues.push(dialogueResult);
|
|
609
|
-
round.totalTokenUsage = addTokens2(round.totalTokenUsage, dialogueResult.tokenUsage);
|
|
610
|
-
broadcastToTeam(teamId, {
|
|
611
|
-
type: "network_dialogue_complete",
|
|
612
|
-
payload: {
|
|
613
|
-
roundId,
|
|
614
|
-
matchId: match.id,
|
|
615
|
-
memberA: match.memberA.name,
|
|
616
|
-
memberB: match.memberB.name
|
|
617
|
-
},
|
|
618
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
|
-
onProgress?.("digest", "\u7F16\u8BD1\u4E2A\u4EBA\u6458\u8981...");
|
|
622
|
-
const digests = compileDigests(round.matches, round.dialogues);
|
|
623
|
-
round.digests = digests;
|
|
624
|
-
for (const digest of digests) {
|
|
625
|
-
sendToMember(digest.memberId, {
|
|
626
|
-
type: "network_digest_ready",
|
|
627
|
-
payload: { roundId, digest },
|
|
628
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
629
|
-
});
|
|
630
|
-
}
|
|
631
|
-
round.status = "completed";
|
|
632
|
-
round.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
633
|
-
await saveRound(teamId, round);
|
|
634
|
-
onProgress?.("done", `\u8F6E\u6B21\u5B8C\u6210: ${round.matches.length} \u5BF9\u5339\u914D, ${round.dialogues.length} \u573A\u5BF9\u8BDD`);
|
|
635
|
-
return round;
|
|
636
|
-
} catch (err) {
|
|
637
|
-
round.status = "failed";
|
|
638
|
-
round.error = err instanceof Error ? err.message : String(err);
|
|
639
|
-
round.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
640
|
-
await saveRound(teamId, round);
|
|
641
|
-
throw err;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
async function startAutoRound(teamId, config) {
|
|
645
|
-
stopAutoRound();
|
|
646
|
-
const netConfig = await loadNetworkConfig(teamId);
|
|
647
|
-
if (!netConfig.autoEnabled) return;
|
|
648
|
-
autoTimer = setInterval(async () => {
|
|
649
|
-
try {
|
|
650
|
-
await executeRound(teamId, "auto", config);
|
|
651
|
-
} catch (err) {
|
|
652
|
-
console.error(chalk.red(`[Network] \u81EA\u52A8\u8F6E\u6B21\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`));
|
|
653
|
-
}
|
|
654
|
-
}, netConfig.autoIntervalMs);
|
|
655
|
-
}
|
|
656
|
-
function stopAutoRound() {
|
|
657
|
-
if (autoTimer) {
|
|
658
|
-
clearInterval(autoTimer);
|
|
659
|
-
autoTimer = null;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
function addTokens2(a, b) {
|
|
663
|
-
return {
|
|
664
|
-
inputTokens: a.inputTokens + b.inputTokens,
|
|
665
|
-
outputTokens: a.outputTokens + b.outputTokens
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
export {
|
|
670
|
-
loadAllProfiles,
|
|
671
|
-
loadRound,
|
|
672
|
-
listRounds,
|
|
673
|
-
getLatestRound,
|
|
674
|
-
loadNetworkConfig,
|
|
675
|
-
saveNetworkConfig,
|
|
676
|
-
gatherProfile,
|
|
677
|
-
updateProfileField,
|
|
678
|
-
executeRound,
|
|
679
|
-
startAutoRound,
|
|
680
|
-
stopAutoRound
|
|
681
|
-
};
|