oasis_test_v2 2.2.98 → 2.2.99
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 +163 -35
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -13674,12 +13674,13 @@ async function recordChatTurnInterruption(deps) {
|
|
|
13674
13674
|
let version2 = await items.sessionVersionCursor(sessionId).catch(() => 0);
|
|
13675
13675
|
const touched = [];
|
|
13676
13676
|
const at2 = now();
|
|
13677
|
-
for (const row of rows) {
|
|
13677
|
+
for (const row of deps.cause === "user-stop" ? [] : rows) {
|
|
13678
13678
|
if (row.status !== "streaming") continue;
|
|
13679
13679
|
const updated = await items.applyOp(row.id, { op: "set_status", status: "interrupted" }, { at: at2, version: ++version2, sessionId });
|
|
13680
13680
|
if (updated) touched.push(updated);
|
|
13681
13681
|
}
|
|
13682
|
-
|
|
13682
|
+
if (existing && isUserStopPayload(existing.payload)) return touched;
|
|
13683
|
+
const payload2 = deps.cause === "user-stop" ? { code: "error", note: CHAT_INTERRUPT_NOTICE["user-stop"], reason: "cancelled", closedBy: deps.reason, cancelledBy: "user" } : deps.cause === "sweep-orphan" ? {
|
|
13683
13684
|
code: "error",
|
|
13684
13685
|
note: deps.cancelledBy ? chatCancelNote(deps.cancelledBy) : CHAT_INTERRUPT_NOTICE[deps.cause],
|
|
13685
13686
|
reason: "cancelled",
|
|
@@ -13713,6 +13714,9 @@ async function recordChatTurnInterruption(deps) {
|
|
|
13713
13714
|
return [];
|
|
13714
13715
|
}
|
|
13715
13716
|
}
|
|
13717
|
+
function isUserStopPayload(payload2) {
|
|
13718
|
+
return !!payload2 && typeof payload2 === "object" && !Array.isArray(payload2) && payload2.cancelledBy === "user";
|
|
13719
|
+
}
|
|
13716
13720
|
var chatInterruptItemId, CHAT_INTERRUPT_NOTICE;
|
|
13717
13721
|
var init_chat_interrupt_notice = __esm({
|
|
13718
13722
|
"../server/src/chat-interrupt-notice.ts"() {
|
|
@@ -13724,7 +13728,10 @@ var init_chat_interrupt_notice = __esm({
|
|
|
13724
13728
|
CHAT_INTERRUPT_NOTICE = {
|
|
13725
13729
|
"sweep-orphan": CHAT_CANCELLED_NOTE,
|
|
13726
13730
|
"sweep-absolute-cap": "\u8FD9\u4E00\u8F6E\u8FD0\u884C\u65F6\u95F4\u8D85\u8FC7\u4E86\u4E0A\u9650\uFF0C\u5DF2\u88AB\u7CFB\u7EDF\u7EC8\u6B62\u3002\u4E0A\u9762\u662F\u7EC8\u6B62\u524D\u5DF2\u7ECF\u751F\u6210\u7684\u5185\u5BB9\uFF0C\u53EF\u4EE5\u628A\u4EFB\u52A1\u62C6\u5C0F\u4E00\u4E9B\u518D\u53D1\u4E00\u6B21\u3002",
|
|
13727
|
-
"run-failed": "\u8FD9\u4E00\u8F6E\u6CA1\u6709\u6B63\u5E38\u7ED3\u675F\uFF08\u8FD0\u884C\u88AB\u4E2D\u65AD\uFF09\uFF0C\u6CA1\u80FD\u8DD1\u5B8C\u3002\u4E0A\u9762\u662F\u4E2D\u65AD\u524D\u5DF2\u7ECF\u751F\u6210\u7684\u5185\u5BB9\uFF0C\u4F60\u53EF\u4EE5\u518D\u53D1\u4E00\u6B21\u3002"
|
|
13731
|
+
"run-failed": "\u8FD9\u4E00\u8F6E\u6CA1\u6709\u6B63\u5E38\u7ED3\u675F\uFF08\u8FD0\u884C\u88AB\u4E2D\u65AD\uFF09\uFF0C\u6CA1\u80FD\u8DD1\u5B8C\u3002\u4E0A\u9762\u662F\u4E2D\u65AD\u524D\u5DF2\u7ECF\u751F\u6210\u7684\u5185\u5BB9\uFF0C\u4F60\u53EF\u4EE5\u518D\u53D1\u4E00\u6B21\u3002",
|
|
13732
|
+
// Bug 0228:serve 重启窗口里点停止,注册表里没有这一轮、只能在台账上收(`chat-turn-stop.ts`)。
|
|
13733
|
+
// 与在飞路径用户停止同一句、同一格归因;不借 `sweep-orphan` 那一支,免得日志里「用户停的」长成孤儿清扫。
|
|
13734
|
+
"user-stop": CHAT_CANCEL_NOTE.user
|
|
13728
13735
|
};
|
|
13729
13736
|
}
|
|
13730
13737
|
});
|
|
@@ -131263,7 +131270,7 @@ async function renewInjectedCredentials(injected, fetchCredentials) {
|
|
|
131263
131270
|
log("[node-connectors]", `\u7EED\u671F\uFF1A${slug6} \u6362\u5230\u65B0\u4EE4\u724C`);
|
|
131264
131271
|
} else {
|
|
131265
131272
|
outcome.unchanged.push(slug6);
|
|
131266
|
-
log("[node-connectors]", `\u7EED\u671F\uFF1A${slug6} server \u8FD4\u56DE\u7684\u4ECD\u662F\u65E7\u4EE4\u724C\uFF08\
|
|
131273
|
+
log("[node-connectors]", `\u7EED\u671F\uFF1A${slug6} server \u8FD4\u56DE\u7684\u4ECD\u662F\u65E7\u4EE4\u724C\uFF08\u539F\u56E0\u89C1 server \u65E5\u5FD7 [credential-refresh]\uFF09`);
|
|
131267
131274
|
}
|
|
131268
131275
|
} catch (err) {
|
|
131269
131276
|
outcome.failed.push({ slug: slug6, error: String(err) });
|
|
@@ -176539,6 +176546,58 @@ var init_chat_workorder_files = __esm({
|
|
|
176539
176546
|
}
|
|
176540
176547
|
});
|
|
176541
176548
|
|
|
176549
|
+
// ../server/src/chat-turn-stop.ts
|
|
176550
|
+
async function stopLedgerTurn(deps) {
|
|
176551
|
+
const now = deps.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
176552
|
+
const log3 = deps.log ?? (() => {
|
|
176553
|
+
});
|
|
176554
|
+
let turn = deps.turn ?? await deps.turns.activeTurn(deps.sessionId);
|
|
176555
|
+
for (let attempt = 0; attempt < MAX_CAS_ATTEMPTS; attempt += 1) {
|
|
176556
|
+
if (!turn || turn.status !== "reserved" && turn.status !== "running") return { stopped: false, reason: "no-live-turn" };
|
|
176557
|
+
if (deps.expectedRunId && turn.assistantRunId && turn.assistantRunId !== deps.expectedRunId) {
|
|
176558
|
+
return { stopped: false, reason: "turn-changed" };
|
|
176559
|
+
}
|
|
176560
|
+
const completedAt = now();
|
|
176561
|
+
const ok3 = await deps.turns.transitionTurn(
|
|
176562
|
+
turn.id,
|
|
176563
|
+
{ status: turn.status, dispatchId: turn.dispatchId },
|
|
176564
|
+
{ status: "cancelled", completedAt, lastError: `\u7528\u6237\u505C\u6B62\uFF08\u672C\u8FDB\u7A0B\u6CE8\u518C\u8868\u91CC\u6CA1\u6709\u8FD9\u4E00\u8F6E\uFF0C\u6309\u53F0\u8D26\u6536\uFF1B\u539F\u72B6\u6001 ${turn.status}\uFF09` }
|
|
176565
|
+
);
|
|
176566
|
+
if (ok3) {
|
|
176567
|
+
log3(`[chat-stop] \u4F1A\u8BDD ${deps.sessionId} \u8F6E ${turn.id} \u6309\u53F0\u8D26\u505C\u6B62\uFF08${turn.status} \u2192 cancelled\uFF09`);
|
|
176568
|
+
await recordUserStopNotice(deps, turn, completedAt);
|
|
176569
|
+
return { stopped: true, ledger: true };
|
|
176570
|
+
}
|
|
176571
|
+
turn = await deps.turns.getTurn(turn.id);
|
|
176572
|
+
}
|
|
176573
|
+
return { stopped: false, reason: "turn-changed" };
|
|
176574
|
+
}
|
|
176575
|
+
async function recordUserStopNotice(deps, turn, completedAt) {
|
|
176576
|
+
if (!deps.items) return;
|
|
176577
|
+
const messageId = turn.assistantRunId && deps.findAssistantMessageId ? await deps.findAssistantMessageId(turn.assistantRunId).catch(() => void 0) : void 0;
|
|
176578
|
+
const turnId = messageId ? await resolveChatItemsTurnId(deps.items, messageId, turn.id) : turn.id;
|
|
176579
|
+
await recordChatTurnInterruption({
|
|
176580
|
+
items: deps.items,
|
|
176581
|
+
sessionId: deps.sessionId,
|
|
176582
|
+
turnId,
|
|
176583
|
+
runId: turn.assistantRunId,
|
|
176584
|
+
messageId,
|
|
176585
|
+
cause: "user-stop",
|
|
176586
|
+
reason: "user-stop",
|
|
176587
|
+
now: () => completedAt,
|
|
176588
|
+
...deps.log ? { log: deps.log } : {}
|
|
176589
|
+
});
|
|
176590
|
+
}
|
|
176591
|
+
var MAX_CAS_ATTEMPTS;
|
|
176592
|
+
var init_chat_turn_stop = __esm({
|
|
176593
|
+
"../server/src/chat-turn-stop.ts"() {
|
|
176594
|
+
"use strict";
|
|
176595
|
+
init_chat_interrupt_notice();
|
|
176596
|
+
init_chat_item_ledger();
|
|
176597
|
+
MAX_CAS_ATTEMPTS = 3;
|
|
176598
|
+
}
|
|
176599
|
+
});
|
|
176600
|
+
|
|
176542
176601
|
// ../server/src/chat-broadcast.ts
|
|
176543
176602
|
function isFreshTerminal(terminalAt, nowMs, maxAgeMs) {
|
|
176544
176603
|
if (!terminalAt) return true;
|
|
@@ -211147,6 +211206,10 @@ function writeApiError(res, err) {
|
|
|
211147
211206
|
error: { code: err.code, message: err.message, ...err.details ?? {} }
|
|
211148
211207
|
}));
|
|
211149
211208
|
}
|
|
211209
|
+
async function findAssistantMessageIdByRun(store, sessionId, runId) {
|
|
211210
|
+
const rows = await (await store())?.listMessages(sessionId, 20).catch(() => []) ?? [];
|
|
211211
|
+
return rows.find((m2) => m2.role === "assistant" && m2.runId === runId)?.id;
|
|
211212
|
+
}
|
|
211150
211213
|
function toApiError(err) {
|
|
211151
211214
|
if (err instanceof ApiError) return err;
|
|
211152
211215
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -212730,6 +212793,7 @@ async function startOasisServer(opts) {
|
|
|
212730
212793
|
}) : void 0;
|
|
212731
212794
|
knowledgeDomain?.register(domainRouter);
|
|
212732
212795
|
const liveChat = opts.liveChat ?? new LiveChatRegistry();
|
|
212796
|
+
const serveBootedAtMs = Date.now();
|
|
212733
212797
|
const resolveChatSessionsForDelegation = opts.chatSessionFor ?? (opts.chatSession ? async () => opts.chatSession : void 0);
|
|
212734
212798
|
let delegationService = null;
|
|
212735
212799
|
if (opts.delegationStoreFor && resolveChatSessionsForDelegation && opts.actors && opts.dispatchChat) {
|
|
@@ -215166,12 +215230,15 @@ async function startOasisServer(opts) {
|
|
|
215166
215230
|
liveChat.reopenForRecovery(sid, {
|
|
215167
215231
|
runtimeSessionId: cs.runtimeSessionId ?? active.dispatchId ?? "",
|
|
215168
215232
|
...active.assistantRunId ? { runId: active.assistantRunId } : {},
|
|
215233
|
+
// 占位轮被 `/stop` 停掉:与注册表落空时同一个收法(条件迁移 + 用户停止结局项,Bug 0228)。
|
|
215169
215234
|
onStop: () => {
|
|
215170
|
-
void
|
|
215171
|
-
|
|
215172
|
-
|
|
215173
|
-
|
|
215174
|
-
|
|
215235
|
+
void (async () => stopLedgerTurn({
|
|
215236
|
+
turns,
|
|
215237
|
+
sessionId: sid,
|
|
215238
|
+
turn: active,
|
|
215239
|
+
items: opts.resolveChatItems ? await opts.resolveChatItems(currentCompanyId).catch(() => void 0) : opts.chatItems,
|
|
215240
|
+
findAssistantMessageId: (runId) => findAssistantMessageIdByRun(chatStoreNowOrNull, sid, runId)
|
|
215241
|
+
}))().catch(() => void 0);
|
|
215175
215242
|
}
|
|
215176
215243
|
});
|
|
215177
215244
|
};
|
|
@@ -215335,7 +215402,32 @@ async function startOasisServer(opts) {
|
|
|
215335
215402
|
if (typeof b2.expectedRunId === "string" && b2.expectedRunId) expectedRunId = b2.expectedRunId;
|
|
215336
215403
|
} catch {
|
|
215337
215404
|
}
|
|
215338
|
-
|
|
215405
|
+
let outcome = liveChat.stop(sid, expectedRunId);
|
|
215406
|
+
if (!outcome.stopped && outcome.reason === "no-live-turn") {
|
|
215407
|
+
const turns = opts.resolveChatTurns ? await opts.resolveChatTurns(currentCompanyId).catch(() => void 0) : opts.chatTurns;
|
|
215408
|
+
const active = turns ? await turns.activeTurn(sid).catch(() => null) : null;
|
|
215409
|
+
if (turns && active) {
|
|
215410
|
+
const openedByThisProcess = Date.parse(active.reservedAt) >= serveBootedAtMs;
|
|
215411
|
+
if (openedByThisProcess) {
|
|
215412
|
+
await waitForAdmittedTurnStart(sid, { liveChat, ledgerTurnRunning: async () => true, timeoutMs: STOP_TURN_START_WAIT_MS });
|
|
215413
|
+
outcome = liveChat.stop(sid, expectedRunId);
|
|
215414
|
+
}
|
|
215415
|
+
if (!outcome.stopped && outcome.reason === "no-live-turn") {
|
|
215416
|
+
outcome = await stopLedgerTurn({
|
|
215417
|
+
turns,
|
|
215418
|
+
sessionId: sid,
|
|
215419
|
+
expectedRunId,
|
|
215420
|
+
...openedByThisProcess ? {} : { turn: active },
|
|
215421
|
+
items: opts.resolveChatItems ? await opts.resolveChatItems(currentCompanyId).catch(() => void 0) : opts.chatItems,
|
|
215422
|
+
findAssistantMessageId: (runId) => findAssistantMessageIdByRun(chatStoreNowOrNull, sid, runId),
|
|
215423
|
+
log: (m2) => console.log(m2)
|
|
215424
|
+
}).catch((err) => {
|
|
215425
|
+
console.warn(`[chat-stop] \u4F1A\u8BDD ${sid} \u6309\u53F0\u8D26\u505C\u6B62\u5931\u8D25: ${String(err)}`);
|
|
215426
|
+
return { stopped: false, reason: "turn-changed" };
|
|
215427
|
+
});
|
|
215428
|
+
}
|
|
215429
|
+
}
|
|
215430
|
+
}
|
|
215339
215431
|
res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify(outcome));
|
|
215340
215432
|
return;
|
|
215341
215433
|
}
|
|
@@ -217432,7 +217524,7 @@ async function markDeliveredWithRetry(store, messageId, attempts = 3) {
|
|
|
217432
217524
|
}
|
|
217433
217525
|
return false;
|
|
217434
217526
|
}
|
|
217435
|
-
var http, import_node_crypto44, CONNECTOR_AUTH_SNAPSHOT_TTL_MS, COMPANY_FROM_PENDING_CALLBACKS, defaultResolveActor, enc, APPEND_TURN_START_WAIT_MS, STREAMING_PATHS, PLANNER_BLOCKING_CODES, WILL_VERBS, GOVERNANCE_COMMANDS, READ_ONLY_COMMANDS, isAgent, isHuman;
|
|
217527
|
+
var http, import_node_crypto44, CONNECTOR_AUTH_SNAPSHOT_TTL_MS, COMPANY_FROM_PENDING_CALLBACKS, defaultResolveActor, enc, APPEND_TURN_START_WAIT_MS, STOP_TURN_START_WAIT_MS, STREAMING_PATHS, PLANNER_BLOCKING_CODES, WILL_VERBS, GOVERNANCE_COMMANDS, READ_ONLY_COMMANDS, isAgent, isHuman;
|
|
217436
217528
|
var init_server3 = __esm({
|
|
217437
217529
|
"../server/src/server.ts"() {
|
|
217438
217530
|
"use strict";
|
|
@@ -217498,6 +217590,7 @@ var init_server3 = __esm({
|
|
|
217498
217590
|
init_chat_workorder_files();
|
|
217499
217591
|
init_chat_item_ledger();
|
|
217500
217592
|
init_chat_cancel_attribution();
|
|
217593
|
+
init_chat_turn_stop();
|
|
217501
217594
|
init_chat_assistant_turn();
|
|
217502
217595
|
init_src2();
|
|
217503
217596
|
init_chat_broadcast();
|
|
@@ -217519,6 +217612,7 @@ var init_server3 = __esm({
|
|
|
217519
217612
|
defaultResolveActor = (token2) => token2.startsWith("token:") ? token2.slice("token:".length) : null;
|
|
217520
217613
|
enc = (s2) => new TextEncoder().encode(s2);
|
|
217521
217614
|
APPEND_TURN_START_WAIT_MS = 1e4;
|
|
217615
|
+
STOP_TURN_START_WAIT_MS = 5e3;
|
|
217522
217616
|
STREAMING_PATHS = ["/api/events", "/api/chat", "/api/trajectory/events", "/api/intervention/wait"];
|
|
217523
217617
|
PLANNER_BLOCKING_CODES = /* @__PURE__ */ new Set([
|
|
217524
217618
|
"title_collision",
|
|
@@ -238094,10 +238188,10 @@ function stepRef(nodeId, title) {
|
|
|
238094
238188
|
return token("s", nodeId ?? "", title);
|
|
238095
238189
|
}
|
|
238096
238190
|
function actorRef2(actorId, name) {
|
|
238097
|
-
return actorId ? token("a", actorId, name) : clean(name);
|
|
238191
|
+
return actorId ? token("a", actorId, name) : withAt(clean(name));
|
|
238098
238192
|
}
|
|
238099
238193
|
function mentionRef(actorId, name) {
|
|
238100
|
-
return actorId ? token("m", actorId, name) :
|
|
238194
|
+
return actorId ? token("m", actorId, name) : withAt(clean(name));
|
|
238101
238195
|
}
|
|
238102
238196
|
function tokenize(s2) {
|
|
238103
238197
|
const out = [];
|
|
@@ -238141,9 +238235,9 @@ function sentenceSegments(s2) {
|
|
|
238141
238235
|
return out;
|
|
238142
238236
|
}
|
|
238143
238237
|
function plainSentence(s2) {
|
|
238144
|
-
return tokenize(s2).map((t) => typeof t === "string" ? t : t.kind === "s" ? `\u300C${t.name}\u300D` : t.
|
|
238238
|
+
return tokenize(s2).map((t) => typeof t === "string" ? t : t.kind === "s" ? `\u300C${t.name}\u300D` : withAt(t.name)).join("");
|
|
238145
238239
|
}
|
|
238146
|
-
var OPEN2, SEP, CLOSE2, MARKS, clean, token;
|
|
238240
|
+
var OPEN2, SEP, CLOSE2, MARKS, clean, withAt, token, plainActor;
|
|
238147
238241
|
var init_activity_text = __esm({
|
|
238148
238242
|
"../server/src/domains/collab/activity-text.ts"() {
|
|
238149
238243
|
"use strict";
|
|
@@ -238152,7 +238246,9 @@ var init_activity_text = __esm({
|
|
|
238152
238246
|
CLOSE2 = "\uE002";
|
|
238153
238247
|
MARKS = /[-]/g;
|
|
238154
238248
|
clean = (s2) => s2.replace(MARKS, "");
|
|
238249
|
+
withAt = (name) => name.startsWith("@") ? name : `@${name}`;
|
|
238155
238250
|
token = (kind, id, name) => `${OPEN2}${kind}${SEP}${clean(id)}${SEP}${clean(name)}${CLOSE2}`;
|
|
238251
|
+
plainActor = (name) => withAt(clean(name));
|
|
238156
238252
|
}
|
|
238157
238253
|
});
|
|
238158
238254
|
|
|
@@ -238625,7 +238721,7 @@ function buildWorkorderActivity(input) {
|
|
|
238625
238721
|
const managerId = resolveWorkorderManager(snap);
|
|
238626
238722
|
const ownerId = snap.workorder.ownerActorId;
|
|
238627
238723
|
const nameOf2 = (id) => id ? ref2(id).name ?? id : "\u2014";
|
|
238628
|
-
const personOf = (id) => actorRef2(id
|
|
238724
|
+
const personOf = (id) => id ? actorRef2(id, nameOf2(id)) : nameOf2(id);
|
|
238629
238725
|
const mentionOf = (id) => mentionRef(id ?? void 0, nameOf2(id));
|
|
238630
238726
|
const managerName = () => personOf(managerId);
|
|
238631
238727
|
const nodeTitleOf = (nodeId) => {
|
|
@@ -240891,7 +240987,10 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
240891
240987
|
...extra?.avatar ? { avatar: extra.avatar } : {}
|
|
240892
240988
|
};
|
|
240893
240989
|
};
|
|
240894
|
-
const
|
|
240990
|
+
const atName = (id) => {
|
|
240991
|
+
const name = resolveActor?.(id)?.name;
|
|
240992
|
+
return name ? plainActor(name) : "";
|
|
240993
|
+
};
|
|
240895
240994
|
const nowMs = nowIso ? Date.parse(nowIso) : Number.NaN;
|
|
240896
240995
|
const overdueSince = (sinceIso) => {
|
|
240897
240996
|
if (slaMs === void 0 || !Number.isFinite(nowMs) || !sinceIso) return void 0;
|
|
@@ -241028,7 +241127,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
241028
241127
|
// 续跑申请的入口在任务动态那张续跑申请卡上(卡 id = 申请 id,见 activity.ts `continuationCards`)。
|
|
241029
241128
|
...r.continuation ? { activityCardId: r.continuation.requestId } : {},
|
|
241030
241129
|
...anchorArt ? { title: nodeLabel(anchorArt) } : {},
|
|
241031
|
-
detail: `${
|
|
241130
|
+
detail: `${atName(r.proposedBy) || "\u7BA1\u7406\u8005"}\uFF1A${r.command ? commandCardLine(r.command) : firstSentence3(r.plan.reason)}`,
|
|
241032
241131
|
...r.kind !== "command" && opCount > 0 ? { impact: `\u6D89\u53CA ${opCount} \u5904\u6539\u52A8${r.nonMonotonicOps.length > 0 ? " \xB7 \u542B\u9500\u6BC1\u6027" : ""}` } : {},
|
|
241033
241132
|
actor: actorRef3(r.proposedBy),
|
|
241034
241133
|
...overdueField(r.at)
|
|
@@ -241069,7 +241168,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
241069
241168
|
actionRequired: true,
|
|
241070
241169
|
summary: `\u6709\u4EBA\u5728\u300C${label2}\u300D\u7684\u4FE1\u91CC @ \u4E86\u4F60\uFF0C\u7B49\u4F60\u56DE\u8BDD\uFF1A${(lastPost?.body ?? an.body).slice(0, 100)}`,
|
|
241071
241170
|
title: label2,
|
|
241072
|
-
detail: `${(lastPost ?
|
|
241171
|
+
detail: `${(lastPost ? atName(lastPost.author) : "") || "\u6709\u4EBA"} @ \u4E86\u4F60\uFF1A${firstSentence3(lastPost?.body ?? an.body)}`,
|
|
241073
241172
|
...lastPost ? { actor: actorRef3(lastPost.author) } : {},
|
|
241074
241173
|
...overdueField(an.createdAt)
|
|
241075
241174
|
});
|
|
@@ -241094,7 +241193,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
241094
241193
|
actionRequired: false,
|
|
241095
241194
|
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`,
|
|
241096
241195
|
title: nodeLabel(a),
|
|
241097
|
-
detail: `${
|
|
241196
|
+
detail: `${atName(activity.by) || "\u5BF9\u65B9"} \u56DE\u5E94\u4E86\u4F60\u7684\u4FE1\uFF1A${firstSentence3(lastNote)}`,
|
|
241098
241197
|
actor: actorRef3(activity.by)
|
|
241099
241198
|
// 通知型不判 overdue(诊断明说),不设 overdue 字段。
|
|
241100
241199
|
});
|
|
@@ -241114,7 +241213,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
241114
241213
|
actionRequired: true,
|
|
241115
241214
|
summary: `\u5F85\u4F60\u9A8C\u6536\uFF1A${label2}\uFF08${pendingHead.id}\uFF09\u2014\u2014\u8BE5\u7248\u7B54\u590D\u4E86\u4F60\u7684\u4FE1`,
|
|
241116
241215
|
title: label2,
|
|
241117
|
-
detail: `${
|
|
241216
|
+
detail: `${atName(pendingHead.author) || "agent"} \u4EA4\u4E86\u65B0\u7248\u7B54\u590D\u4F60\u7684\u4FE1\uFF1A${firstSentence3(pendingHead.reason)}`,
|
|
241118
241217
|
actor: actorRef3(pendingHead.author),
|
|
241119
241218
|
...overdueField(pendingHead.createdAt)
|
|
241120
241219
|
});
|
|
@@ -241141,7 +241240,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
241141
241240
|
actionRequired: true,
|
|
241142
241241
|
summary: `\u5F85\u4F60\u5BA1\u6279\uFF1A${label2}`,
|
|
241143
241242
|
title: label2,
|
|
241144
|
-
...gp ? { detail: `${
|
|
241243
|
+
...gp ? { detail: `${atName(gp.headAuthor) || "\u4F5C\u8005"} \u4EA4\u4E86\u65B0\u7248\uFF1A${firstSentence3(headReason)}`, actor: actorRef3(gp.headAuthor) } : {},
|
|
241145
241244
|
...impactParts.length > 0 ? { impact: impactParts.join(" \xB7 ") } : {},
|
|
241146
241245
|
...overdueField(gate.at)
|
|
241147
241246
|
});
|
|
@@ -241164,7 +241263,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
241164
241263
|
actionRequired: true,
|
|
241165
241264
|
summary: `\u4EA7\u51FA\u88AB\u6253\u56DE\uFF0C\u9700\u8FD4\u5DE5\uFF1A${label2}`,
|
|
241166
241265
|
title: label2,
|
|
241167
|
-
...rejectVote ? { detail: `${
|
|
241266
|
+
...rejectVote ? { detail: `${atName(rejectVote.author) || "\u8BC4\u5BA1"} \u6253\u56DE\uFF1A${firstSentence3(rejectVote.note ?? "\u89C1\u8BC4\u5BA1\u610F\u89C1")}`, actor: actorRef3(rejectVote.author) } : {},
|
|
241168
241267
|
...reworkDs > 0 ? { impact: `\u6321\u7740\u4E0B\u6E38 ${reworkDs} \u4E2A\u8282\u70B9` } : {},
|
|
241169
241268
|
...overdueField(latest.createdAt)
|
|
241170
241269
|
});
|
|
@@ -241284,6 +241383,7 @@ var init_inbox = __esm({
|
|
|
241284
241383
|
init_src8();
|
|
241285
241384
|
init_src();
|
|
241286
241385
|
init_node_state();
|
|
241386
|
+
init_activity_text();
|
|
241287
241387
|
C_ACTION_LABEL = {
|
|
241288
241388
|
unlink: "\u65AD\u5F00\u4F9D\u8D56\u8FB9",
|
|
241289
241389
|
pin: "\u6539\u9489\u7248\u672C",
|
|
@@ -247596,11 +247696,12 @@ function nodesDomain(deps) {
|
|
|
247596
247696
|
...typeof r.presentOnMachine === "boolean" ? { presentOnMachine: r.presentOnMachine } : {}
|
|
247597
247697
|
};
|
|
247598
247698
|
}
|
|
247599
|
-
function revokeNodeAccess(nodeId) {
|
|
247699
|
+
function revokeNodeAccess(nodeId, opts = {}) {
|
|
247700
|
+
const tellMachine = opts.tellMachine ?? true;
|
|
247600
247701
|
const daemon = deps.getHub()?.connectedDaemons().find((d) => d.daemonId === nodeId);
|
|
247601
|
-
daemon?.send({ type: "node_deleted", nodeId });
|
|
247702
|
+
if (tellMachine) daemon?.send({ type: "node_deleted", nodeId });
|
|
247602
247703
|
for (const { token: token2, nodeId: nid } of deps.nodeTokens.list()) {
|
|
247603
|
-
if (nid === nodeId) deps.nodeTokens.revoke(token2, "node-deleted");
|
|
247704
|
+
if (nid === nodeId) deps.nodeTokens.revoke(token2, tellMachine ? "node-deleted" : "unspecified");
|
|
247604
247705
|
}
|
|
247605
247706
|
daemon?.close();
|
|
247606
247707
|
}
|
|
@@ -247608,9 +247709,9 @@ function nodesDomain(deps) {
|
|
|
247608
247709
|
const restartEmptyClock = (nodeId) => {
|
|
247609
247710
|
emptySince.set(nodeId, Date.now());
|
|
247610
247711
|
};
|
|
247611
|
-
async function removeNode(nodeId, releaseAs) {
|
|
247712
|
+
async function removeNode(nodeId, releaseAs, opts = {}) {
|
|
247612
247713
|
const kinds = [...new Set((await deps.nodeStore.listRuntimes(nodeId)).map((r) => r.kind))];
|
|
247613
|
-
revokeNodeAccess(nodeId);
|
|
247714
|
+
revokeNodeAccess(nodeId, opts);
|
|
247614
247715
|
await deps.nodeStore.deleteNode(nodeId);
|
|
247615
247716
|
emptySince.delete(nodeId);
|
|
247616
247717
|
const released = [];
|
|
@@ -247647,13 +247748,25 @@ function nodesDomain(deps) {
|
|
|
247647
247748
|
if (removed.length > 0) deps.onStatusChange?.();
|
|
247648
247749
|
return removed;
|
|
247649
247750
|
}
|
|
247751
|
+
async function purgeUnownedNodes() {
|
|
247752
|
+
const removed = [];
|
|
247753
|
+
for (const n of await deps.nodeStore.listUnownedNodes()) {
|
|
247754
|
+
const current = await deps.nodeStore.getNode(n.id);
|
|
247755
|
+
if (!current || current.companyId) continue;
|
|
247756
|
+
await removeNode(n.id, void 0, { tellMachine: false });
|
|
247757
|
+
removed.push(n.id);
|
|
247758
|
+
console.log(`[nodes] \u4F5C\u5E9F\u6CA1\u6709\u5F52\u5C5E\u516C\u53F8\u7684\u8282\u70B9\uFF1A${n.id}\uFF08\u4E3B\u673A\u540D ${n.hostname}${n.name ? `\uFF0C\u540D\u79F0 ${n.name}` : ""}\uFF0C\u72B6\u6001 ${n.status}\uFF09\u2014\u2014\u5DF2\u64A4\u51ED\u8BC1\u3001\u65AD\u5F00\u8FDE\u63A5\u3001\u5220\u9664\u8BB0\u5F55\uFF0C\u673A\u5668\u672C\u5730\u4E0D\u52A8\uFF1B\u91CD\u65B0\u8FD0\u884C\u63A5\u5165\u547D\u4EE4\u5373\u6309\u65B0\u673A\u5668\u63A5\u5165`);
|
|
247759
|
+
}
|
|
247760
|
+
if (removed.length > 0) deps.onStatusChange?.();
|
|
247761
|
+
return removed;
|
|
247762
|
+
}
|
|
247650
247763
|
if (deps.emptyNodeSweep) {
|
|
247651
247764
|
const { graceMs, intervalMs } = deps.emptyNodeSweep;
|
|
247652
247765
|
let sweeping = false;
|
|
247653
247766
|
const timer = setInterval(() => {
|
|
247654
247767
|
if (sweeping) return;
|
|
247655
247768
|
sweeping = true;
|
|
247656
|
-
void sweepEmptyNodes(graceMs).catch((err) => console.warn(`[nodes] \u7A7A\u8282\u70B9\u6E05\u626B\u5931\u8D25\uFF08\u4E0B\u4E00\u62CD\u518D\u8BD5\uFF09\uFF1A${err instanceof Error ? err.message : String(err)}`)).finally(() => {
|
|
247769
|
+
void purgeUnownedNodes().then(() => sweepEmptyNodes(graceMs)).catch((err) => console.warn(`[nodes] \u7A7A\u8282\u70B9\u6E05\u626B\u5931\u8D25\uFF08\u4E0B\u4E00\u62CD\u518D\u8BD5\uFF09\uFF1A${err instanceof Error ? err.message : String(err)}`)).finally(() => {
|
|
247657
247770
|
sweeping = false;
|
|
247658
247771
|
});
|
|
247659
247772
|
}, intervalMs);
|
|
@@ -248160,6 +248273,12 @@ function nodesDomain(deps) {
|
|
|
248160
248273
|
deps.enrollTokens.setIssuedNodeId(enrollToken, nodeId);
|
|
248161
248274
|
}
|
|
248162
248275
|
const existingNode = await deps.nodeStore.getNode(nodeId);
|
|
248276
|
+
if (existingNode && !existingNode.companyId && entry.companyId) {
|
|
248277
|
+
return {
|
|
248278
|
+
status: 409,
|
|
248279
|
+
body: { error: "NODE_UNOWNED", message: "\u8FD9\u53F0\u673A\u5668\u5728\u7CFB\u7EDF\u91CC\u7684\u65E7\u8BB0\u5F55\u6CA1\u6709\u5F52\u5C5E\u516C\u53F8\uFF0C\u4E0D\u80FD\u88AB\u63A5\u5165\uFF1B\u7CFB\u7EDF\u4F1A\u5728\u7EA6\u4E00\u5206\u949F\u5185\u6E05\u6389\u8FD9\u6761\u65E7\u8BB0\u5F55\uFF0C\u4E4B\u540E\u91CD\u65B0\u8FD0\u884C\u63A5\u5165\u547D\u4EE4\u5373\u53EF\u6309\u65B0\u673A\u5668\u63A5\u5165" }
|
|
248280
|
+
};
|
|
248281
|
+
}
|
|
248163
248282
|
if (existingNode?.companyId && entry.companyId && existingNode.companyId !== entry.companyId) {
|
|
248164
248283
|
return { status: 409, body: { error: "\u8BE5\u8282\u70B9\u65E0\u6CD5\u7528\u5F53\u524D\u5165\u7F51\u4EE4\u724C\u63A5\u7BA1" } };
|
|
248165
248284
|
}
|
|
@@ -249169,6 +249288,9 @@ var init_node_store = __esm({
|
|
|
249169
249288
|
const live = [...this.nodes.values()].filter((n) => n.status !== "deleted");
|
|
249170
249289
|
return filter?.companyId === void 0 ? live : live.filter((n) => n.companyId === filter.companyId);
|
|
249171
249290
|
}
|
|
249291
|
+
async listUnownedNodes() {
|
|
249292
|
+
return [...this.nodes.values()].filter((n) => !n.companyId);
|
|
249293
|
+
}
|
|
249172
249294
|
async listRuntimes(nodeId, filter) {
|
|
249173
249295
|
let all2 = [...this.runtimes.values()];
|
|
249174
249296
|
if (nodeId) all2 = all2.filter((r) => r.nodeId === nodeId);
|
|
@@ -253341,11 +253463,12 @@ function missingNodeFacts(body2) {
|
|
|
253341
253463
|
}
|
|
253342
253464
|
function renderEscalationOpeningBody(facts) {
|
|
253343
253465
|
const body2 = facts.body.trim();
|
|
253466
|
+
const who = facts.actorName ? plainActor(facts.actorName) : void 0;
|
|
253344
253467
|
if (facts.kind === "reviewer_unavailable") {
|
|
253345
253468
|
const { reviewerId, role } = reviewerUnavailableFacts(body2);
|
|
253346
253469
|
if (!reviewerId) return body2;
|
|
253347
253470
|
return [
|
|
253348
|
-
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u9501\u5B9A\u7684\u5BA1\u6838\u4EBA${
|
|
253471
|
+
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u9501\u5B9A\u7684\u5BA1\u6838\u4EBA${who ? ` ${who}` : ""}\uFF08${role} \u89D2\u8272\uFF09\u73B0\u5728\u4E0D\u53EF\u7528\u2014\u2014\u7194\u65AD\u3001\u79BB\u5C97\uFF0C\u6216\u8005\u5DF2\u88AB\u79FB\u51FA\u8FD9\u4E2A\u89D2\u8272\u2014\u2014\u8FD9\u4E00\u6B65\u7684\u8BC4\u5BA1\u6D3E\u4E0D\u51FA\u53BB\u3002`,
|
|
253349
253472
|
"\u9700\u8981\u4F60\u5B9A\u4E00\u4E0B\uFF1A\u6362\u4E00\u4E2A\u5BA1\u6838\u4EBA\uFF0C\u8FD8\u662F\u7B49\u539F\u5BA1\u6838\u4EBA\u6062\u590D\u3002"
|
|
253350
253473
|
].join("\n\n");
|
|
253351
253474
|
}
|
|
@@ -253353,7 +253476,7 @@ function renderEscalationOpeningBody(facts) {
|
|
|
253353
253476
|
const { gone, runtimeNode } = missingNodeFacts(body2);
|
|
253354
253477
|
if (!runtimeNode) return body2;
|
|
253355
253478
|
return [
|
|
253356
|
-
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u8FD8\u6CA1\u6709\u542F\u52A8\uFF1A${
|
|
253479
|
+
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u8FD8\u6CA1\u6709\u542F\u52A8\uFF1A${who ?? "\u6267\u884C\u4EBA"}\u7ED1\u5B9A\u7684\u8FD0\u884C\u8282\u70B9 ${runtimeNode} ${gone === "\u672A\u6CE8\u518C" ? "\u6CA1\u6709\u6CE8\u518C\u8FC7" : "\u5DF2\u7ECF\u88AB\u5220\u9664"}\uFF0C\u6D3E\u4E0D\u51FA\u53BB\u3002\u8FD9\u6B21\u68C0\u67E5\u6CA1\u6709\u7EC8\u6B62\u4EFB\u4F55\u4F1A\u8BDD\uFF0C\u4E5F\u6CA1\u6709\u6D88\u8017\u91CD\u8BD5\u6B21\u6570\u3002`,
|
|
253357
253480
|
"\u9700\u8981\u4F60\u6062\u590D\u90A3\u53F0\u8282\u70B9\uFF0C\u6216\u8005\u7ED9\u6267\u884C\u4EBA\u6539\u7ED1\u4E00\u53F0\u5728\u7EBF\u7684\u8282\u70B9\uFF1B\u4FEE\u597D\u4E4B\u540E\u544A\u8BC9\u6211\uFF0C\u6211\u6765\u628A\u8FD9\u4E00\u6B65\u653E\u51FA\u53BB\u3002"
|
|
253358
253481
|
].join("\n\n");
|
|
253359
253482
|
}
|
|
@@ -253362,7 +253485,7 @@ function renderEscalationOpeningBody(facts) {
|
|
|
253362
253485
|
const { count: count3, lastReason } = retryFacts(body2);
|
|
253363
253486
|
if (!count3) return body2;
|
|
253364
253487
|
return [
|
|
253365
|
-
`${
|
|
253488
|
+
`${who ?? "\u8FD9\u4E00\u6B65\u7684\u6267\u884C\u4EBA"}${at(facts.nodeLabel)}\u8FDE\u7EED ${count3.n} \u8F6E\u90FD\u6CA1\u8DD1\u6210\uFF0C\u81EA\u52A8\u91CD\u8BD5\u5DF2\u7ECF\u7528\u5B8C\u2014\u2014\u8FD9\u4E00\u6B65\u4E0D\u4F1A\u518D\u81EA\u52A8\u91CD\u6765\u4E86\u3002`,
|
|
253366
253489
|
...lastReason ? [`\u6700\u540E\u4E00\u6B21\u5931\u8D25\u8BB0\u4E0B\u7684\u539F\u56E0\uFF1A${lastReason}`] : [],
|
|
253367
253490
|
"\u9700\u8981\u4F60\u5B9A\u4E00\u4E0B\u63A5\u4E0B\u6765\u600E\u4E48\u529E\uFF1A\u6309\u539F\u65B9\u6848\u518D\u8BD5\u4E00\u6B21\u3001\u6539\u4E86\u4EFB\u52A1\u8BF4\u660E\u518D\u8DD1\uFF0C\u8FD8\u662F\u6362\u4E2A\u4EBA\u505A\u3002"
|
|
253368
253491
|
].join("\n\n");
|
|
@@ -253377,7 +253500,7 @@ function renderEscalationOpeningBody(facts) {
|
|
|
253377
253500
|
}
|
|
253378
253501
|
const { count: count2, minutes, cost, remark, stalled } = stallFacts(body2);
|
|
253379
253502
|
if (!count2) return body2;
|
|
253380
|
-
const subject = stalled ? `${
|
|
253503
|
+
const subject = stalled ? `${who ?? (stalled === "review" ? "\u8FD9\u4E00\u6B65\u7684\u8BC4\u5BA1\u5458" : "\u8FD9\u4E00\u6B65\u7684\u6267\u884C\u4EBA")}${at(facts.nodeLabel)}` : `\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D`;
|
|
253381
253504
|
const window3 = minutes !== void 0 ? `\u6700\u8FD1 ${minutes} \u5206\u949F\u91CC` : "\u6700\u8FD1\u4E00\u6BB5\u65F6\u95F4\u91CC";
|
|
253382
253505
|
const spent = cost ? `\uFF08\u8FD9\u4E9B\u7A7A\u8DD1\u5408\u8BA1\u5DF2\u7ECF\u82B1\u6389\u7EA6 ${cost}\uFF09` : "";
|
|
253383
253506
|
const each = count2.unit === "\u8F6E" ? "\u6BCF\u4E00\u8F6E" : "\u6BCF\u4E00\u6B21";
|
|
@@ -253393,6 +253516,7 @@ var num3, at;
|
|
|
253393
253516
|
var init_escalation_opening_body = __esm({
|
|
253394
253517
|
"../server/src/domains/collab/escalation-opening-body.ts"() {
|
|
253395
253518
|
"use strict";
|
|
253519
|
+
init_activity_text();
|
|
253396
253520
|
num3 = (v2) => {
|
|
253397
253521
|
if (v2 === void 0) return void 0;
|
|
253398
253522
|
const n = Number(v2);
|
|
@@ -272051,6 +272175,10 @@ var init_postgres_nodes = __esm({
|
|
|
272051
272175
|
const r = filter?.companyId !== void 0 ? await this.pool.query(`SELECT * FROM ${this.s}.nodes WHERE status <> 'deleted' AND company_id = $1 ORDER BY enrolled_at ASC`, [filter.companyId]) : await this.pool.query(`SELECT * FROM ${this.s}.nodes WHERE status <> 'deleted' ORDER BY enrolled_at ASC`);
|
|
272052
272176
|
return r.rows.map(rowToNode);
|
|
272053
272177
|
}
|
|
272178
|
+
async listUnownedNodes() {
|
|
272179
|
+
const r = await this.pool.query(`SELECT * FROM ${this.s}.nodes WHERE company_id IS NULL ORDER BY enrolled_at ASC`);
|
|
272180
|
+
return r.rows.map(rowToNode);
|
|
272181
|
+
}
|
|
272054
272182
|
async listRuntimes(nodeId, filter) {
|
|
272055
272183
|
const where = [];
|
|
272056
272184
|
const params = [];
|
|
@@ -298232,7 +298360,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
298232
298360
|
}
|
|
298233
298361
|
}
|
|
298234
298362
|
}
|
|
298235
|
-
var CLI_VERSION = "2.2.
|
|
298363
|
+
var CLI_VERSION = "2.2.99" ? "2.2.99" : "dev";
|
|
298236
298364
|
function apiHeaders(token2, company) {
|
|
298237
298365
|
const headers = {
|
|
298238
298366
|
authorization: `Bearer ${token2}`,
|
|
@@ -302203,7 +302331,7 @@ function shimScript() {
|
|
|
302203
302331
|
}
|
|
302204
302332
|
|
|
302205
302333
|
// src/index.ts
|
|
302206
|
-
var PKG_VERSION = true ? "2.2.
|
|
302334
|
+
var PKG_VERSION = true ? "2.2.99" : "dev";
|
|
302207
302335
|
var LOCAL_BIN = localBin();
|
|
302208
302336
|
var NPM_PREFIX = npmPrefix();
|
|
302209
302337
|
var INSTANCE = DEFAULT_INSTANCE;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oasis_test_v2",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.99",
|
|
4
4
|
"description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"oasis": "./dist/index.js"
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"node": ">=20"
|
|
27
27
|
},
|
|
28
28
|
"oasisRelease": {
|
|
29
|
-
"sourceHead": "
|
|
29
|
+
"sourceHead": "705a5a2b945e6e24cd1ddefef8d0e6e148574808"
|
|
30
30
|
}
|
|
31
31
|
}
|