@ycodium-ai/plugin-team 0.2.3576 → 0.2.3608
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/assets/ui.js +11 -11
- package/dist/index.js +281 -79
- package/locales/en.json +5 -0
- package/locales/zh-CN.json +5 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -7268,6 +7268,7 @@ async function createGoalThread(ctx, goal, thread) {
|
|
|
7268
7268
|
requestId: `thread:${thread.threadId}`,
|
|
7269
7269
|
threadId: thread.threadId,
|
|
7270
7270
|
projectId: goal.projectId,
|
|
7271
|
+
memberId: thread.memberId,
|
|
7271
7272
|
title: goalThreadTitle(goal, thread.name),
|
|
7272
7273
|
...thread.selection,
|
|
7273
7274
|
// 有意写死、不读默认档:带团队的 AI 要无人值守地干活,成员子会话按 YCO-337 只能与负责人同档或更严。
|
|
@@ -7290,6 +7291,7 @@ async function createTeamThread(ctx, thread) {
|
|
|
7290
7291
|
requestId: `thread:${thread.threadId}`,
|
|
7291
7292
|
threadId: thread.threadId,
|
|
7292
7293
|
projectId: thread.projectId,
|
|
7294
|
+
memberId: thread.memberId,
|
|
7293
7295
|
title: thread.title,
|
|
7294
7296
|
...thread.selection,
|
|
7295
7297
|
runtimeMode: "full-access",
|
|
@@ -7411,6 +7413,16 @@ function registerGoalCommands(ctx, service2) {
|
|
|
7411
7413
|
// src/watch.ts
|
|
7412
7414
|
import * as NodeTimers from "node:timers";
|
|
7413
7415
|
|
|
7416
|
+
// src/domain/person.ts
|
|
7417
|
+
var personKey = (person) => person.kind === "account" ? `account:${person.userId}` : `local-owner:${person.environmentId}`;
|
|
7418
|
+
var samePerson = (a, b) => personKey(a) === personKey(b);
|
|
7419
|
+
var personOfMember = (member) => member.identity?.kind === "human" && member.identity.principal !== void 0 ? member.identity.principal : null;
|
|
7420
|
+
var currentPerson = async (invocation) => invocation.viewer === void 0 ? null : (await invocation.viewer.communication.people.current({})).person;
|
|
7421
|
+
async function personDisplayName(ctx, projectId, person, fallback) {
|
|
7422
|
+
const { items } = await ctx.communication.people.list({ projectId, limit: 100 });
|
|
7423
|
+
return items.find((item) => samePerson(item.person, person))?.displayName ?? fallback;
|
|
7424
|
+
}
|
|
7425
|
+
|
|
7414
7426
|
// src/domain/roster.ts
|
|
7415
7427
|
var MEMBER_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7416
7428
|
var MAX_NAME_LENGTH = 40;
|
|
@@ -7535,7 +7547,6 @@ var WorkIdentity = Struct({
|
|
|
7535
7547
|
/** 人的稳定键(见 personKey),界面拿它到快照的人名表里找名字。 */
|
|
7536
7548
|
personKey: optionalKey2(String4)
|
|
7537
7549
|
});
|
|
7538
|
-
var personKey = (principal) => principal.kind === "account" ? `account:${principal.userId}` : `local-owner:${principal.environmentId}`;
|
|
7539
7550
|
var workIdentity = (value) => ({
|
|
7540
7551
|
kind: value.kind,
|
|
7541
7552
|
...value.principalId === void 0 ? {} : { principalId: value.principalId },
|
|
@@ -9045,6 +9056,67 @@ function createRosterService(ctx, options = {}) {
|
|
|
9045
9056
|
|
|
9046
9057
|
// src/runtime/deliver.ts
|
|
9047
9058
|
import * as NodeCrypto from "node:crypto";
|
|
9059
|
+
|
|
9060
|
+
// ../../packages/ycodium-system-text/src/systemText.ts
|
|
9061
|
+
var SYSTEM_NOTIFICATION_OPEN_TAG = "<ycodium-system>";
|
|
9062
|
+
var SYSTEM_NOTIFICATION_CLOSE_TAG = "</ycodium-system>";
|
|
9063
|
+
var isSystemNotificationText = (text) => text.startsWith(SYSTEM_NOTIFICATION_OPEN_TAG);
|
|
9064
|
+
var rendersAsSystemMessage = (text) => isSystemNotificationText(text) && !(isPresetPrefixMessage(text) && text.includes(PRESET_PREFIX_CLOSE) && parsePresetPrefixText(text) === null);
|
|
9065
|
+
var FIRST_BLOCK_START = `^(?:${SYSTEM_NOTIFICATION_OPEN_TAG}\\n)?`;
|
|
9066
|
+
var PRESET_PREFIX_MESSAGE_START = `${SYSTEM_NOTIFICATION_OPEN_TAG}
|
|
9067
|
+
<preset-prefix `;
|
|
9068
|
+
var isPresetPrefixMessage = (text) => text.startsWith(PRESET_PREFIX_MESSAGE_START);
|
|
9069
|
+
var SYSTEM_TEXT_ESCAPED_ATTRIBUTE = 'esc="1"';
|
|
9070
|
+
var escapeSystemText = (text) => text.replace(/&/g, "&").replace(/</g, "<");
|
|
9071
|
+
var SYSTEM_TEXT_MAX_ESCAPE_GROWTH = "&".length;
|
|
9072
|
+
var escapeSystemAttribute = (text) => escapeSystemText(text).replace(/>/g, ">").replace(/"/g, """).replace(/\r/g, " ").replace(/\n/g, " ");
|
|
9073
|
+
var ESCAPED_BLOCK_NAMES = [
|
|
9074
|
+
"thread-response",
|
|
9075
|
+
"thread-handover",
|
|
9076
|
+
"scheduled-wake",
|
|
9077
|
+
"plugin-wake"
|
|
9078
|
+
];
|
|
9079
|
+
var escapedBlockOpenTag = (name, attributes) => `<${name} ${[
|
|
9080
|
+
...attributes.map(([key, value]) => `${key}="${escapeSystemAttribute(value)}"`),
|
|
9081
|
+
SYSTEM_TEXT_ESCAPED_ATTRIBUTE
|
|
9082
|
+
].join(" ")}>`;
|
|
9083
|
+
var ESCAPED_OPEN_LINE_PATTERN = new RegExp(
|
|
9084
|
+
`^<(?:${ESCAPED_BLOCK_NAMES.join("|")})(?:\\s[^>]*)? ${SYSTEM_TEXT_ESCAPED_ATTRIBUTE}>$`
|
|
9085
|
+
);
|
|
9086
|
+
var PRESET_PREFIX_CLOSE = `
|
|
9087
|
+
</preset-prefix>
|
|
9088
|
+
${SYSTEM_NOTIFICATION_CLOSE_TAG}`;
|
|
9089
|
+
var PRESET_PREFIX_PATTERN = new RegExp(
|
|
9090
|
+
`^${SYSTEM_NOTIFICATION_OPEN_TAG}\\n<preset-prefix id="([^"]*)">\\n([\\s\\S]*?)\\n</preset-prefix>\\n${SYSTEM_NOTIFICATION_CLOSE_TAG}(?:\\n\\n([\\s\\S]*))?$`
|
|
9091
|
+
);
|
|
9092
|
+
var parsePresetPrefixText = (text) => {
|
|
9093
|
+
if (text.split(PRESET_PREFIX_CLOSE).length !== 2) return null;
|
|
9094
|
+
const match7 = PRESET_PREFIX_PATTERN.exec(text);
|
|
9095
|
+
if (match7 === null) return null;
|
|
9096
|
+
const [, presetId, prefix, body] = match7;
|
|
9097
|
+
if (!presetId) return null;
|
|
9098
|
+
return { presetId, prefix: prefix ?? "", body: body ?? "" };
|
|
9099
|
+
};
|
|
9100
|
+
var userSpokenText = (text) => {
|
|
9101
|
+
if (!rendersAsSystemMessage(text)) return text;
|
|
9102
|
+
return parsePresetPrefixText(text)?.body || null;
|
|
9103
|
+
};
|
|
9104
|
+
var formatPluginWakeText = (input) => [
|
|
9105
|
+
SYSTEM_NOTIFICATION_OPEN_TAG,
|
|
9106
|
+
escapedBlockOpenTag("plugin-wake", [
|
|
9107
|
+
["plugin", input.pluginId],
|
|
9108
|
+
["reason", input.reason],
|
|
9109
|
+
...input.item ? [["item", input.item]] : []
|
|
9110
|
+
]),
|
|
9111
|
+
escapeSystemText(input.text),
|
|
9112
|
+
"</plugin-wake>",
|
|
9113
|
+
SYSTEM_NOTIFICATION_CLOSE_TAG
|
|
9114
|
+
].join("\n");
|
|
9115
|
+
var PLUGIN_WAKE_PATTERN = new RegExp(
|
|
9116
|
+
`${FIRST_BLOCK_START}<plugin-wake plugin="([^"]+)" reason="([^"]+)"(?: item="([^"]+)")? ${SYSTEM_TEXT_ESCAPED_ATTRIBUTE}>\\n[\\s\\S]*?\\n</plugin-wake>`
|
|
9117
|
+
);
|
|
9118
|
+
|
|
9119
|
+
// src/runtime/deliver.ts
|
|
9048
9120
|
var worktreeSetupSentence = async (ctx, projectId, branch) => {
|
|
9049
9121
|
const intro = `You are in your own newly created worktree on branch ${branch}.`;
|
|
9050
9122
|
const project2 = await ctx.projects.get({ projectId }).catch(() => null);
|
|
@@ -9053,6 +9125,12 @@ var worktreeSetupSentence = async (ctx, projectId, branch) => {
|
|
|
9053
9125
|
return `${intro} Install dependencies according to the project's instructions before starting work.`;
|
|
9054
9126
|
return `${intro} If dependencies are missing, install them before starting work. This project defines a setup command for that: ${setup.command}; run it from the worktree root with the environment variables YCODIUM_PROJECT_ROOT set to "${project2.workspaceRoot}" and YCODIUM_WORKTREE_PATH set to this worktree's path. If it fails with "could not lock config file", wait a moment and run it again.`;
|
|
9055
9127
|
};
|
|
9128
|
+
var teamWakeText = (display, text) => formatPluginWakeText({
|
|
9129
|
+
pluginId: "team",
|
|
9130
|
+
reason: display.reason,
|
|
9131
|
+
item: display.sequenceId === void 0 ? void 0 : `W${display.sequenceId}`,
|
|
9132
|
+
text
|
|
9133
|
+
});
|
|
9056
9134
|
var stableHash = (key) => NodeCrypto.createHash("sha256").update(key).digest("hex").slice(0, 32);
|
|
9057
9135
|
var memberWorktreeBranch = (name, threadId) => {
|
|
9058
9136
|
const slug = Array.from(
|
|
@@ -9104,7 +9182,7 @@ async function deliverWake(ctx, input) {
|
|
|
9104
9182
|
message: {
|
|
9105
9183
|
messageId: input.messageId,
|
|
9106
9184
|
role: "user",
|
|
9107
|
-
text,
|
|
9185
|
+
text: teamWakeText(input.wake, text),
|
|
9108
9186
|
attachments: []
|
|
9109
9187
|
},
|
|
9110
9188
|
modelSelection: execution.modelSelection,
|
|
@@ -9141,9 +9219,12 @@ async function deliverWake(ctx, input) {
|
|
|
9141
9219
|
requestId: input.requestId,
|
|
9142
9220
|
message: {
|
|
9143
9221
|
...turn.message,
|
|
9144
|
-
text:
|
|
9222
|
+
text: teamWakeText(
|
|
9223
|
+
input.wake,
|
|
9224
|
+
`${text}
|
|
9145
9225
|
|
|
9146
9226
|
${await worktreeSetupSentence(ctx, input.projectId, branch)}`
|
|
9227
|
+
)
|
|
9147
9228
|
},
|
|
9148
9229
|
bootstrap: {
|
|
9149
9230
|
prepareWorktree: {
|
|
@@ -9179,7 +9260,8 @@ ${await worktreeSetupSentence(ctx, input.projectId, branch)}`
|
|
|
9179
9260
|
recipient: { threadId: worktree.leadThreadId },
|
|
9180
9261
|
requestId: `team-worktree-report:${threadId}`,
|
|
9181
9262
|
messageId: `team-worktree-report-msg:${threadId}`,
|
|
9182
|
-
text: `Could not create a worktree for member ${await worktree.name()} (threadId ${threadId}): ${failure.reason}. They will work in the project folder for now
|
|
9263
|
+
text: `Could not create a worktree for member ${await worktree.name()} (threadId ${threadId}): ${failure.reason}. They will work in the project folder for now.`,
|
|
9264
|
+
wake: { reason: "notice" }
|
|
9183
9265
|
});
|
|
9184
9266
|
if (!reported) throw new Error("Member worktree failure could not be reported to the lead");
|
|
9185
9267
|
const receipt = await worktree.lane.events.append({
|
|
@@ -9487,6 +9569,10 @@ var en_default = {
|
|
|
9487
9569
|
kindAgentHint: "Runs with the provider and model you pick when the machine is this one. A member set to another machine fails its trial run: set it back to this machine, or skip the trial run, and it runs on this machine with the project's default model.",
|
|
9488
9570
|
kindRemoteHint: "An agent that connects from another machine with its own credentials.",
|
|
9489
9571
|
kindPersonHint: "A teammate. People are listed as members but do not run sessions.",
|
|
9572
|
+
thisIsMe: "This is me",
|
|
9573
|
+
thisIsMeHint: "When someone @-mentions this member in a team group, the message goes to your Sent to me.",
|
|
9574
|
+
boundToOther: "This member is another person. Only they can change this.",
|
|
9575
|
+
you: "You",
|
|
9490
9576
|
name: "Name",
|
|
9491
9577
|
memberTitle: "Title",
|
|
9492
9578
|
responsibility: "Responsibility",
|
|
@@ -9533,6 +9619,7 @@ var en_default = {
|
|
|
9533
9619
|
noDefaultModel: "This project has no default model. Choose one in the project settings under New threads \u2192 Model, then try again.",
|
|
9534
9620
|
modelUnavailable: "The project's default model isn't available on this machine. Check the provider, or choose another model in the project settings under New threads \u2192 Model.",
|
|
9535
9621
|
duplicateMember: "Another member already has this name or remote agent. Rename or remove that member first.",
|
|
9622
|
+
alreadyYou: "You are already {{name}} on this roster. Clear \u201CThis is me\u201D on {{name}} first.",
|
|
9536
9623
|
staleVersion: "This member was changed elsewhere and has been reloaded. Review it and save again.",
|
|
9537
9624
|
notFound: "This member no longer exists.",
|
|
9538
9625
|
invalidState: "The member's state was changed elsewhere and has been reloaded.",
|
|
@@ -10035,7 +10122,10 @@ function createGoalService(ctx, rosterService, options = {}) {
|
|
|
10035
10122
|
message: {
|
|
10036
10123
|
messageId: `team-lead-message:${goal.projectId}:${goal.goalId}`,
|
|
10037
10124
|
role: "user",
|
|
10038
|
-
text:
|
|
10125
|
+
text: teamWakeText(
|
|
10126
|
+
{ reason: "instructions" },
|
|
10127
|
+
leadBrief(goal, roster, { engineMembers: view.stored?.version === 2 })
|
|
10128
|
+
),
|
|
10039
10129
|
attachments: []
|
|
10040
10130
|
},
|
|
10041
10131
|
modelSelection: selections.get(goal.leadMemberId).modelSelection,
|
|
@@ -10090,6 +10180,7 @@ import {
|
|
|
10090
10180
|
MEMBER_RESPONSIBILITY_MAX,
|
|
10091
10181
|
MEMBER_TITLE_MAX
|
|
10092
10182
|
} from "@ycodium-ai/plugin-api";
|
|
10183
|
+
var MAX_MEMBER_NAME_LENGTH = MEMBER_NAME_MAX;
|
|
10093
10184
|
var MemberAvatar = Struct({ pattern: String4, color: String4 });
|
|
10094
10185
|
var AgentChoice = Struct({
|
|
10095
10186
|
environmentId: String4,
|
|
@@ -10104,6 +10195,8 @@ var MemberRow = Struct({
|
|
|
10104
10195
|
avatar: NullOr(MemberAvatar),
|
|
10105
10196
|
/** 远端 agent 成员绑的主体;本机 agent 与人是 null。 */
|
|
10106
10197
|
remotePrincipalId: NullOr(String4),
|
|
10198
|
+
/** 人成员绑着的人是不是正在看这一页的人;没绑就没有这一项。 */
|
|
10199
|
+
person: optionalKey2(Literals(["me", "other"])),
|
|
10107
10200
|
agent: NullOr(
|
|
10108
10201
|
Struct({
|
|
10109
10202
|
environmentId: String4,
|
|
@@ -10158,7 +10251,9 @@ var CreateMemberInput = Struct({
|
|
|
10158
10251
|
avatar: optionalKey2(MemberAvatar),
|
|
10159
10252
|
/** 给了就是远端 agent:绑这个主体。 */
|
|
10160
10253
|
remotePrincipalId: optionalKey2(String4),
|
|
10161
|
-
agent: optionalKey2(AgentChoice)
|
|
10254
|
+
agent: optionalKey2(AgentChoice),
|
|
10255
|
+
/** 人成员「这是我」:绑到发起这次调用的人。 */
|
|
10256
|
+
bindToMe: optionalKey2(Boolean3)
|
|
10162
10257
|
});
|
|
10163
10258
|
var UpdateMemberInput = Struct({
|
|
10164
10259
|
...projectAndRequest,
|
|
@@ -10168,7 +10263,9 @@ var UpdateMemberInput = Struct({
|
|
|
10168
10263
|
...memberTextFields,
|
|
10169
10264
|
avatar: optionalKey2(MemberAvatar),
|
|
10170
10265
|
clearAvatar: optionalKey2(Boolean3),
|
|
10171
|
-
agent: optionalKey2(AgentChoice)
|
|
10266
|
+
agent: optionalKey2(AgentChoice),
|
|
10267
|
+
/** 人成员「这是我」:`true` 绑到发起这次调用的人,`false` 解绑。 */
|
|
10268
|
+
bindToMe: optionalKey2(Boolean3)
|
|
10172
10269
|
});
|
|
10173
10270
|
var MemberRefInput = Struct({ ...projectAndRequest, memberId: String4 });
|
|
10174
10271
|
var ImportRosterInput = Struct({ projectId: String4 });
|
|
@@ -10646,24 +10743,30 @@ function startCoordinatorRuntime(ctx, deps) {
|
|
|
10646
10743
|
}
|
|
10647
10744
|
|
|
10648
10745
|
// src/members/snapshot.ts
|
|
10649
|
-
var toMemberRow = (member, trial) =>
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
|
|
10654
|
-
|
|
10655
|
-
|
|
10656
|
-
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10660
|
-
|
|
10661
|
-
|
|
10662
|
-
|
|
10663
|
-
|
|
10664
|
-
|
|
10665
|
-
|
|
10666
|
-
}
|
|
10746
|
+
var toMemberRow = (member, trial, viewer) => {
|
|
10747
|
+
const person = personOfMember(member);
|
|
10748
|
+
return {
|
|
10749
|
+
memberId: member.memberId,
|
|
10750
|
+
kind: member.kind,
|
|
10751
|
+
name: member.name,
|
|
10752
|
+
title: member.title,
|
|
10753
|
+
responsibility: member.responsibility,
|
|
10754
|
+
avatar: member.avatar === null ? null : { pattern: member.avatar.pattern, color: member.avatar.color },
|
|
10755
|
+
remotePrincipalId: member.identity?.kind === "remote-agent" ? member.identity.principalId : null,
|
|
10756
|
+
...person === null ? {} : {
|
|
10757
|
+
person: viewer !== null && samePerson(person, viewer) ? "me" : "other"
|
|
10758
|
+
},
|
|
10759
|
+
agent: member.agent === null ? null : {
|
|
10760
|
+
environmentId: member.agent.environmentId,
|
|
10761
|
+
instanceId: member.agent.modelSelection.instanceId,
|
|
10762
|
+
model: member.agent.modelSelection.model
|
|
10763
|
+
},
|
|
10764
|
+
hasInstructions: member.workInstructionsRevision !== null,
|
|
10765
|
+
version: member.version,
|
|
10766
|
+
removed: member.removedAt !== null,
|
|
10767
|
+
...trial === null ? {} : { trial }
|
|
10768
|
+
};
|
|
10769
|
+
};
|
|
10667
10770
|
var legacyOffer = (stored) => ({
|
|
10668
10771
|
revision: stored.roster.revision,
|
|
10669
10772
|
leadMemberId: stored.roster.leadMemberId,
|
|
@@ -10673,10 +10776,10 @@ var legacyOffer = (stored) => ({
|
|
|
10673
10776
|
principalId: member.principal?.principalId ?? null
|
|
10674
10777
|
}))
|
|
10675
10778
|
});
|
|
10676
|
-
function membersSnapshot(view, trialOf = () => null) {
|
|
10779
|
+
function membersSnapshot(view, trialOf = () => null, viewer = null) {
|
|
10677
10780
|
const { stored } = view;
|
|
10678
10781
|
return {
|
|
10679
|
-
members: view.members.map((member) => toMemberRow(member, trialOf(member.memberId))),
|
|
10782
|
+
members: view.members.map((member) => toMemberRow(member, trialOf(member.memberId), viewer)),
|
|
10680
10783
|
lead: {
|
|
10681
10784
|
memberId: stored?.version === 2 ? stored.roster.leadMemberId : null,
|
|
10682
10785
|
revision: stored?.roster.revision ?? 0
|
|
@@ -10999,10 +11102,18 @@ function registerMemberCommands(ctx, rosters, writer, trials2) {
|
|
|
10999
11102
|
name: "members",
|
|
11000
11103
|
scope: "read",
|
|
11001
11104
|
payloadSchema: payloadSchemaOf(ReadMembersInput),
|
|
11002
|
-
handle: async (payload) => {
|
|
11105
|
+
handle: async (payload, invocation) => {
|
|
11003
11106
|
const { projectId } = decodeReadMembers(payload);
|
|
11004
|
-
const [view, trial] = await Promise.all([
|
|
11005
|
-
|
|
11107
|
+
const [view, trial, viewer] = await Promise.all([
|
|
11108
|
+
rosters.inspect(projectId),
|
|
11109
|
+
trials2.get(),
|
|
11110
|
+
currentPerson(invocation)
|
|
11111
|
+
]);
|
|
11112
|
+
return membersSnapshot(
|
|
11113
|
+
view,
|
|
11114
|
+
(memberId) => trialViewOf(recordOf(trial, projectId, memberId)),
|
|
11115
|
+
viewer
|
|
11116
|
+
);
|
|
11006
11117
|
}
|
|
11007
11118
|
});
|
|
11008
11119
|
ctx.command({
|
|
@@ -11091,14 +11202,21 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
|
|
|
11091
11202
|
const serial = queue.run;
|
|
11092
11203
|
const asPerson = (commandType, handler) => (payload, invocation) => serial(async () => {
|
|
11093
11204
|
const person = invocation.asPerson;
|
|
11094
|
-
return person === void 0 ? rejectMember(commandType, "needs-person") : handler(payload, person.members);
|
|
11205
|
+
return person === void 0 ? rejectMember(commandType, "needs-person") : handler(payload, person.members, invocation);
|
|
11095
11206
|
});
|
|
11096
|
-
const
|
|
11207
|
+
const meOf = async (commandType, invocation) => await currentPerson(invocation) ?? rejectMember(commandType, "needs-person");
|
|
11208
|
+
const create = asPerson("createMember", async (payload, members, invocation) => {
|
|
11097
11209
|
const decoded = decodeCreate3(payload);
|
|
11098
11210
|
if (isNone2(decoded)) return rejectMember("createMember", "invalid-payload");
|
|
11099
11211
|
const input = decoded.value;
|
|
11100
|
-
if (input.kind === "human"
|
|
11212
|
+
if (input.kind === "human" ? input.agent !== void 0 || input.remotePrincipalId !== void 0 : input.bindToMe !== void 0)
|
|
11101
11213
|
return rejectMember("createMember", "invalid-payload");
|
|
11214
|
+
let me;
|
|
11215
|
+
if (input.bindToMe === true) {
|
|
11216
|
+
const found = await meOf("createMember", invocation);
|
|
11217
|
+
if ("code" in found) return found;
|
|
11218
|
+
me = found;
|
|
11219
|
+
}
|
|
11102
11220
|
const memberId = createdMemberId(input.projectId, input.requestId);
|
|
11103
11221
|
let agent;
|
|
11104
11222
|
if (input.kind === "agent") {
|
|
@@ -11125,17 +11243,29 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
|
|
|
11125
11243
|
...input.avatar === void 0 ? {} : { avatar: input.avatar },
|
|
11126
11244
|
...input.workInstructions === void 0 ? {} : { workInstructions: input.workInstructions },
|
|
11127
11245
|
...input.remotePrincipalId === void 0 ? {} : { identity: { kind: "remote-agent", principalId: input.remotePrincipalId } },
|
|
11246
|
+
...me === void 0 ? {} : { identity: { kind: "human", principal: me } },
|
|
11128
11247
|
...agent === void 0 ? {} : { agent }
|
|
11129
11248
|
})
|
|
11130
11249
|
);
|
|
11131
11250
|
return "code" in result2 ? result2 : written(result2);
|
|
11132
11251
|
});
|
|
11133
|
-
const update = asPerson("updateMember", async (payload, members) => {
|
|
11252
|
+
const update = asPerson("updateMember", async (payload, members, invocation) => {
|
|
11134
11253
|
const decoded = decodeUpdate3(payload);
|
|
11135
11254
|
if (isNone2(decoded)) return rejectMember("updateMember", "invalid-payload");
|
|
11136
11255
|
const input = decoded.value;
|
|
11137
11256
|
if (input.avatar !== void 0 && input.clearAvatar === true)
|
|
11138
11257
|
return rejectMember("updateMember", "invalid-payload");
|
|
11258
|
+
let identity2;
|
|
11259
|
+
if (input.bindToMe !== void 0) {
|
|
11260
|
+
const me = await meOf("updateMember", invocation);
|
|
11261
|
+
if ("code" in me) return me;
|
|
11262
|
+
const member = await findMember(ctx, input.projectId, input.memberId);
|
|
11263
|
+
if (member === null) return rejectMember("updateMember", "not-found");
|
|
11264
|
+
const held = personOfMember(member);
|
|
11265
|
+
if (held !== null && !samePerson(held, me))
|
|
11266
|
+
return rejectMember("updateMember", "bound-to-other");
|
|
11267
|
+
identity2 = input.bindToMe ? { kind: "human", principal: me } : null;
|
|
11268
|
+
}
|
|
11139
11269
|
const result2 = await refused(
|
|
11140
11270
|
"updateMember",
|
|
11141
11271
|
() => members.update({
|
|
@@ -11148,7 +11278,8 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
|
|
|
11148
11278
|
...input.responsibility === void 0 ? {} : { responsibility: input.responsibility },
|
|
11149
11279
|
...input.clearAvatar === true ? { avatar: null } : input.avatar === void 0 ? {} : { avatar: input.avatar },
|
|
11150
11280
|
...input.workInstructions === void 0 ? {} : { workInstructions: input.workInstructions },
|
|
11151
|
-
...input.agent === void 0 ? {} : { agent: toEngineAgent(input.agent) }
|
|
11281
|
+
...input.agent === void 0 ? {} : { agent: toEngineAgent(input.agent) },
|
|
11282
|
+
...identity2 === void 0 ? {} : { identity: identity2 }
|
|
11152
11283
|
})
|
|
11153
11284
|
);
|
|
11154
11285
|
return "code" in result2 ? result2 : written(result2);
|
|
@@ -11694,7 +11825,15 @@ function startGroupDeliveryRuntime(ctx, wakes, now3 = () => runPromise2(map5(now
|
|
|
11694
11825
|
};
|
|
11695
11826
|
ctx.reactor({
|
|
11696
11827
|
name: "team-group-delivery",
|
|
11697
|
-
|
|
11828
|
+
// 成员建出或改了(人点「这是我」绑上)也补扫:停在待绑定的人目标立刻投到人。
|
|
11829
|
+
events: [
|
|
11830
|
+
"communication.group-message-sent",
|
|
11831
|
+
"work.line-restored",
|
|
11832
|
+
"plugin.event-appended",
|
|
11833
|
+
"member.created",
|
|
11834
|
+
"member.updated",
|
|
11835
|
+
"member.restored"
|
|
11836
|
+
],
|
|
11698
11837
|
handle: (event) => {
|
|
11699
11838
|
const projectId = decodeProjectEvent(event.payload);
|
|
11700
11839
|
if (isSome2(projectId)) return sweep(projectId.value.projectId);
|
|
@@ -11792,6 +11931,7 @@ function startMemberBindingRuntime(ctx, goals, rosters, wakes, trials2) {
|
|
|
11792
11931
|
if (goal.workLineId !== void 0 && lead !== void 0)
|
|
11793
11932
|
await createTeamThread(ctx, {
|
|
11794
11933
|
projectId,
|
|
11934
|
+
memberId: member.memberId,
|
|
11795
11935
|
threadId,
|
|
11796
11936
|
parentThreadId: lead.threadId,
|
|
11797
11937
|
title: goalThreadTitle(goal, member.name),
|
|
@@ -11836,6 +11976,7 @@ function startMemberBindingRuntime(ctx, goals, rosters, wakes, trials2) {
|
|
|
11836
11976
|
recipient: { threadId: leadThreadId },
|
|
11837
11977
|
requestId: `team-member-unbound-notice:${key}`,
|
|
11838
11978
|
messageId: `team-member-unbound-notice-message:${key}`,
|
|
11979
|
+
wake: { reason: "notice" },
|
|
11839
11980
|
text: rebinding ? `Member ${member.name} (memberId ${member.memberId}) passed its trial run with the new setup but could not be moved onto it: ${failure.detail}. Work not yet handed to them waits until it is. Fix the cause, for example change their model with team_update_member; they are set up again within a couple of minutes.` : `Member ${member.name} (memberId ${member.memberId}) could not join this goal: ${failure.detail}. Work assigned to them waits until they join. Fix the cause, for example change their model with team_update_member; they are set up again within a couple of minutes.`
|
|
11840
11981
|
});
|
|
11841
11982
|
if (delivered) told.add(key);
|
|
@@ -12014,6 +12155,7 @@ function startMemberRemovalRuntime(ctx, goals, wakes) {
|
|
|
12014
12155
|
recipient: { threadId: lead },
|
|
12015
12156
|
requestId: `team-member-removed-notice:${key}`,
|
|
12016
12157
|
messageId: `team-member-removed-notice-message:${key}`,
|
|
12158
|
+
wake: { reason: "notice" },
|
|
12017
12159
|
text: [
|
|
12018
12160
|
`Member ${member.name} (memberId ${memberId}) was removed from this project's team.`,
|
|
12019
12161
|
`Work that had not reached them yet was taken off them and now has no assignee: ${list(mine(taken))}. Assign it to another member with work_update_item.`,
|
|
@@ -13305,6 +13447,7 @@ function startWakeRuntime(ctx, goals, options = {}) {
|
|
|
13305
13447
|
recipient: wake,
|
|
13306
13448
|
requestId: wakeRequestId(id),
|
|
13307
13449
|
messageId: `team-wake-msg:${id}`,
|
|
13450
|
+
wake: { reason: "work", sequenceId: wake.sequenceId },
|
|
13308
13451
|
memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees },
|
|
13309
13452
|
// 评论在收件人正在跑时插进当前这一轮,不排到这一轮结束(试跑 3:一轮 97 分钟,检查点落空)。
|
|
13310
13453
|
...wake.kind === "comment" ? { steer: true } : {},
|
|
@@ -13508,6 +13651,10 @@ function startRecoveryRuntime(ctx, goals, state, worktrees) {
|
|
|
13508
13651
|
requestId: `team-recovery:${id}:${plan.action}`,
|
|
13509
13652
|
messageId: `team-recovery-msg:${id}:${plan.action}`,
|
|
13510
13653
|
text: plan.text,
|
|
13654
|
+
// 续做与提醒是叫成员接着干活;告诉负责人谁停了是通知。
|
|
13655
|
+
wake: {
|
|
13656
|
+
reason: plan.action === "resume" || plan.action === "remind" ? "work" : "notice"
|
|
13657
|
+
},
|
|
13511
13658
|
memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees }
|
|
13512
13659
|
});
|
|
13513
13660
|
if (!delivered) continue;
|
|
@@ -13599,7 +13746,8 @@ fired:${fired.wakes.length}`);
|
|
|
13599
13746
|
recipient: { threadId },
|
|
13600
13747
|
requestId: `team-lead-checkin:${threadId}:${key}`,
|
|
13601
13748
|
messageId: `team-lead-checkin-message:${threadId}:${key}`,
|
|
13602
|
-
text: LEAD_CHECKIN_REMINDER
|
|
13749
|
+
text: LEAD_CHECKIN_REMINDER,
|
|
13750
|
+
wake: { reason: "check-in" }
|
|
13603
13751
|
});
|
|
13604
13752
|
}
|
|
13605
13753
|
};
|
|
@@ -14306,6 +14454,7 @@ function startHandbookRuntime(ctx, worktrees) {
|
|
|
14306
14454
|
messageId: `team-handbook-msg:${id}`,
|
|
14307
14455
|
// 成员闲着时被换版提醒叫醒,不能借机自己挑活:成员的提醒写死只确认、确认完就结束这一轮。
|
|
14308
14456
|
text: handbookReminder(release, seat.goal.leadMemberId === member.memberId),
|
|
14457
|
+
wake: { reason: "instructions" },
|
|
14309
14458
|
memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees.lane }
|
|
14310
14459
|
});
|
|
14311
14460
|
if (!delivered) continue;
|
|
@@ -15184,14 +15333,78 @@ function startLineNameMirror(ctx, queue) {
|
|
|
15184
15333
|
});
|
|
15185
15334
|
}
|
|
15186
15335
|
|
|
15336
|
+
// src/team/freeName.ts
|
|
15337
|
+
var NAME_RETRIES = 3;
|
|
15338
|
+
var nameTag = (seed, attempt) => attempt === 0 ? "" : ` #${stableHash(`${seed}${attempt}`).slice(0, 4)}`;
|
|
15339
|
+
var withNameTag = (name, tag2) => {
|
|
15340
|
+
const base = name.trim().slice(0, MAX_MEMBER_NAME_LENGTH);
|
|
15341
|
+
return tag2 === "" ? base : `${base.slice(0, MAX_MEMBER_NAME_LENGTH - tag2.length)}${tag2}`;
|
|
15342
|
+
};
|
|
15343
|
+
|
|
15344
|
+
// src/team/ownerMember.ts
|
|
15345
|
+
async function ownerOf(ctx, threadId) {
|
|
15346
|
+
const createdBy = (await ctx.threads.get({ threadId })).createdBy ?? null;
|
|
15347
|
+
const person = createdBy === null ? { kind: "local-owner", environmentId: ctx.environment.id } : { kind: "account", userId: createdBy.userId };
|
|
15348
|
+
return { person, createdName: createdBy?.displayName ?? null };
|
|
15349
|
+
}
|
|
15350
|
+
async function boundOwnerMember(ctx, projectId, threadId) {
|
|
15351
|
+
const { person } = await ownerOf(ctx, threadId);
|
|
15352
|
+
const { items } = await readPages(
|
|
15353
|
+
Number.POSITIVE_INFINITY,
|
|
15354
|
+
(page) => ctx.members.list({ projectId, ...page })
|
|
15355
|
+
);
|
|
15356
|
+
return items.find((row) => {
|
|
15357
|
+
const held = row.kind === "human" && row.removedAt === null ? personOfMember(row) : null;
|
|
15358
|
+
return held !== null && samePerson(held, person);
|
|
15359
|
+
})?.memberId ?? null;
|
|
15360
|
+
}
|
|
15361
|
+
async function ensureOwnerMember(ctx, projectId, threadId, chosen) {
|
|
15362
|
+
if (chosen !== null) return chosen;
|
|
15363
|
+
const memberId = `person:${stableHash(JSON.stringify([projectId, threadId])).slice(0, 24)}`;
|
|
15364
|
+
const mine = await findMember(ctx, projectId, memberId);
|
|
15365
|
+
if (mine !== null) return mine.removedAt === null ? memberId : null;
|
|
15366
|
+
const { person, createdName } = await ownerOf(ctx, threadId);
|
|
15367
|
+
const name = await personDisplayName(ctx, projectId, person, createdName);
|
|
15368
|
+
if (name === null) return null;
|
|
15369
|
+
for (let attempt = 0; ; attempt++) {
|
|
15370
|
+
const candidate = withNameTag(name, nameTag(threadId, attempt));
|
|
15371
|
+
try {
|
|
15372
|
+
await ctx.members.create({
|
|
15373
|
+
projectId,
|
|
15374
|
+
requestId: `team-owner-member:${mark(projectId, threadId, "owner")}:${attempt}`,
|
|
15375
|
+
memberId,
|
|
15376
|
+
kind: "human",
|
|
15377
|
+
name: candidate,
|
|
15378
|
+
identity: { kind: "human", principal: person }
|
|
15379
|
+
});
|
|
15380
|
+
return memberId;
|
|
15381
|
+
} catch (error) {
|
|
15382
|
+
const refusal = memberRefusal(error);
|
|
15383
|
+
if (refusal?.code !== "duplicate-member") throw error;
|
|
15384
|
+
const details = refusal.details;
|
|
15385
|
+
if (typeof details === "object" && details !== null && Reflect.get(details, "field") === "identity")
|
|
15386
|
+
return boundOwnerMember(ctx, projectId, threadId);
|
|
15387
|
+
if (attempt >= NAME_RETRIES) throw error;
|
|
15388
|
+
}
|
|
15389
|
+
}
|
|
15390
|
+
}
|
|
15391
|
+
|
|
15187
15392
|
// src/team/open.ts
|
|
15188
15393
|
var decodeOpen = decodeUnknownOption2(TeamOpenInput);
|
|
15394
|
+
var decodeOwner = decodeUnknownOption2(
|
|
15395
|
+
Struct({ ownerMemberId: NullOr(String4) })
|
|
15396
|
+
);
|
|
15189
15397
|
function statusOf2(trials2, projectId, member) {
|
|
15190
15398
|
if (member.kind === "human") return "human";
|
|
15191
15399
|
const view = trialViewOf(recordOf(trials2, projectId, member.memberId));
|
|
15192
15400
|
if (view === null) return "ready";
|
|
15193
15401
|
return view.status === "passed" || view.status === "overridden" ? "ready" : view.status === "failed" ? "trial-failed" : "trial-pending";
|
|
15194
15402
|
}
|
|
15403
|
+
function leadMemberName(leadName, title, tag2) {
|
|
15404
|
+
if (leadName !== void 0) return withNameTag(leadName, tag2);
|
|
15405
|
+
const tail = ` lead${tag2}`;
|
|
15406
|
+
return `${title.trim().slice(0, MAX_MEMBER_NAME_LENGTH - tail.length).trimEnd()}${tail}`.trim();
|
|
15407
|
+
}
|
|
15195
15408
|
var remotePrincipalOf2 = (member) => member.identity?.kind === "remote-agent" ? member.identity.principalId : null;
|
|
15196
15409
|
function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps), now3 = factTime) {
|
|
15197
15410
|
const lineIdOf = (projectId, threadId, requestId) => `wl-${mark(projectId, threadId, requestId).slice(0, 24)}`;
|
|
@@ -15211,9 +15424,8 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15211
15424
|
ctx.projections.getThreadExecution(threadId)
|
|
15212
15425
|
]);
|
|
15213
15426
|
if (execution === null) throw new TeamRuleError("not-local", teamMessage("notLocal"));
|
|
15214
|
-
const base = (leadName ?? `${shell.title} lead`).trim().slice(0, 40);
|
|
15215
15427
|
for (let attempt = 0; ; attempt++) {
|
|
15216
|
-
const name =
|
|
15428
|
+
const name = leadMemberName(leadName, shell.title, nameTag(threadId, attempt));
|
|
15217
15429
|
try {
|
|
15218
15430
|
await ctx.members.create({
|
|
15219
15431
|
projectId,
|
|
@@ -15228,7 +15440,7 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15228
15440
|
});
|
|
15229
15441
|
return memberId;
|
|
15230
15442
|
} catch (error) {
|
|
15231
|
-
if (hostRefusalCode(error) !== "duplicate-member" || attempt >=
|
|
15443
|
+
if (hostRefusalCode(error) !== "duplicate-member" || attempt >= NAME_RETRIES) throw error;
|
|
15232
15444
|
}
|
|
15233
15445
|
}
|
|
15234
15446
|
};
|
|
@@ -15265,6 +15477,17 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15265
15477
|
const local = rows.filter((row) => row.kind === "agent" && remotePrincipalOf2(row) === null);
|
|
15266
15478
|
const selections = await resolveLocalSelections(projectId, local);
|
|
15267
15479
|
const leadMemberId = await ensureLeadMember(projectId, callerThreadId, input.leadName);
|
|
15480
|
+
const ownerMemberId = await ensureOwnerMember(
|
|
15481
|
+
ctx,
|
|
15482
|
+
projectId,
|
|
15483
|
+
callerThreadId,
|
|
15484
|
+
match(decodeOwner(intent.input), {
|
|
15485
|
+
onNone: () => null,
|
|
15486
|
+
onSome: (recorded) => recorded.ownerMemberId
|
|
15487
|
+
})
|
|
15488
|
+
);
|
|
15489
|
+
const owner = ownerMemberId === null || rows.some((row) => row.memberId === ownerMemberId) ? null : await findMember(ctx, projectId, ownerMemberId);
|
|
15490
|
+
const team = owner === null ? rows : [owner, ...rows];
|
|
15268
15491
|
try {
|
|
15269
15492
|
const created = await ctx.work.lines.create({
|
|
15270
15493
|
projectId,
|
|
@@ -15272,7 +15495,7 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15272
15495
|
workLineId,
|
|
15273
15496
|
name,
|
|
15274
15497
|
leadMemberId,
|
|
15275
|
-
members: [leadMemberId, ...
|
|
15498
|
+
members: [leadMemberId, ...team.map((row) => row.memberId)],
|
|
15276
15499
|
threadId: callerThreadId
|
|
15277
15500
|
});
|
|
15278
15501
|
await ctx.events.append(baselineMirrored(projectId, workLineId, created.result.version));
|
|
@@ -15317,6 +15540,7 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15317
15540
|
for (const row of local) {
|
|
15318
15541
|
await createTeamThread(ctx, {
|
|
15319
15542
|
projectId,
|
|
15543
|
+
memberId: row.memberId,
|
|
15320
15544
|
threadId: teamThreadId(projectId, goalId, row.memberId),
|
|
15321
15545
|
parentThreadId: callerThreadId,
|
|
15322
15546
|
title: goalThreadTitle(goal, row.name),
|
|
@@ -15335,7 +15559,7 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15335
15559
|
});
|
|
15336
15560
|
await syncLineTitle(ctx, projectId, workLineId);
|
|
15337
15561
|
const trials2 = await deps.trials.get();
|
|
15338
|
-
const roster =
|
|
15562
|
+
const roster = team.map((row) => {
|
|
15339
15563
|
const principalId = remotePrincipalOf2(row);
|
|
15340
15564
|
return {
|
|
15341
15565
|
name: row.name,
|
|
@@ -15416,7 +15640,10 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
|
|
|
15416
15640
|
projectId,
|
|
15417
15641
|
rows.filter((row) => row.kind === "agent" && remotePrincipalOf2(row) === null)
|
|
15418
15642
|
);
|
|
15419
|
-
return
|
|
15643
|
+
return {
|
|
15644
|
+
...input,
|
|
15645
|
+
ownerMemberId: await boundOwnerMember(ctx, projectId, callerThreadId)
|
|
15646
|
+
};
|
|
15420
15647
|
}
|
|
15421
15648
|
});
|
|
15422
15649
|
};
|
|
@@ -15787,39 +16014,6 @@ async function teamWaitingList(ctx, memberThreads, nameOf2) {
|
|
|
15787
16014
|
return waiting.length === 0 ? null : `${count(waiting.length, "member is", "members are")} waiting on the person: ${waiting.join("; ")}. These appear in this conversation for the person to answer; you cannot answer them and should not wait for them. Hand out work to members who are not blocked.`;
|
|
15788
16015
|
}
|
|
15789
16016
|
|
|
15790
|
-
// ../../packages/ycodium-system-text/src/systemText.ts
|
|
15791
|
-
var SYSTEM_NOTIFICATION_OPEN_TAG = "<ycodium-system>";
|
|
15792
|
-
var SYSTEM_NOTIFICATION_CLOSE_TAG = "</ycodium-system>";
|
|
15793
|
-
var isSystemNotificationText = (text) => text.startsWith(SYSTEM_NOTIFICATION_OPEN_TAG);
|
|
15794
|
-
var rendersAsSystemMessage = (text) => isSystemNotificationText(text) && !(isPresetPrefixMessage(text) && text.includes(PRESET_PREFIX_CLOSE) && parsePresetPrefixText(text) === null);
|
|
15795
|
-
var FIRST_BLOCK_START = `^(?:${SYSTEM_NOTIFICATION_OPEN_TAG}\\n)?`;
|
|
15796
|
-
var PRESET_PREFIX_MESSAGE_START = `${SYSTEM_NOTIFICATION_OPEN_TAG}
|
|
15797
|
-
<preset-prefix `;
|
|
15798
|
-
var isPresetPrefixMessage = (text) => text.startsWith(PRESET_PREFIX_MESSAGE_START);
|
|
15799
|
-
var SYSTEM_TEXT_ESCAPED_ATTRIBUTE = 'esc="1"';
|
|
15800
|
-
var ESCAPED_BLOCK_NAMES = ["thread-response", "thread-handover", "scheduled-wake"];
|
|
15801
|
-
var ESCAPED_OPEN_LINE_PATTERN = new RegExp(
|
|
15802
|
-
`^<(?:${ESCAPED_BLOCK_NAMES.join("|")})(?:\\s[^>]*)? ${SYSTEM_TEXT_ESCAPED_ATTRIBUTE}>$`
|
|
15803
|
-
);
|
|
15804
|
-
var PRESET_PREFIX_CLOSE = `
|
|
15805
|
-
</preset-prefix>
|
|
15806
|
-
${SYSTEM_NOTIFICATION_CLOSE_TAG}`;
|
|
15807
|
-
var PRESET_PREFIX_PATTERN = new RegExp(
|
|
15808
|
-
`^${SYSTEM_NOTIFICATION_OPEN_TAG}\\n<preset-prefix id="([^"]*)">\\n([\\s\\S]*?)\\n</preset-prefix>\\n${SYSTEM_NOTIFICATION_CLOSE_TAG}(?:\\n\\n([\\s\\S]*))?$`
|
|
15809
|
-
);
|
|
15810
|
-
var parsePresetPrefixText = (text) => {
|
|
15811
|
-
if (text.split(PRESET_PREFIX_CLOSE).length !== 2) return null;
|
|
15812
|
-
const match7 = PRESET_PREFIX_PATTERN.exec(text);
|
|
15813
|
-
if (match7 === null) return null;
|
|
15814
|
-
const [, presetId, prefix, body] = match7;
|
|
15815
|
-
if (!presetId) return null;
|
|
15816
|
-
return { presetId, prefix: prefix ?? "", body: body ?? "" };
|
|
15817
|
-
};
|
|
15818
|
-
var userSpokenText = (text) => {
|
|
15819
|
-
if (!rendersAsSystemMessage(text)) return text;
|
|
15820
|
-
return parsePresetPrefixText(text)?.body || null;
|
|
15821
|
-
};
|
|
15822
|
-
|
|
15823
16017
|
// src/team/groupDigest.ts
|
|
15824
16018
|
var DIGEST_LIMIT = 30;
|
|
15825
16019
|
var SCAN_PAGES = 5;
|
|
@@ -16278,6 +16472,10 @@ var zh_CN_default = {
|
|
|
16278
16472
|
kindAgentHint: "\u673A\u5668\u9009\u8FD9\u4E00\u53F0\u65F6\uFF0C\u7528\u4F60\u9009\u7684 provider \u548C\u6A21\u578B\u8FD0\u884C\u3002\u9009\u4E86\u522B\u7684\u673A\u5668\u7684\u6210\u5458\u8BD5\u8DD1\u4F1A\u51FA\u9519\uFF1A\u6539\u56DE\u8FD9\u4E00\u53F0\uFF0C\u6216\u8005\u8DF3\u8FC7\u8BD5\u8DD1\uFF0C\u5B83\u5C31\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u7528\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u8FD0\u884C\u3002",
|
|
16279
16473
|
kindRemoteHint: "\u4ECE\u53E6\u4E00\u53F0\u673A\u5668\u7528\u81EA\u5DF1\u7684\u51ED\u636E\u8FDE\u8FDB\u6765\u7684 agent\u3002",
|
|
16280
16474
|
kindPersonHint: "\u56E2\u961F\u91CC\u7684\u4EBA\u3002\u4EBA\u4F1A\u5217\u5728\u6210\u5458\u91CC\uFF0C\u4F46\u4E0D\u4F1A\u8FD0\u884C\u4F1A\u8BDD\u3002",
|
|
16475
|
+
thisIsMe: "\u8FD9\u662F\u6211",
|
|
16476
|
+
thisIsMeHint: "\u6709\u4EBA\u5728\u56E2\u961F\u7FA4\u91CC @ \u8FD9\u4E2A\u6210\u5458\u65F6\uFF0C\u6D88\u606F\u4F1A\u8FDB\u4F60\u7684\u300C\u53D1\u7ED9\u6211\u7684\u300D\u3002",
|
|
16477
|
+
boundToOther: "\u8FD9\u4E2A\u6210\u5458\u662F\u53E6\u4E00\u4E2A\u4EBA\uFF0C\u53EA\u6709\u5BF9\u65B9\u672C\u4EBA\u80FD\u6539\u8FD9\u4E00\u9879\u3002",
|
|
16478
|
+
you: "\u6211",
|
|
16281
16479
|
name: "\u540D\u5B57",
|
|
16282
16480
|
memberTitle: "\u5934\u8854",
|
|
16283
16481
|
responsibility: "\u804C\u8D23",
|
|
@@ -16324,6 +16522,7 @@ var zh_CN_default = {
|
|
|
16324
16522
|
noDefaultModel: "\u8FD9\u4E2A\u9879\u76EE\u6CA1\u8BBE\u9ED8\u8BA4\u6A21\u578B\u3002\u5230\u9879\u76EE\u8BBE\u7F6E\u7684\u300C\u65B0\u4F1A\u8BDD \u2192 \u6A21\u578B\u300D\u9009\u4E00\u4E2A\uFF0C\u518D\u91CD\u8BD5\u3002",
|
|
16325
16523
|
modelUnavailable: "\u8FD9\u4E2A\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u7528\u4E0D\u4E86\u3002\u68C0\u67E5\u4E00\u4E0B provider\uFF0C\u6216\u5230\u9879\u76EE\u8BBE\u7F6E\u7684\u300C\u65B0\u4F1A\u8BDD \u2192 \u6A21\u578B\u300D\u6362\u4E00\u4E2A\u3002",
|
|
16326
16524
|
duplicateMember: "\u5DF2\u6709\u6210\u5458\u7528\u4E86\u8FD9\u4E2A\u540D\u5B57\u6216\u8FD9\u4E2A\u8FDC\u7AEF agent\uFF0C\u8BF7\u5148\u6539\u540D\u6216\u79FB\u9664\u5B83\u3002",
|
|
16525
|
+
alreadyYou: "\u4F60\u5728\u540D\u518C\u4E0A\u5DF2\u7ECF\u662F\u300C{{name}}\u300D\u4E86\uFF0C\u8BF7\u5148\u5728\u300C{{name}}\u300D\u90A3\u91CC\u53D6\u6D88\u300C\u8FD9\u662F\u6211\u300D\u3002",
|
|
16327
16526
|
staleVersion: "\u8FD9\u540D\u6210\u5458\u5DF2\u88AB\u522B\u5904\u6539\u8FC7\uFF0C\u5DF2\u91CD\u65B0\u8F7D\u5165\u3002\u8BF7\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002",
|
|
16328
16527
|
notFound: "\u8FD9\u540D\u6210\u5458\u5DF2\u4E0D\u5B58\u5728\u3002",
|
|
16329
16528
|
invalidState: "\u8FD9\u540D\u6210\u5458\u7684\u72B6\u6001\u5DF2\u88AB\u522B\u5904\u6539\u8FC7\uFF0C\u5DF2\u91CD\u65B0\u8F7D\u5165\u3002",
|
|
@@ -16742,6 +16941,7 @@ async function ensureSession(env, record2, ensured, prepared) {
|
|
|
16742
16941
|
if (parentThreadId !== void 0)
|
|
16743
16942
|
await createTeamThread(ctx, {
|
|
16744
16943
|
projectId: record2.projectId,
|
|
16944
|
+
memberId: record2.memberId,
|
|
16745
16945
|
threadId: trialId,
|
|
16746
16946
|
parentThreadId,
|
|
16747
16947
|
title: member.name,
|
|
@@ -16752,6 +16952,7 @@ async function ensureSession(env, record2, ensured, prepared) {
|
|
|
16752
16952
|
requestId: `thread:${trialId}`,
|
|
16753
16953
|
threadId: trialId,
|
|
16754
16954
|
projectId: record2.projectId,
|
|
16955
|
+
memberId: record2.memberId,
|
|
16755
16956
|
title: member.name,
|
|
16756
16957
|
...selection,
|
|
16757
16958
|
// 与旧目标的成员一致:不然试跑里的工具调用会卡在审批上。
|
|
@@ -16766,7 +16967,7 @@ async function ensureSession(env, record2, ensured, prepared) {
|
|
|
16766
16967
|
message: {
|
|
16767
16968
|
messageId: `team-trial-message:${key}`,
|
|
16768
16969
|
role: "user",
|
|
16769
|
-
text: trialMessage("localPrompt", { trialId }),
|
|
16970
|
+
text: teamWakeText({ reason: "instructions" }, trialMessage("localPrompt", { trialId })),
|
|
16770
16971
|
attachments: []
|
|
16771
16972
|
},
|
|
16772
16973
|
modelSelection: selection.modelSelection,
|
|
@@ -16836,7 +17037,8 @@ async function tellLeads(env, leadThreads, projectId, key, text) {
|
|
|
16836
17037
|
recipient: { threadId: leadThreadId },
|
|
16837
17038
|
requestId,
|
|
16838
17039
|
messageId: `${requestId}:message`,
|
|
16839
|
-
text
|
|
17040
|
+
text,
|
|
17041
|
+
wake: { reason: "notice" }
|
|
16840
17042
|
});
|
|
16841
17043
|
delivered ||= sent;
|
|
16842
17044
|
}
|
|
@@ -17262,7 +17464,7 @@ function startTrialRuntime(ctx, deps, options = {}) {
|
|
|
17262
17464
|
// src/index.ts
|
|
17263
17465
|
var index_default = definePlugin({
|
|
17264
17466
|
id: "team",
|
|
17265
|
-
apiVersion:
|
|
17467
|
+
apiVersion: 49,
|
|
17266
17468
|
activate(ctx) {
|
|
17267
17469
|
const trialState = ctx.derivedState(trialStateDefinition);
|
|
17268
17470
|
const rosters = createRosterService(ctx);
|