oasis_test 0.1.77 → 0.1.78
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/dist/index.js +238 -44
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4734,12 +4734,12 @@ var init_memory_prompt = __esm({
|
|
|
4734
4734
|
});
|
|
4735
4735
|
|
|
4736
4736
|
// ../core/src/assembler.ts
|
|
4737
|
-
function renderLetterDetail(model, a, recipient) {
|
|
4737
|
+
function renderLetterDetail(model, a, recipient, actorLabel) {
|
|
4738
4738
|
const rootSeq = model.annotationSeq.get(a.id) ?? 0;
|
|
4739
4739
|
const lastSelf = recipient !== void 0 ? lastPostSeqOf(model, a, recipient) : Number.NEGATIVE_INFINITY;
|
|
4740
4740
|
const lines = [];
|
|
4741
4741
|
if (rootSeq > lastSelf) lines.push(`- \u300C${a.body}\u300D`);
|
|
4742
|
-
for (const t of a.thread) if ((t.seq ?? rootSeq) > lastSelf) lines.push(` - \u21B3 ${t.author}\uFF1A${t.body}`);
|
|
4742
|
+
for (const t of a.thread) if ((t.seq ?? rootSeq) > lastSelf) lines.push(` - \u21B3 ${actorLabel(t.author)}\uFF1A${t.body}`);
|
|
4743
4743
|
lines.push(`\uFF08\u672C\u4FE1\u5168\u6587\uFF1A\`oasis content ${a.id}\`\uFF09`);
|
|
4744
4744
|
return lines;
|
|
4745
4745
|
}
|
|
@@ -4864,12 +4864,14 @@ async function assembleContext(args) {
|
|
|
4864
4864
|
if (!artifact) throw new Error(`assembleContext: artifact not found: ${artifactId}`);
|
|
4865
4865
|
const typeDef = args.schema?.get(artifact.type);
|
|
4866
4866
|
const canvasMode = typeDef?.name === "design" && args.action !== "review" && args.part === void 0;
|
|
4867
|
+
const actorLabels = args.resolveActorLabels ? await args.resolveActorLabels().catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
|
|
4868
|
+
const actorLabel = (id) => id === void 0 ? "" : actorLabels.get(id) ?? id;
|
|
4867
4869
|
const files = {};
|
|
4868
4870
|
if (canvasMode && artifact.description) files["DESIGN_BRIEF.md"] = artifact.description;
|
|
4869
4871
|
if (args.action === "reply") {
|
|
4870
4872
|
const a = args.annotationId !== void 0 ? model.annotations.get(args.annotationId) : void 0;
|
|
4871
4873
|
if (!a) throw new Error(`assembleContext(reply): annotation not found: ${args.annotationId}`);
|
|
4872
|
-
const newPostLines = renderLetterDetail(model, a, args.actorId);
|
|
4874
|
+
const newPostLines = renderLetterDetail(model, a, args.actorId, actorLabel);
|
|
4873
4875
|
if (args.resolveActorContext && args.actorId) {
|
|
4874
4876
|
const actorCtx = await args.resolveActorContext(args.actorId).catch(() => null);
|
|
4875
4877
|
if (actorCtx?.config?.prompt) Object.assign(files, splitIdentityFiles(actorCtx.config.prompt));
|
|
@@ -4881,13 +4883,14 @@ async function assembleContext(args) {
|
|
|
4881
4883
|
``,
|
|
4882
4884
|
`artifact_id: ${artifactId}`,
|
|
4883
4885
|
`annotation_id: ${a.id}`,
|
|
4884
|
-
`actor_id
|
|
4886
|
+
// 诊断 1be339c7:`your_actor_id` 而非 `actor_id`——消歧「这行是我还是对方」(与 chat 抬头同款同改)。
|
|
4887
|
+
`your_actor_id: ${args.actorId ?? ""}`,
|
|
4885
4888
|
``,
|
|
4886
4889
|
`## \u672C\u6B21\u4E3A\u4EC0\u4E48\u5524\u8D77\u4F60`,
|
|
4887
4890
|
`\u6709\u4EBA\u5728\u4EA7\u7269 ${artifactId} \u7684\u4E00\u5C01\u4FE1\u91CC @ \u4E86\u4F60\uFF0C\u7B49\u4F60\u56DE\u8BDD\u3002\u4F60**\u4E0D\u662F**\u8FD9\u4E2A\u4EA7\u7269\u7684 owner\u2014\u2014`,
|
|
4888
4891
|
`\u672C\u8F6E\u4F60\u53EA\u6709\u53D1\u8A00\u6743\uFF1A\u8BFB\u4E0A\u4E0B\u6587\u3001\u56DE\u4E00\u5E16\uFF0C\u522B\u7684\u90FD\u4E0D\u7528\uFF08\u4E5F\u4E0D\u80FD\uFF09\u505A\u3002`,
|
|
4889
4892
|
``,
|
|
4890
|
-
`## \u8981\u4F60\u56DE\u7684\u65B0\u8BDD\uFF08\u4F5C\u8005 ${a.author}${a.state === "open" ? "" : `\uFF0C\u72B6\u6001 ${a.state}`}\uFF09`,
|
|
4893
|
+
`## \u8981\u4F60\u56DE\u7684\u65B0\u8BDD\uFF08\u4F5C\u8005 ${actorLabel(a.author)}${a.state === "open" ? "" : `\uFF0C\u72B6\u6001 ${a.state}`}\uFF09`,
|
|
4891
4894
|
...newPostLines,
|
|
4892
4895
|
``,
|
|
4893
4896
|
`## \u9700\u8981\u4F60\u505A\u4EC0\u4E48`,
|
|
@@ -5037,7 +5040,7 @@ async function assembleContext(args) {
|
|
|
5037
5040
|
const detail = [];
|
|
5038
5041
|
for (const r of queued) {
|
|
5039
5042
|
const info = queuedParts.find((q) => q.revisionId === r.id);
|
|
5040
|
-
const who = r.author === artifact.owner ? "\u4F60\u81EA\u5DF1\u4E0A\u4E00\u8F6E" : r.author;
|
|
5043
|
+
const who = r.author === artifact.owner ? "\u4F60\u81EA\u5DF1\u4E0A\u4E00\u8F6E" : actorLabel(r.author);
|
|
5041
5044
|
const baseC = await contentMapOf(r.base ? model.revisions.get(r.base) ?? null : null);
|
|
5042
5045
|
const newC = await contentMapOf(r);
|
|
5043
5046
|
const dir = info?.dir ?? `competing/${slug2(r.id.slice(9, 17))}`;
|
|
@@ -5045,7 +5048,7 @@ async function assembleContext(args) {
|
|
|
5045
5048
|
if (baseC !== null && newC !== null) {
|
|
5046
5049
|
files[`${dir}/DIFF.md`] = `# \`${r.id.slice(9, 17)}\` \u76F8\u5BF9\u5B83\u81EA\u5DF1\u7684\u5E95\u7A3F\uFF08base \`${(r.base ?? "\u2205").slice(9, 17)}\`\uFF09\u6539\u4E86\u4EC0\u4E48
|
|
5047
5050
|
|
|
5048
|
-
> \u4F5C\u8005\uFF1A${r.author}\u3000\u7406\u7531\uFF1A${r.reason}
|
|
5051
|
+
> \u4F5C\u8005\uFF1A${actorLabel(r.author)}\u3000\u7406\u7531\uFF1A${r.reason}
|
|
5049
5052
|
|
|
5050
5053
|
${manifestDiff(baseC, newC)}
|
|
5051
5054
|
`;
|
|
@@ -5119,15 +5122,15 @@ ${manifestDiff(baseC, newC)}
|
|
|
5119
5122
|
const onRev = v2.onRev;
|
|
5120
5123
|
const stale = head !== null && onRev !== head;
|
|
5121
5124
|
const at = stale ? `\uFF08\u57FA\u4E8E ${onRev}\uFF0C**\u5F53\u524D head \u5DF2\u662F ${head}**\u2014\u2014\u81EA\u884C\u5224\u65AD\u8FD9\u6761\u662F\u5426\u5DF2\u88AB\u540E\u7EED\u7248\u672C\u4FEE\u6389\uFF1B\u770B\u90A3\u4E00\u7248\u539F\u6587\uFF1A\`oasis content ${onRev}\`\uFF09` : "";
|
|
5122
|
-
return `- ${v2.author}${at}\uFF1A${truncateReviewNote(v2.note ?? "\uFF08\u65E0\u8BC4\u8BED\uFF09")}`;
|
|
5125
|
+
return `- ${actorLabel(v2.author)}${at}\uFF1A${truncateReviewNote(v2.note ?? "\uFF08\u65E0\u8BC4\u8BED\uFF09")}`;
|
|
5123
5126
|
}),
|
|
5124
5127
|
closing: `**\u9010\u6761\u56DE\u5E94\u4E0A\u9762\u7684\u8BC4\u5BA1\u610F\u89C1**\uFF08\u6539\u52A8\u5E76\u5165\u672C\u8F6E propose\uFF09\u3002`
|
|
5125
5128
|
});
|
|
5126
5129
|
}
|
|
5127
5130
|
for (const a of openAnnosHere) {
|
|
5128
|
-
const from = `${a.raisedFrom ?? a.author}${a.anchor.target !== artifactId ? `\uFF08\u951A ${a.anchor.target}\uFF09` : ""}`;
|
|
5129
|
-
const detail = renderLetterDetail(model, a, ownerId);
|
|
5130
|
-
const detailFull = [`- \u300C${a.body}\u300D`, ...a.thread.map((t) => ` - \u21B3 ${t.author}\uFF1A${t.body}`)];
|
|
5131
|
+
const from = `${actorLabel(a.raisedFrom ?? a.author)}${a.anchor.target !== artifactId ? `\uFF08\u951A ${a.anchor.target}\uFF09` : ""}`;
|
|
5132
|
+
const detail = renderLetterDetail(model, a, ownerId, actorLabel);
|
|
5133
|
+
const detailFull = [`- \u300C${a.body}\u300D`, ...a.thread.map((t) => ` - \u21B3 ${actorLabel(t.author)}\uFF1A${t.body}`)];
|
|
5131
5134
|
if (a.state !== "open") {
|
|
5132
5135
|
tasks.push({
|
|
5133
5136
|
label: `\u3010\u590D\u6D3B\u7684\u4FE1\xB7\u4F5C\u8005\u8FFD\u95EE\u3011${from}\uFF08id\uFF1A${a.id}\uFF09`,
|
|
@@ -5510,7 +5513,8 @@ ${m2.spec.split("\n").map((l) => ` > ${l}`).join("\n")}`);
|
|
|
5510
5513
|
(e) => `- ${e.to} @ ${e.pinned ?? "\u2205\uFF08\u672A\u5C31\u7EEA\uFF09"}${e.required ? " [required]" : ""}`
|
|
5511
5514
|
),
|
|
5512
5515
|
`\u4E0B\u6E38\u6D88\u8D39\u8005\uFF1A${consumers.length === 0 ? "\uFF08\u6682\u65E0\uFF09" : ""}`,
|
|
5513
|
-
|
|
5516
|
+
// 诊断 1be339c7:邻域里下游消费者的 owner 也走 actorLabel——否则这里留一个裸 actor id。
|
|
5517
|
+
...consumers.map((c) => `- ${c.id}\uFF08type=${c.type}\uFF0Cowner=${actorLabel(c.owner)}\uFF09`),
|
|
5514
5518
|
...staleSet.length > 0 ? [
|
|
5515
5519
|
``,
|
|
5516
5520
|
`## \u8FC7\u671F\u8F93\u5165\uFF08stale-set\uFF09`,
|
|
@@ -6884,6 +6888,7 @@ var init_dispatcher = __esm({
|
|
|
6884
6888
|
...this.opts.schema !== void 0 ? { schema: this.opts.schema } : {},
|
|
6885
6889
|
...codeRepo ? { codeRepo } : {},
|
|
6886
6890
|
...this.opts.resolveActorContext !== void 0 ? { resolveActorContext: this.opts.resolveActorContext } : {},
|
|
6891
|
+
...this.opts.resolveActorLabels !== void 0 ? { resolveActorLabels: this.opts.resolveActorLabels } : {},
|
|
6887
6892
|
...this.opts.resolveRoleBriefs !== void 0 ? { resolveRoleBriefs: this.opts.resolveRoleBriefs } : {},
|
|
6888
6893
|
...materializeSkills ? { materializeSkills } : {},
|
|
6889
6894
|
...resolveActorMemoryIndex ? { resolveActorMemoryIndex } : {}
|
|
@@ -137607,19 +137612,27 @@ var init_live_chat = __esm({
|
|
|
137607
137612
|
* 顺序不能倒:runtime 没接受就不该在流里留下痕迹,否则刷新后那条插入会凭空消失。
|
|
137608
137613
|
*/
|
|
137609
137614
|
async append(chatSessionId, text2) {
|
|
137615
|
+
const t0 = Date.now();
|
|
137616
|
+
const say = (r, extra) => {
|
|
137617
|
+
const bits = { sid: chatSessionId, accepted: r.accepted, reason: r.reason ?? "-", ms: Date.now() - t0, ...extra ?? {} };
|
|
137618
|
+
console.log("[live-chat.append]", JSON.stringify(bits));
|
|
137619
|
+
return r;
|
|
137620
|
+
};
|
|
137610
137621
|
const turn = this.turns.get(chatSessionId);
|
|
137611
|
-
if (!turn || turn.status !== "running")
|
|
137622
|
+
if (!turn || turn.status !== "running") {
|
|
137623
|
+
return say({ accepted: false, reason: "no-live-turn" }, { turnStatus: turn?.status ?? "<no-turn>" });
|
|
137624
|
+
}
|
|
137612
137625
|
const fn = turn.handle.appendInput;
|
|
137613
|
-
if (typeof fn !== "function") return { accepted: false, reason: "unsupported" };
|
|
137626
|
+
if (typeof fn !== "function") return say({ accepted: false, reason: "unsupported" });
|
|
137614
137627
|
let res;
|
|
137615
137628
|
try {
|
|
137616
137629
|
res = await fn.call(turn.handle, { text: text2 });
|
|
137617
|
-
} catch {
|
|
137618
|
-
return { accepted: false, reason: "rejected" };
|
|
137630
|
+
} catch (e) {
|
|
137631
|
+
return say({ accepted: false, reason: "rejected" }, { err: String(e) });
|
|
137619
137632
|
}
|
|
137620
|
-
if (!res.accepted) return res;
|
|
137633
|
+
if (!res.accepted) return say(res, { from: "runtime" });
|
|
137621
137634
|
if (this.turns.get(chatSessionId) !== turn || turn.status !== "running") {
|
|
137622
|
-
return { accepted: true, reason: "turn-finished" };
|
|
137635
|
+
return say({ accepted: true, reason: "turn-finished" }, { turnStatus: turn.status, replaced: this.turns.get(chatSessionId) !== turn });
|
|
137623
137636
|
}
|
|
137624
137637
|
const withSeq = { type: "user", text: text2, seq: ++turn.seq };
|
|
137625
137638
|
turn.buffer.push(withSeq);
|
|
@@ -142082,22 +142095,70 @@ async function startOasisServer(opts) {
|
|
|
142082
142095
|
const discussSessions = opts.discussSessions ?? /* @__PURE__ */ new Map();
|
|
142083
142096
|
const reviewWaiters = /* @__PURE__ */ new Map();
|
|
142084
142097
|
const terminalReviews = /* @__PURE__ */ new Map();
|
|
142085
|
-
const notifyReviewResolved = (draftId, r) => {
|
|
142098
|
+
const notifyReviewResolved = (draftId, r, resume) => {
|
|
142099
|
+
if (terminalReviews.has(draftId)) return;
|
|
142086
142100
|
terminalReviews.set(draftId, r);
|
|
142087
142101
|
if (terminalReviews.size > 512) {
|
|
142088
142102
|
const first = terminalReviews.keys().next().value;
|
|
142089
142103
|
if (first !== void 0) terminalReviews.delete(first);
|
|
142090
142104
|
}
|
|
142091
142105
|
const waiters = reviewWaiters.get(draftId);
|
|
142106
|
+
const hadWaiters = !!waiters && waiters.size > 0;
|
|
142092
142107
|
if (waiters) {
|
|
142093
142108
|
reviewWaiters.delete(draftId);
|
|
142094
142109
|
for (const w2 of waiters) w2(r);
|
|
142095
142110
|
}
|
|
142111
|
+
if (!hadWaiters && resume && resume.kind === "command" && resume.origin) {
|
|
142112
|
+
void resumeChatAfterAuthorization(resume.origin, r, resume);
|
|
142113
|
+
}
|
|
142096
142114
|
};
|
|
142097
142115
|
const resolveEngine = opts.resolveEngine ?? (async () => ({ kernel: opts.kernel, oplog: opts.oplog, blobs: opts.blobs, ...opts.registry ? { registry: opts.registry } : {} }));
|
|
142098
142116
|
const domainRouter = new Router();
|
|
142099
142117
|
for (const register of opts.domains ?? []) register(domainRouter);
|
|
142100
142118
|
const liveChat = opts.liveChat ?? new LiveChatRegistry();
|
|
142119
|
+
const resumeChatAfterAuthorization = async (origin, resolution, ctx) => {
|
|
142120
|
+
const store = opts.chatSession;
|
|
142121
|
+
const dispatch = opts.dispatchChat;
|
|
142122
|
+
if (!store || !dispatch) return;
|
|
142123
|
+
const session = await store.getSession(origin).catch(() => null);
|
|
142124
|
+
if (!session) return;
|
|
142125
|
+
const { randomUUID: randomUUID29 } = await import("node:crypto");
|
|
142126
|
+
const approved = resolution.status === "approved";
|
|
142127
|
+
const by = ctx.authorizedBy ?? "\u7BA1\u7406\u8005";
|
|
142128
|
+
const label = ctx.effectLabel || ctx.command || "";
|
|
142129
|
+
const statusText = approved ? `\u547D\u4EE4\u5DF2\u7531 ${by} \u6279\u51C6\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C${label ? `\uFF1A${label}` : ""}\u3002` : `\u547D\u4EE4\u5DF2\u88AB ${by} \u9A73\u56DE${ctx.reason ? `\uFF1A${ctx.reason}` : ""}\u3002`;
|
|
142130
|
+
await store.appendMessage({ id: randomUUID29(), sessionId: origin, role: "system", content: statusText, createdAt: (/* @__PURE__ */ new Date()).toISOString() }).catch(() => void 0);
|
|
142131
|
+
if (liveChat.isRunning(origin)) return;
|
|
142132
|
+
const prompt = approved ? `\u4E0A\u4E00\u6761\u5F85\u6388\u6743\u547D\u4EE4\u5DF2\u88AB ${by} \u6279\u51C6\u5E76\u4EE5\u5176\u540D\u4E49\u6267\u884C\uFF08\u547D\u4EE4\uFF1A${label}\uFF09\u3002\u8BF7\u7EE7\u7EED\u539F\u4EFB\u52A1\u3002` : `\u4E0A\u4E00\u6761\u5F85\u6388\u6743\u547D\u4EE4\u5DF2\u88AB ${by} \u9A73\u56DE${ctx.reason ? `\uFF08\u7406\u7531\uFF1A${ctx.reason}\uFF09` : ""}\u3002\u522B\u91CD\u8BD5\u540C\u4E00\u6761\u2014\u2014\u8BF7\u6539\u65B9\u6848\u6216\u5148\u5411\u53D1\u8D77\u4EBA\u95EE\u6E05\u695A\u3002`;
|
|
142133
|
+
let dispatched;
|
|
142134
|
+
try {
|
|
142135
|
+
dispatched = await dispatch({
|
|
142136
|
+
actorId: session.aiActorId,
|
|
142137
|
+
message: prompt,
|
|
142138
|
+
chatSessionId: origin,
|
|
142139
|
+
...session.runtimeSessionId ? { sessionId: session.runtimeSessionId } : {}
|
|
142140
|
+
});
|
|
142141
|
+
} catch {
|
|
142142
|
+
return;
|
|
142143
|
+
}
|
|
142144
|
+
let text2 = "";
|
|
142145
|
+
dispatched.onOutput((chunk) => {
|
|
142146
|
+
text2 += chunk;
|
|
142147
|
+
});
|
|
142148
|
+
void dispatched.done.then(async () => {
|
|
142149
|
+
if (text2 || dispatched.runId) {
|
|
142150
|
+
await store.appendMessage({
|
|
142151
|
+
id: randomUUID29(),
|
|
142152
|
+
sessionId: origin,
|
|
142153
|
+
role: "assistant",
|
|
142154
|
+
content: text2,
|
|
142155
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
142156
|
+
...dispatched.runId ? { runId: dispatched.runId } : {}
|
|
142157
|
+
}).catch(() => void 0);
|
|
142158
|
+
}
|
|
142159
|
+
await store.updateSession(origin, { runtimeSessionId: dispatched.nativeSessionId ?? null, touchedAt: (/* @__PURE__ */ new Date()).toISOString() }).catch(() => void 0);
|
|
142160
|
+
}).catch(() => void 0);
|
|
142161
|
+
};
|
|
142101
142162
|
const channelService = opts.channels?.enabled && opts.dispatchChat && opts.actors ? new ChannelService({
|
|
142102
142163
|
store: opts.channels.store,
|
|
142103
142164
|
dispatchChat: (req) => opts.dispatchChat(req),
|
|
@@ -142615,7 +142676,11 @@ async function startOasisServer(opts) {
|
|
|
142615
142676
|
if (review.kind === "command" && review.command) {
|
|
142616
142677
|
const { command, artifactId } = await engine.kernel.applyAuthorizedCommand({ draftId, actor });
|
|
142617
142678
|
const receipt = authorizedCommandReceipt(command, review.command.args, actor);
|
|
142618
|
-
notifyReviewResolved(
|
|
142679
|
+
notifyReviewResolved(
|
|
142680
|
+
draftId,
|
|
142681
|
+
{ status: "approved", command, effectLabel: review.command.effectLabel, authorizedBy: actor, receipt },
|
|
142682
|
+
{ origin: review.origin, kind: "command", authorizedBy: actor, effectLabel: review.command.effectLabel, command }
|
|
142683
|
+
);
|
|
142619
142684
|
res.writeHead(200, { "content-type": "application/json" }).end(
|
|
142620
142685
|
JSON.stringify({ applied: 1, command, artifactId, draftId, draftedBy: review.proposedBy, authorizedBy: actor })
|
|
142621
142686
|
);
|
|
@@ -142624,7 +142689,11 @@ async function startOasisServer(opts) {
|
|
|
142624
142689
|
const plan = { ...review.plan, authorizedBy: actor, draftedBy: review.proposedBy, resolvesProposal: draftId };
|
|
142625
142690
|
const fresh = await engine.kernel.previewIntervention(plan);
|
|
142626
142691
|
const result = await engine.kernel.applyIntervention(plan, fresh.baseSeqs, actor);
|
|
142627
|
-
notifyReviewResolved(
|
|
142692
|
+
notifyReviewResolved(
|
|
142693
|
+
draftId,
|
|
142694
|
+
{ status: "approved", command: "", effectLabel: review.plan.reason, authorizedBy: actor },
|
|
142695
|
+
{ origin: review.origin, kind: review.kind ?? "graph-edit" }
|
|
142696
|
+
);
|
|
142628
142697
|
res.writeHead(200, { "content-type": "application/json" }).end(
|
|
142629
142698
|
JSON.stringify({ ...result, draftId, draftedBy: review.proposedBy, authorizedBy: actor })
|
|
142630
142699
|
);
|
|
@@ -142653,7 +142722,18 @@ async function startOasisServer(opts) {
|
|
|
142653
142722
|
}
|
|
142654
142723
|
}
|
|
142655
142724
|
await engine.kernel.rejectIntervention({ draftId, anchor: review.anchor, actor, ...reason !== void 0 ? { reason } : {} });
|
|
142656
|
-
notifyReviewResolved(
|
|
142725
|
+
notifyReviewResolved(
|
|
142726
|
+
draftId,
|
|
142727
|
+
{ status: "denied", ...reason !== void 0 ? { reason } : {} },
|
|
142728
|
+
{
|
|
142729
|
+
origin: review.origin,
|
|
142730
|
+
kind: review.kind ?? "graph-edit",
|
|
142731
|
+
authorizedBy: actor,
|
|
142732
|
+
...review.command?.effectLabel ? { effectLabel: review.command.effectLabel } : {},
|
|
142733
|
+
...review.command?.command ? { command: review.command.command } : {},
|
|
142734
|
+
...reason !== void 0 ? { reason } : {}
|
|
142735
|
+
}
|
|
142736
|
+
);
|
|
142657
142737
|
res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ rejected: true, draftId, annotated: touched.length }));
|
|
142658
142738
|
} catch (err) {
|
|
142659
142739
|
res.writeHead(400, { "content-type": "application/json" }).end(
|
|
@@ -143140,7 +143220,7 @@ async function startOasisServer(opts) {
|
|
|
143140
143220
|
{ nodeId: currentRuntimeId, runtimeKind: currentRuntimeKind }
|
|
143141
143221
|
);
|
|
143142
143222
|
const persistedUserMessage = persistTarget ? stripInjectedChatContext(body.message) : body.message;
|
|
143143
|
-
const history = runtimeChanged && chatStore && persistTarget ? (await chatStore.listMessages(persistTarget.id, 20)).filter((message) => !(message.role === "assistant" && message.status === "running")).map((message) => ({
|
|
143223
|
+
const history = runtimeChanged && chatStore && persistTarget ? (await chatStore.listMessages(persistTarget.id, 20)).filter((message) => message.role !== "system" && !(message.role === "assistant" && message.status === "running")).map((message) => ({
|
|
143144
143224
|
role: message.role,
|
|
143145
143225
|
content: message.role === "user" ? stripInjectedChatContext(message.content) : message.content
|
|
143146
143226
|
})) : [];
|
|
@@ -143152,7 +143232,7 @@ async function startOasisServer(opts) {
|
|
|
143152
143232
|
...draftWorkspace ? { draftWorkspace } : {}
|
|
143153
143233
|
});
|
|
143154
143234
|
const effectiveSessionId = persistTarget ? runtimeChanged ? void 0 : persistTarget.runtimeSessionId ?? void 0 : body.sessionId || void 0;
|
|
143155
|
-
const resumeFallbackHistory = effectiveSessionId && chatStore && persistTarget ? (await chatStore.listMessages(persistTarget.id, 20)).filter((m2) => !(m2.role === "assistant" && m2.status === "running")).map((m2) => ({ role: m2.role, content: m2.role === "user" ? stripInjectedChatContext(m2.content) : m2.content })) : [];
|
|
143235
|
+
const resumeFallbackHistory = effectiveSessionId && chatStore && persistTarget ? (await chatStore.listMessages(persistTarget.id, 20)).filter((m2) => m2.role !== "system" && !(m2.role === "assistant" && m2.status === "running")).map((m2) => ({ role: m2.role, content: m2.role === "user" ? stripInjectedChatContext(m2.content) : m2.content })) : [];
|
|
143156
143236
|
const fallbackMessage = resumeFallbackHistory.length ? buildRuntimeChatPrompt({ userMessage: persistedUserMessage, history: resumeFallbackHistory, ...draftWorkspace ? { draftWorkspace } : {} }) : void 0;
|
|
143157
143237
|
const session = await opts.dispatchChat({
|
|
143158
143238
|
actorId: body.actorId,
|
|
@@ -153649,6 +153729,8 @@ var init_claude_code = __esm({
|
|
|
153649
153729
|
let writes = 0;
|
|
153650
153730
|
let results = 0;
|
|
153651
153731
|
let inputClosing = false;
|
|
153732
|
+
let diag = () => {
|
|
153733
|
+
};
|
|
153652
153734
|
let pendingClose = null;
|
|
153653
153735
|
const cancelPendingClose = () => {
|
|
153654
153736
|
if (pendingClose) {
|
|
@@ -153663,15 +153745,18 @@ var init_claude_code = __esm({
|
|
|
153663
153745
|
);
|
|
153664
153746
|
writes++;
|
|
153665
153747
|
cancelPendingClose();
|
|
153748
|
+
diag("stdin_write", { writes, results, chars: text2.length });
|
|
153666
153749
|
return true;
|
|
153667
|
-
} catch {
|
|
153750
|
+
} catch (e) {
|
|
153751
|
+
diag("stdin_write_failed", { writes, results, err: String(e) });
|
|
153668
153752
|
return false;
|
|
153669
153753
|
}
|
|
153670
153754
|
};
|
|
153671
|
-
const closeInput = () => {
|
|
153755
|
+
const closeInput = (reason = "unspecified") => {
|
|
153672
153756
|
cancelPendingClose();
|
|
153673
153757
|
if (inputClosing) return;
|
|
153674
153758
|
inputClosing = true;
|
|
153759
|
+
diag("stdin_closed", { reason, writes, results });
|
|
153675
153760
|
try {
|
|
153676
153761
|
child.stdin.end();
|
|
153677
153762
|
} catch {
|
|
@@ -153680,13 +153765,13 @@ var init_claude_code = __esm({
|
|
|
153680
153765
|
const maybeCloseInputOnResult = () => {
|
|
153681
153766
|
if (!appendMode || inputClosing) return;
|
|
153682
153767
|
if (appendGraceMs <= 0) {
|
|
153683
|
-
closeInput();
|
|
153768
|
+
closeInput("result");
|
|
153684
153769
|
return;
|
|
153685
153770
|
}
|
|
153686
153771
|
cancelPendingClose();
|
|
153687
153772
|
pendingClose = setTimeout(() => {
|
|
153688
153773
|
pendingClose = null;
|
|
153689
|
-
closeInput();
|
|
153774
|
+
closeInput("grace-expired");
|
|
153690
153775
|
}, appendGraceMs);
|
|
153691
153776
|
pendingClose.unref?.();
|
|
153692
153777
|
};
|
|
@@ -153705,6 +153790,13 @@ var init_claude_code = __esm({
|
|
|
153705
153790
|
}
|
|
153706
153791
|
let transcriptRef = path12.join(dir, "transcript.txt");
|
|
153707
153792
|
const out = openTranscript(transcriptRef);
|
|
153793
|
+
diag = (event, extra) => {
|
|
153794
|
+
try {
|
|
153795
|
+
out.write(JSON.stringify({ type: "oasis_diag", at: (/* @__PURE__ */ new Date()).toISOString(), event, ...extra ?? {} }) + "\n");
|
|
153796
|
+
} catch {
|
|
153797
|
+
}
|
|
153798
|
+
};
|
|
153799
|
+
diag("session_started", { appendMode, appendGraceMs });
|
|
153708
153800
|
const telemetryCbs = [];
|
|
153709
153801
|
let eventSeq = 0;
|
|
153710
153802
|
let lastResult;
|
|
@@ -153723,6 +153815,7 @@ var init_claude_code = __esm({
|
|
|
153723
153815
|
if (p2["type"] === "result") {
|
|
153724
153816
|
lastResult = p2;
|
|
153725
153817
|
results++;
|
|
153818
|
+
diag("result", { writes, results, subtype: p2["subtype"], is_error: p2["is_error"] });
|
|
153726
153819
|
maybeCloseInputOnResult();
|
|
153727
153820
|
}
|
|
153728
153821
|
accumulateClaudeUsage(usageAcc, p2);
|
|
@@ -153844,6 +153937,7 @@ var init_claude_code = __esm({
|
|
|
153844
153937
|
return {
|
|
153845
153938
|
id,
|
|
153846
153939
|
async kill() {
|
|
153940
|
+
diag("kill", { writes, results, exited, inputClosing });
|
|
153847
153941
|
cancelPendingClose();
|
|
153848
153942
|
inputClosing = true;
|
|
153849
153943
|
killReason ??= "cancelled";
|
|
@@ -153865,10 +153959,17 @@ var init_claude_code = __esm({
|
|
|
153865
153959
|
return appendMode && !exited && !inputClosing;
|
|
153866
153960
|
},
|
|
153867
153961
|
appendInput(input) {
|
|
153868
|
-
if (!appendMode)
|
|
153869
|
-
|
|
153962
|
+
if (!appendMode) {
|
|
153963
|
+
diag("append_rejected", { reason: "unsupported", writes, results });
|
|
153964
|
+
return Promise.resolve({ accepted: false, reason: "unsupported" });
|
|
153965
|
+
}
|
|
153966
|
+
if (exited || inputClosing) {
|
|
153967
|
+
diag("append_rejected", { reason: "session-closing", exited, inputClosing, writes, results });
|
|
153968
|
+
return Promise.resolve({ accepted: false, reason: "session-closing" });
|
|
153969
|
+
}
|
|
153870
153970
|
materializeFiles(dir, input.files);
|
|
153871
153971
|
if (input.interrupt) writeInterrupt();
|
|
153972
|
+
diag("append_accepted", { writes, results, interrupt: !!input.interrupt, chars: input.text.length });
|
|
153872
153973
|
const ok = writeUserMessage(input.text);
|
|
153873
153974
|
return Promise.resolve(ok ? { accepted: true } : { accepted: false, reason: "rejected" });
|
|
153874
153975
|
}
|
|
@@ -161345,9 +161446,30 @@ function changeConfirmSummary(r) {
|
|
|
161345
161446
|
const what = r.nonMonotonicOps.map((a) => C_ACTION_LABEL[a] ?? a).join("\u3001");
|
|
161346
161447
|
return `\u7BA1\u7406\u8005\u63D0\u4E86\u4E00\u4EFD\u9700\u8981\u4F60\u786E\u8BA4\u7684\u6539\u52A8\uFF08${what || "\u9500\u6BC1\u6027\u6539\u56FE"}\uFF09\uFF1A${why}`;
|
|
161347
161448
|
}
|
|
161449
|
+
function latestOtherLetterActivity(an, me) {
|
|
161450
|
+
let best;
|
|
161451
|
+
const consider = (at, by, seq) => {
|
|
161452
|
+
if (!at || by === void 0 || by === me) return;
|
|
161453
|
+
const s2 = seq ?? -1;
|
|
161454
|
+
if (!best || s2 > best.seq) best = { at, by, seq: s2 };
|
|
161455
|
+
};
|
|
161456
|
+
for (const t of an.thread) consider(t.ts, t.author, t.seq);
|
|
161457
|
+
if (an.resolvedBy !== void 0) consider(an.resolvedAt, an.resolvedBy, an.resolvedAtSeq);
|
|
161458
|
+
return best;
|
|
161459
|
+
}
|
|
161460
|
+
function myLatestLetterPostSeq(an, me) {
|
|
161461
|
+
let s2;
|
|
161462
|
+
for (const t of an.thread) {
|
|
161463
|
+
if (t.author !== me) continue;
|
|
161464
|
+
const v2 = t.seq ?? -1;
|
|
161465
|
+
if (s2 === void 0 || v2 > s2) s2 = v2;
|
|
161466
|
+
}
|
|
161467
|
+
return s2;
|
|
161468
|
+
}
|
|
161348
161469
|
function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso) {
|
|
161349
161470
|
const out = [];
|
|
161350
161471
|
const gapItems = [];
|
|
161472
|
+
const mentionedLettersEmittedForMe = /* @__PURE__ */ new Set();
|
|
161351
161473
|
const readAt = new Map(markers.map((m2) => [m2.scope, m2]));
|
|
161352
161474
|
const actorRef = (id) => {
|
|
161353
161475
|
const extra = resolveActor?.(id);
|
|
@@ -161508,26 +161630,29 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
161508
161630
|
...lastPost ? { actor: actorRef(lastPost.author) } : {},
|
|
161509
161631
|
...overdueField(an.createdAt)
|
|
161510
161632
|
});
|
|
161633
|
+
mentionedLettersEmittedForMe.add(an.id);
|
|
161511
161634
|
}
|
|
161512
161635
|
for (const an of anns) {
|
|
161513
|
-
if (!an.mail && !model.convergenceUnified || an.author !== me
|
|
161514
|
-
if (
|
|
161515
|
-
const
|
|
161516
|
-
if (
|
|
161517
|
-
const
|
|
161518
|
-
if (
|
|
161636
|
+
if (!an.mail && !model.convergenceUnified || an.author !== me) continue;
|
|
161637
|
+
if (mentionedLettersEmittedForMe.has(an.id)) continue;
|
|
161638
|
+
const activity = latestOtherLetterActivity(an, me);
|
|
161639
|
+
if (!activity) continue;
|
|
161640
|
+
const myLatest = myLatestLetterPostSeq(an, me);
|
|
161641
|
+
if (myLatest !== void 0 && myLatest > activity.seq) continue;
|
|
161642
|
+
if (!isUnread(activity.at, readAt.get(letterScope(an.id)))) continue;
|
|
161519
161643
|
const lastNote = an.thread.at(-1)?.body ?? "\uFF08\u65E0\u8BF4\u660E\uFF09";
|
|
161644
|
+
const phrase = an.state === "open" ? "\u6709\u65B0\u56DE\u590D" : an.state === "wontfix" ? "\u672A\u6539\u5185\u5BB9" : an.answeredVia ? `\u58F0\u79F0\u5DF2\u5728 ${an.answeredVia.slice(9, 17)} \u89E3\u51B3` : "\u5DF2\u5904\u7F6E";
|
|
161520
161645
|
out.push({
|
|
161521
161646
|
kind: "letter-answered",
|
|
161522
161647
|
artifactId: a.id,
|
|
161523
161648
|
workspace: ws,
|
|
161524
161649
|
annotationId: an.id,
|
|
161525
|
-
since:
|
|
161650
|
+
since: activity.at,
|
|
161526
161651
|
actionRequired: false,
|
|
161527
|
-
summary: `\u4F60\u7684\u4FE1\
|
|
161652
|
+
summary: `\u4F60\u7684\u4FE1\u6709\u65B0\u52A8\u9759\uFF08${phrase}\uFF09\u300C${nodeLabel(a)}\u300D\uFF1A${lastNote.slice(0, 100)}\u2014\u2014\u4E0D\u8BA4\u53EF\u53EF\u5728\u4FE1\u4E2D\u56DE\u5E16`,
|
|
161528
161653
|
title: nodeLabel(a),
|
|
161529
|
-
detail: `${actorName(
|
|
161530
|
-
actor: actorRef(
|
|
161654
|
+
detail: `${actorName(activity.by) || "\u5BF9\u65B9"} \u56DE\u5E94\u4E86\u4F60\u7684\u4FE1\uFF1A${firstSentence(lastNote)}`,
|
|
161655
|
+
actor: actorRef(activity.by)
|
|
161531
161656
|
// 通知型不判 overdue(诊断明说),不设 overdue 字段。
|
|
161532
161657
|
});
|
|
161533
161658
|
}
|
|
@@ -175407,6 +175532,7 @@ var init_worker = __esm({
|
|
|
175407
175532
|
|
|
175408
175533
|
- \`oasis roles\` \u2014\u2014 **\u6709\u54EA\u4E9B\u5C97\u4F4D**\uFF1A\u6807\u8BC6 / \u663E\u793A\u540D / \u5728\u5C97\u4EBA\u6570 / \u804C\u8D23 / \u5B83\u8D1F\u8D23\xB7\u8BC4\u5BA1\u54EA\u4E9B\u4EA4\u4ED8\u7269\uFF08\u65E0\u53C2\u6570\uFF09\u3002**\u522B\u731C\u5C97\u4F4D\u540D**\u2014\u2014\u5EFA\u56FE\u586B\u4E0D\u5230\u5C97\u4F4D\u7684\u5730\u65B9\u3001\u60F3\u77E5\u9053\u67D0\u7C7B\u4EA4\u4ED8\u7269\u5F52\u8C01\u7BA1\uFF0C\u5148\u67E5\u8FD9\u4E2A\u3002\u6807"0 \u4EBA\u5728\u5C97"\u7684\u5C97\u4F4D\u6D3E\u4E0D\u51FA\u6D3B\uFF1B\u6807"\u4E0D\u53EF\u5206\u914D"\u7684\u662F\u7CFB\u7EDF\u5C97\u4F4D\uFF08\u5982 ci\uFF09\u3002
|
|
175409
175534
|
- \`oasis actors [--role <\u5C97\u4F4D>] [--kind human|agent]\` \u2014\u2014 **\u6709\u8C01\u53EF\u6D3E**\uFF1Aid / \u540D\u5B57 / \u4EBA\u8FD8\u662F agent / \u5C97\u4F4D\u3002\u9ED8\u8BA4\u53EA\u5217**\u5728\u5C97**\uFF08\u79BB\u5C97\u7684\u6D3E\u4E0D\u4E86\u6D3B\uFF0C\u522B\u9009\uFF09\u3002\u8981\u7ED9\u8282\u70B9\u6307\u8D1F\u8D23\u4EBA\uFF08\`oasis assign\`\uFF09\u65F6\u7528 \`--role\` \u6309\u5C97\u4F4D\u627E\u4EBA\u3002
|
|
175535
|
+
- \`oasis actor <actorId>\` \u2014\u2014 **\u8FD9\u4E2A id \u5230\u5E95\u662F\u8C01**\uFF1A\u5355\u4EBA\u5B8C\u6574\u6863\u6848\uFF08\u59D3\u540D / \u5C97\u4F4D / \u56E2\u961F / \u6C47\u62A5\u5173\u7CFB / \u80FD\u529B\u4ECB\u7ECD / \u64C5\u957F / \u90AE\u7BB1 / \u72B6\u6001\uFF09\u3002\`oasis actors\` \u5217\u51FA\u5C97\u4F4D\u4E0B\u6709\u8C01\u4E4B\u540E\u3001\u8981**\u4ECE\u5C97\u4F4D\u843D\u5230\u5177\u4F53\u4EBA**\uFF08\u770B\u8FD9\u4E2A\u4EBA\u64C5\u957F\u4EC0\u4E48\u3001\u80FD\u4E0D\u80FD\u62C5\u8FD9\u6D3B\uFF09\u65F6\u7528\u5B83\u6DF1\u6316\u4E00\u5C42\u2014\u2014\u5206\u8BCA / \u6307\u6D3E / \u627E\u4EBA\u6B63\u662F\u4F60\u534F\u8C03\u8005\u6700\u9700\u8981\u7684\u90A3\u4E00\u8DF3\u3002
|
|
175410
175536
|
- \`oasis assign <id> --owner <actorId>\` \u2014\u2014 \u7ED9\u8282\u70B9**\u6307\u5B9A\u8D1F\u8D23\u4EBA**\u3002\`<id>\` = \u8282\u70B9\uFF1B\`--owner\` = \u5177\u4F53\u7684\u4EBA\u6216 agent \u7684 id\uFF08\u7528\u4E0A\u9762 \`oasis actors\` \u67E5\uFF0C\u522B\u7F16\uFF09\u3002**\u6709\u7684\u4EA4\u4ED8\u7269\u7C7B\u578B\u4E0D\u7ED1\u5C97\u4F4D**\uFF08\u8C01\u90FD\u80FD\u5199\uFF09\uFF0C\u5B83\u4EEC\u5EFA\u51FA\u6765 owner \u662F\u5F85\u6D3E\u72B6\u6001\u3001\u5FC5\u987B assign \u624D\u52A8\u5F97\u4E86\u2014\u2014preview \u4F1A\u7528 \u26A0 \u63D0\u9192\u4F60\u3002**\u9500\u6BC1\u6027**\uFF08\u4F1A\u593A\u8D70\u5728\u4EA7\u65B9\u7684\u6D3B\uFF09\u2014\u2014apply \u65F6\u8F6C\u4EBA\u786E\u8BA4\u3002
|
|
175411
175537
|
- \`oasis link <consumer> --to <up> [--required true]\` \u2014\u2014 \u7ED9 consumer \u52A0\u4E00\u6761\u6307\u5411\u4E0A\u6E38 up \u7684\u4F9D\u8D56\u8FB9\u3002\`<consumer>\` = \u8981\u52A0\u4F9D\u8D56\u7684\u4E0B\u6E38\u8282\u70B9\uFF08\u5F15\u7528,\u89C1\u4E0A\uFF09\uFF1B\`--to <up>\` = \u88AB\u4F9D\u8D56\u7684\u4E0A\u6E38\uFF1B\`--required true\` = \u8FD9\u6761\u662F**\u963B\u585E\u6027**\u4F9D\u8D56\uFF08up \u6CA1 conclude\uFF0Cconsumer \u5C31\u52A8\u4E0D\u4E86\uFF09\uFF0C**\u7701\u7565\u5219\u662F\u8F6F\u4F9D\u8D56**\uFF08\u53EA\u8BB0\u5173\u7CFB\u3001\u4E0D\u963B\u585E\uFF09\u3002\u53BB\u91CD\u65F6\u7528\u5B83\u628A"\u8BE5\u8FDE\u65E2\u6709"\u7684\u8FB9\u8865\u4E0A\u3002
|
|
175412
175538
|
- \`oasis spawn --type <t> --title "<\u77ED\u540D>" [--brief "<\u89C4\u683C>"] [--input <ref>[,\u2026]]\` \u2014\u2014 \u65B0\u5EFA\u4E00\u4E2A\u8282\u70B9\u3002**id \u4E0D\u7528\u4F60\u7ED9,\u7CFB\u7EDF\u636E (type,title) \u81EA\u52A8\u6D3E\u751F**\u3002\`--type <t>\` = \u7C7B\u578B\u540D\uFF08**\u5FC5\u586B**\uFF0C\u5148 \`oasis artifact-types\` \u770B\u53EF\u9009\u7C7B\u578B\u4E0E\u7528\u9014\uFF09\uFF1B\`--title\` = \u77ED\u540D\uFF08**\u5FC5\u586B\u3001\u540C type \u4E0B\u552F\u4E00**,\u649E\u540D\u4F1A\u8BA9\u4F60\u6539\uFF09\uFF1B\`--brief\` = \u7ED9\u5B83\u7684\u4EA7\u51FA\u89C4\u683C\uFF08\u5199\u6E05\u8981\u505A\u6210\u4EC0\u4E48\uFF0C\u4F1A\u6210\u4E3A\u8BE5\u8282\u70B9 owner \u7684\u4EFB\u52A1\u4E66\uFF09\uFF1B\`--input\` = \u5B83\u4F9D\u8D56\u54EA\u4E9B\u4E0A\u6E38\uFF08**\u9017\u53F7\u5206\u9694**\u591A\u4E2A,\u6BCF\u4E2A\u6309\u4E0A\u9762\u5F15\u7528\u5199\u6CD5\uFF09\u3002**\u786E\u65E0\u65E2\u6709\u53EF\u8FDE\u3001\u662F\u771F\u65B0\u9700\u6C42\u624D\u7528**\u3002
|
|
@@ -186935,6 +187061,29 @@ async function buildActorContext(service, actorId) {
|
|
|
186935
187061
|
]);
|
|
186936
187062
|
return { config: config2, connectors, installedSkills, ...record8?.roles?.length ? { roles: record8.roles } : {} };
|
|
186937
187063
|
}
|
|
187064
|
+
async function buildChatWhoSection(service, rolesAdmin, humanActorId, selfActorId) {
|
|
187065
|
+
if (!humanActorId) return [];
|
|
187066
|
+
const [human, self2, roleDefs, teams] = await Promise.all([
|
|
187067
|
+
service.getActor(humanActorId).catch(() => null),
|
|
187068
|
+
service.getActor(selfActorId).catch(() => null),
|
|
187069
|
+
rolesAdmin.list().catch(() => []),
|
|
187070
|
+
service.listTeams().catch(() => [])
|
|
187071
|
+
]);
|
|
187072
|
+
if (!human) return [];
|
|
187073
|
+
const roleLabel = new Map(roleDefs.map((r) => [r.name, r.label ?? r.name]));
|
|
187074
|
+
const headerParts = [`${human.name}\uFF08${human.id}\uFF09`];
|
|
187075
|
+
const pos = (human.roles ?? [])[0];
|
|
187076
|
+
if (pos) headerParts.push(roleLabel.get(pos) ?? pos);
|
|
187077
|
+
const teamName = human.teamId ? teams.find((t) => t.id === human.teamId)?.name : void 0;
|
|
187078
|
+
if (teamName) headerParts.push(teamName);
|
|
187079
|
+
const lines = ["## \u4F60\u5728\u8DDF\u8C01\u8BF4\u8BDD", "", headerParts.join(" \xB7 ")];
|
|
187080
|
+
if (human.description) lines.push(human.description);
|
|
187081
|
+
if (human.tags?.length) lines.push(`\u64C5\u957F\uFF1A${human.tags.join("\u3001")}`);
|
|
187082
|
+
if (human.email) lines.push(`\u90AE\u7BB1\uFF1A${human.email}`);
|
|
187083
|
+
lines.push("", `\u4F60\u662F ${self2?.name ?? selfActorId}\u3002TA \u8BF4\u300C\u6211\u300D\u65F6\u6307\u7684\u5C31\u662F\u4E0A\u9762\u8FD9\u4E2A\u4EBA\uFF1B\u63D0\u5230\u7684\u5176\u4ED6\u4EBA\u662F\u522B\u4EBA\uFF0C\u522B\u6DF7\u3002`);
|
|
187084
|
+
lines.push(`\u60F3\u8FDB\u4E00\u6B65\u4E86\u89E3 TA\u3001\u6216\u6838\u5B9E\u5BF9\u8BDD\u91CC\u63D0\u5230\u7684\u5176\u4ED6\u4EBA\u662F\u8C01\uFF1A\`oasis actor <actorId>\`\uFF08\u5355\u4EBA\u5B8C\u6574\u6863\u6848\uFF09\u3002`);
|
|
187085
|
+
return lines;
|
|
187086
|
+
}
|
|
186938
187087
|
function traceRuntimeKind(runtimeKind) {
|
|
186939
187088
|
if (runtimeKind === "claude" || runtimeKind === "claude-code") return "claude-code";
|
|
186940
187089
|
if (runtimeKind === "codex") return "codex";
|
|
@@ -188018,11 +188167,13 @@ async function startServe(opts) {
|
|
|
188018
188167
|
}
|
|
188019
188168
|
}
|
|
188020
188169
|
const sessionLine = chatSessionId ? `chat_session_id: ${chatSessionId}` : `runtime_session_id: ${runtimeSessionId}`;
|
|
188170
|
+
const whoLines = await buildChatWhoSection(actorService, rolesAdmin, priorChatSession?.humanActorId, actorId);
|
|
188021
188171
|
const taskHeader = workspace ? [
|
|
188022
188172
|
"# \u4E0E\u5DE5\u5355\u7BA1\u7406\u8005\u5BF9\u8BDD",
|
|
188023
188173
|
"",
|
|
188024
188174
|
sessionLine,
|
|
188025
|
-
`actor_id
|
|
188175
|
+
// 诊断 1be339c7:`your_actor_id` 而非 `actor_id`——这行是 **agent 自己**,改名把「这行是我还是对方」消歧到零。
|
|
188176
|
+
`your_actor_id: ${actorId}`,
|
|
188026
188177
|
`workspace: ${workspace}`,
|
|
188027
188178
|
"",
|
|
188028
188179
|
CONVERSATIONAL_MANAGER_BODY
|
|
@@ -188030,7 +188181,7 @@ async function startServe(opts) {
|
|
|
188030
188181
|
"# \u5373\u65F6\u8111\u66B4\u5BF9\u8BDD",
|
|
188031
188182
|
"",
|
|
188032
188183
|
sessionLine,
|
|
188033
|
-
`
|
|
188184
|
+
`your_actor_id: ${actorId}`,
|
|
188034
188185
|
"",
|
|
188035
188186
|
"\u8BF7\u76F4\u63A5\u56DE\u7B54\u7528\u6237\u95EE\u9898\u3002\u9664\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\u5199\u5165\u7CFB\u7EDF\uFF0C\u5426\u5219\u4E0D\u8981\u521B\u5EFA\u6216\u4FEE\u6539 artifact\u3002"
|
|
188036
188187
|
];
|
|
@@ -188040,6 +188191,8 @@ async function startServe(opts) {
|
|
|
188040
188191
|
...taskHeader,
|
|
188041
188192
|
...attachmentPaths.length ? ["", "## \u7528\u6237\u9644\u4EF6", "", "\u7528\u6237\u968F\u6D88\u606F\u9644\u5E26\u4E86\u4EE5\u4E0B\u6587\u4EF6\uFF08\u5728\u4F60\u7684\u5DE5\u4F5C\u76EE\u5F55\u4E0B\uFF0C\u53EF\u76F4\u63A5\u8BFB\u53D6\uFF09\uFF1A", ...attachmentPaths.map((p2) => `- ${p2}`)] : [],
|
|
188042
188193
|
...projectContextLines.length ? ["", "## \u5F53\u524D\u9879\u76EE\u516C\u5F00\u8F93\u5165", "", "\u751F\u6210 Brief \u524D\u5FC5\u987B\u5148\u8BFB\u53D6 `PROJECT_CONTEXT.md` \u53CA\u5176\u4E2D\u5217\u51FA\u7684 `project/` \u6587\u4EF6\uFF1B\u4ED3\u5E93\u7B49\u5916\u90E8\u4F4D\u7F6E\u4E5F\u8BB0\u5F55\u5728\u8BE5\u6587\u4EF6\u4E2D\u3002"] : [],
|
|
188194
|
+
// 诊断 1be339c7:身份段紧贴在「## 用户消息」之前——让 agent 先知道「你在跟谁说话」,再读那条消息。
|
|
188195
|
+
...whoLines.length ? ["", ...whoLines] : [],
|
|
188043
188196
|
"",
|
|
188044
188197
|
"## \u7528\u6237\u6D88\u606F",
|
|
188045
188198
|
"",
|
|
@@ -188492,6 +188645,23 @@ async function startServe(opts) {
|
|
|
188492
188645
|
const want = new Set(roles);
|
|
188493
188646
|
return all.filter((r) => want.has(r.name)).map((r) => ({ name: r.name, ...r.label ? { label: r.label } : {}, ...r.description ? { description: r.description } : {} }));
|
|
188494
188647
|
},
|
|
188648
|
+
// 诊断 1be339c7:actorId → 「姓名(岗位)」全量映射,供装配器把任务书里所有裸 id 换掉(信署名、评审票
|
|
188649
|
+
// 作者、集成竞争版作者、thread 每帖……)。一次性拉全员名册 ∪ 岗位目录(岗位取首个 position 的显示名);
|
|
188650
|
+
// 无岗位仅姓名;查不到某 id 由装配器回退裸 id。整表拉 = 一次 listActors,比逐 id 回调更省也更不会漏。
|
|
188651
|
+
resolveActorLabels: async () => {
|
|
188652
|
+
const [actorList, roleList] = await Promise.all([
|
|
188653
|
+
(await runActors()).service.listActors().catch(() => []),
|
|
188654
|
+
rolesAdmin.list().catch(() => [])
|
|
188655
|
+
]);
|
|
188656
|
+
const roleLabel = new Map(roleList.map((r) => [r.name, r.label ?? r.name]));
|
|
188657
|
+
const map = /* @__PURE__ */ new Map();
|
|
188658
|
+
for (const a of actorList) {
|
|
188659
|
+
const pos = (a.roles ?? [])[0];
|
|
188660
|
+
const posLabel = pos ? roleLabel.get(pos) ?? pos : void 0;
|
|
188661
|
+
map.set(a.id, posLabel ? `${a.name}\uFF08${posLabel}\uFF09` : a.name);
|
|
188662
|
+
}
|
|
188663
|
+
return map;
|
|
188664
|
+
},
|
|
188495
188665
|
materializeSkills: async (actorId, runtimeKind) => {
|
|
188496
188666
|
if (SKILL_CACHE_RUNTIMES.has(runtimeKind)) return {};
|
|
188497
188667
|
const ctx = await runActors();
|
|
@@ -190280,6 +190450,7 @@ var USAGE = `oasis \u2014\u2014 artifact-centric \u534F\u4F5C\u5185\u6838 CLI\uF
|
|
|
190280
190450
|
freeze <artifactId> [--note "\u2026"] # \u51BB\u7ED3\u8282\u70B9\uFF1A\u4FDD\u7559\u8F93\u51FA\u3001\u505C\u6B62\u6539\u52A8
|
|
190281
190451
|
accept <artifactId> [--note "\u2026"] # \u5B9A\u7A3F\uFF08\u5148 conclude \u518D accept\uFF09
|
|
190282
190452
|
actors [--role <\u5C97\u4F4D>] [--kind human|agent] [--all true] # \u6709\u8C01\u53EF\u6D3E\uFF1Aid/\u540D\u5B57/\u4EBA\u8FD8\u662Fagent/\u5C97\u4F4D\u3002\u9ED8\u8BA4\u53EA\u5217\u5728\u5C97\uFF08\u79BB\u5C97\u7684\u6D3E\u4E0D\u4E86\u6D3B\uFF09\u3002assign \u524D\u7528\u5B83\u627E\u4EBA
|
|
190453
|
+
actor <actorId> # \u8FD9\u4E2A id \u5230\u5E95\u662F\u8C01\uFF1A\u5355\u4EBA\u5B8C\u6574\u6863\u6848\uFF08\u59D3\u540D/\u5C97\u4F4D/\u56E2\u961F/\u6C47\u62A5/\u80FD\u529B\u4ECB\u7ECD/\u64C5\u957F/\u90AE\u7BB1/\u72B6\u6001\uFF09\u3002\u4ECE\u5C97\u4F4D\u8DF3\u5230\u5177\u4F53\u4EBA\u3001\u6216\u6838\u5B9E\u7F72\u540D\u8EAB\u4EFD\u65F6\u7528
|
|
190283
190454
|
roles # \u6709\u54EA\u4E9B\u5C97\u4F4D\uFF1A\u6807\u8BC6/\u663E\u793A\u540D/\u5728\u5C97\u4EBA\u6570/\u804C\u8D23/\u5B83\u8D1F\u8D23\xB7\u8BC4\u5BA1\u54EA\u4E9B\u4EA4\u4ED8\u7269\u3002\u586B --owner-role\u3001\u95F8\u7684 reviewers\u3001\u7ED9\u5458\u5DE5\u5B9A\u5C97\u524D\u7528\u5B83\u67E5\u5408\u6CD5\u5C97\u4F4D
|
|
190284
190455
|
assign <artifactId> --owner <actorId>
|
|
190285
190456
|
gc # \u5B64\u513F blob \u56DE\u6536\uFF08mark-and-sweep\uFF1B\u64CD\u4F5C\u8005\u547D\u4EE4\uFF0CF1\uFF09
|
|
@@ -190382,9 +190553,13 @@ var ASYNC_AUTH_MESSAGE = "\u5DF2\u63D0\u4EA4\u4EBA\u5DE5\u5BA1\u6838\uFF1B\u5148
|
|
|
190382
190553
|
function asyncAuthorizationReturn(data) {
|
|
190383
190554
|
return data !== void 0 ? { message: ASYNC_AUTH_MESSAGE, data } : { message: ASYNC_AUTH_MESSAGE };
|
|
190384
190555
|
}
|
|
190556
|
+
var DEFAULT_AUTH_WAIT_MS = 2 * 60 * 1e3;
|
|
190557
|
+
function resolveAuthWaitMs() {
|
|
190558
|
+
return Number(process.env["OASIS_AUTH_WAIT_MS"] ?? DEFAULT_AUTH_WAIT_MS);
|
|
190559
|
+
}
|
|
190385
190560
|
async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
190386
190561
|
const asyncFallback = asyncAuthorizationReturn(fallback.data);
|
|
190387
|
-
const timeoutMs =
|
|
190562
|
+
const timeoutMs = resolveAuthWaitMs();
|
|
190388
190563
|
const controller = new AbortController();
|
|
190389
190564
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
190390
190565
|
process.stderr.write(
|
|
@@ -191960,6 +192135,25 @@ ${res.warning}`);
|
|
|
191960
192135
|
}
|
|
191961
192136
|
break;
|
|
191962
192137
|
}
|
|
192138
|
+
// 诊断 1be339c7 ③:单人详情——「这个 id 到底是谁」。协调者要从岗位跳到人时用它,chat agent 想核实
|
|
192139
|
+
// 发起人身份时也用它。复用现成 GET /api/actors/:id(服务端零改动);id 不存在时该路由已回 404「没有这个
|
|
192140
|
+
// 员工」而非 500。命令签名与 status <id> / content <id> 同形(位置参数,不用 --id);不加 --company(公司
|
|
192141
|
+
// 由 token 定死,加了服务端也会忽略 = 假承诺)。每字段一行、人话标签、id 完整不截断。
|
|
192142
|
+
case "actor": {
|
|
192143
|
+
const id = needPos(positional, 0, "oasis actor <actorId>");
|
|
192144
|
+
const a = await api.request("GET", `/api/actors/${encodeURIComponent(id)}`);
|
|
192145
|
+
println(`id\uFF1A${a.id}`);
|
|
192146
|
+
if (a.name) println(`\u59D3\u540D\uFF1A${a.name}`);
|
|
192147
|
+
println(`\u7C7B\u578B\uFF1A${a.kind === "human" ? "\u4EBA" : a.kind === "agent" ? "AI \u5458\u5DE5" : a.kind}`);
|
|
192148
|
+
println(`\u5C97\u4F4D\uFF1A${(a.positions ?? []).join("\u3001") || "(\u65E0\u5C97\u4F4D)"}`);
|
|
192149
|
+
if (a.teamId) println(`\u56E2\u961F\uFF1A${a.teamId}`);
|
|
192150
|
+
if (a.reportsTo) println(`\u6C47\u62A5\u7ED9\uFF1A${a.reportsTo}`);
|
|
192151
|
+
if (a.description) println(`\u80FD\u529B\u4ECB\u7ECD\uFF1A${a.description}`);
|
|
192152
|
+
if (a.tags?.length) println(`\u64C5\u957F\uFF1A${a.tags.join("\u3001")}`);
|
|
192153
|
+
if (a.email) println(`\u90AE\u7BB1\uFF1A${a.email}`);
|
|
192154
|
+
println(`\u72B6\u6001\uFF1A${a.status === "active" ? "\u5728\u5C97" : a.status === "disabled" ? "\u5DF2\u505C\u7528" : a.status}`);
|
|
192155
|
+
break;
|
|
192156
|
+
}
|
|
191963
192157
|
case "roles": {
|
|
191964
192158
|
const { items } = await api.request(
|
|
191965
192159
|
"GET",
|
|
@@ -192406,7 +192600,7 @@ ${res.warning}`);
|
|
|
192406
192600
|
init_src6();
|
|
192407
192601
|
|
|
192408
192602
|
// src/index.ts
|
|
192409
|
-
var PKG_VERSION = true ? "0.1.
|
|
192603
|
+
var PKG_VERSION = true ? "0.1.78" : "dev";
|
|
192410
192604
|
var OASIS_DIR = path28.join(os9.homedir(), ".oasis");
|
|
192411
192605
|
var CONFIG_FILE = path28.join(OASIS_DIR, "node-config.json");
|
|
192412
192606
|
var PID_FILE = path28.join(OASIS_DIR, "node.pid");
|