oasis_test_v2 2.2.121 → 2.2.123
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 +967 -223
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1634,6 +1634,165 @@ var init_todos = __esm({
|
|
|
1634
1634
|
}
|
|
1635
1635
|
});
|
|
1636
1636
|
|
|
1637
|
+
// ../contract/src/overlap.ts
|
|
1638
|
+
function overlapCandidateId(c5) {
|
|
1639
|
+
return c5.kind === "todo" ? c5.todoId : c5.kind === "workorder" ? c5.workorderId : c5.delegationId;
|
|
1640
|
+
}
|
|
1641
|
+
function overlapTokens(text7) {
|
|
1642
|
+
const out = /* @__PURE__ */ new Set();
|
|
1643
|
+
const norm = text7.normalize("NFKC").toLowerCase();
|
|
1644
|
+
let run = "";
|
|
1645
|
+
let word = "";
|
|
1646
|
+
const flushRun = () => {
|
|
1647
|
+
if (run.length === 1) out.add(run);
|
|
1648
|
+
for (let i5 = 0; i5 + 1 < run.length; i5++) out.add(run.slice(i5, i5 + 2));
|
|
1649
|
+
run = "";
|
|
1650
|
+
};
|
|
1651
|
+
const flushWord = () => {
|
|
1652
|
+
if (word.length >= 2) out.add(word);
|
|
1653
|
+
word = "";
|
|
1654
|
+
};
|
|
1655
|
+
for (const ch of norm) {
|
|
1656
|
+
if (isCjk(ch)) {
|
|
1657
|
+
flushWord();
|
|
1658
|
+
run += ch;
|
|
1659
|
+
continue;
|
|
1660
|
+
}
|
|
1661
|
+
flushRun();
|
|
1662
|
+
if (/[\p{L}\p{N}]/u.test(ch)) word += ch;
|
|
1663
|
+
else flushWord();
|
|
1664
|
+
}
|
|
1665
|
+
flushRun();
|
|
1666
|
+
flushWord();
|
|
1667
|
+
for (const t of [...out]) if (STOP_TOKENS.has(t)) out.delete(t);
|
|
1668
|
+
return out;
|
|
1669
|
+
}
|
|
1670
|
+
function overlapSimilarity(a5, b6) {
|
|
1671
|
+
if (a5.size === 0 || b6.size === 0) return 0;
|
|
1672
|
+
let shared = 0;
|
|
1673
|
+
for (const t of a5) if (b6.has(t)) shared++;
|
|
1674
|
+
return shared / Math.sqrt(a5.size * b6.size);
|
|
1675
|
+
}
|
|
1676
|
+
function overlapScore(query, title, body2) {
|
|
1677
|
+
const byTitle = overlapSimilarity(query, overlapTokens(title));
|
|
1678
|
+
const byAll = body2 ? overlapSimilarity(query, overlapTokens(`${title}
|
|
1679
|
+
${body2}`)) : byTitle;
|
|
1680
|
+
return Math.round(Math.max(byTitle, byAll) * 1e3) / 1e3;
|
|
1681
|
+
}
|
|
1682
|
+
function monthDay(dayOrIso, timeZone) {
|
|
1683
|
+
let day = dayOrIso.slice(0, 10);
|
|
1684
|
+
if (dayOrIso.length > 10) {
|
|
1685
|
+
try {
|
|
1686
|
+
day = new Intl.DateTimeFormat("sv-SE", { timeZone: timeZone ?? "UTC", year: "numeric", month: "2-digit", day: "2-digit" }).format(new Date(dayOrIso));
|
|
1687
|
+
} catch {
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
const [, m4, d5] = day.split("-");
|
|
1691
|
+
return `${Number(m4)} \u6708 ${Number(d5)} \u65E5`;
|
|
1692
|
+
}
|
|
1693
|
+
function formatOverlapCandidate(c5, timeZone) {
|
|
1694
|
+
const phase = c5.phase === "active" ? "\u5728\u505A" : "\u505A\u5B8C";
|
|
1695
|
+
if (c5.kind === "todo") {
|
|
1696
|
+
const people = c5.creatorActorId === c5.assigneeActorId ? who(c5.assigneeName, c5.assigneeActorId) : `${who(c5.creatorName, c5.creatorActorId)}\u2192${who(c5.assigneeName, c5.assigneeActorId)}`;
|
|
1697
|
+
const bits2 = [`${phase} \u5F85\u529E ${c5.todoId}`, `${people}\u300C${c5.title}\u300D`];
|
|
1698
|
+
if (c5.phase === "active" && c5.dueDate) bits2.push(`\u622A\u6B62 ${monthDay(c5.dueDate)}`);
|
|
1699
|
+
if (c5.phase === "done" && c5.doneAt) bits2.push(`${monthDay(c5.doneAt, timeZone)}\u5B8C\u6210`);
|
|
1700
|
+
if (c5.phase === "done") bits2.push(c5.result ? `\u7ED3\u679C\u5728\u54EA\uFF1A${c5.result}` : "\u7ED3\u679C\u5728\u54EA\uFF1A\uFF08\u6CA1\u8BB0\uFF09");
|
|
1701
|
+
if (c5.sourceChatSessionId) bits2.push(`\u51FA\u5904\u5BF9\u8BDD ${c5.sourceChatSessionId}`);
|
|
1702
|
+
return ` ${bits2.join(" ")}`;
|
|
1703
|
+
}
|
|
1704
|
+
if (c5.kind === "workorder") {
|
|
1705
|
+
const bits2 = [`${phase} \u5DE5\u5355 ${c5.workorderId}`, `${c5.initiatorActorId || c5.initiatorName ? who(c5.initiatorName, c5.initiatorActorId) : ""}\u300C${c5.title}\u300D`];
|
|
1706
|
+
if (c5.phase === "active" && c5.dueDate) bits2.push(`\u622A\u6B62 ${monthDay(c5.dueDate)}`);
|
|
1707
|
+
if (c5.phase === "done" && c5.endedAt) bits2.push(`${monthDay(c5.endedAt, timeZone)}\u7ED3\u675F`);
|
|
1708
|
+
if (c5.deliverableCount !== void 0) bits2.push(`\u4EA4\u4ED8\u7269 ${c5.deliverableCount} \u4E2A`);
|
|
1709
|
+
return ` ${bits2.join(" ")}`;
|
|
1710
|
+
}
|
|
1711
|
+
const bits = [
|
|
1712
|
+
`${phase} \u59D4\u6D3E ${c5.delegationId}\uFF08\u5B50\u4F1A\u8BDD ${c5.childSessionId}\uFF0C\u51FA\u81EA\u5BF9\u8BDD ${c5.parentSessionId}\uFF09`,
|
|
1713
|
+
`${who(c5.delegatorName, c5.delegatorActorId)}\u2192${who(c5.expertName, c5.expertActorId)}\u300C${c5.title}\u300D`
|
|
1714
|
+
];
|
|
1715
|
+
if (c5.phase === "done" && c5.settledAt) bits.push(`${monthDay(c5.settledAt, timeZone)}\u4EA4\u56DE`);
|
|
1716
|
+
bits.push(`\u4EA7\u51FA ${c5.artifactCount} \u4E2A`);
|
|
1717
|
+
return ` ${bits.join(" ")}`;
|
|
1718
|
+
}
|
|
1719
|
+
function formatOverlapLines(r5, timeZone) {
|
|
1720
|
+
const all2 = [...r5.active, ...r5.done];
|
|
1721
|
+
if (all2.length === 0) return [];
|
|
1722
|
+
return [OVERLAP_HEADING, ...all2.map((c5) => formatOverlapCandidate(c5, timeZone)), OVERLAP_LOOKUP_HINT, OVERLAP_HANDLING_HINT];
|
|
1723
|
+
}
|
|
1724
|
+
var OVERLAP_ACTIONS, STOP_TOKENS, isCjk, OVERLAP_HEADING, OVERLAP_LOOKUP_HINT, OVERLAP_HANDLING_HINT, who;
|
|
1725
|
+
var init_overlap = __esm({
|
|
1726
|
+
"../contract/src/overlap.ts"() {
|
|
1727
|
+
"use strict";
|
|
1728
|
+
OVERLAP_ACTIONS = ["todo-add", "delegate", "create-workorder", "run-playbook"];
|
|
1729
|
+
STOP_TOKENS = /* @__PURE__ */ new Set([
|
|
1730
|
+
"\u4E00\u4E0B",
|
|
1731
|
+
"\u5E2E\u6211",
|
|
1732
|
+
"\u6211\u4EEC",
|
|
1733
|
+
"\u4F60\u4EEC",
|
|
1734
|
+
"\u4ED6\u4EEC",
|
|
1735
|
+
"\u8FD9\u4E2A",
|
|
1736
|
+
"\u90A3\u4E2A",
|
|
1737
|
+
"\u8FD9\u4E9B",
|
|
1738
|
+
"\u90A3\u4E9B",
|
|
1739
|
+
"\u4E00\u4E2A",
|
|
1740
|
+
"\u4E00\u4EFD",
|
|
1741
|
+
"\u4E00\u7248",
|
|
1742
|
+
"\u4E00\u4E9B",
|
|
1743
|
+
"\u8FDB\u884C",
|
|
1744
|
+
"\u76F8\u5173",
|
|
1745
|
+
"\u9700\u8981",
|
|
1746
|
+
"\u5DF2\u7ECF",
|
|
1747
|
+
"\u8FD8\u662F",
|
|
1748
|
+
"\u7136\u540E",
|
|
1749
|
+
"\u4EE5\u53CA",
|
|
1750
|
+
"\u6216\u8005",
|
|
1751
|
+
"\u5982\u679C",
|
|
1752
|
+
"\u53EF\u4EE5",
|
|
1753
|
+
"\u8981\u6C42",
|
|
1754
|
+
"\u95EE\u9898",
|
|
1755
|
+
"\u4E8B\u60C5",
|
|
1756
|
+
"\u5DE5\u4F5C",
|
|
1757
|
+
"\u5904\u7406",
|
|
1758
|
+
"\u5B8C\u6210",
|
|
1759
|
+
"\u770B\u770B",
|
|
1760
|
+
"\u6574\u7406",
|
|
1761
|
+
"\u51C6\u5907",
|
|
1762
|
+
"\u4ECA\u5929",
|
|
1763
|
+
"\u660E\u5929",
|
|
1764
|
+
"\u672C\u5468",
|
|
1765
|
+
"\u4E0B\u5468",
|
|
1766
|
+
"\u5468\u4E00",
|
|
1767
|
+
"\u5468\u4E8C",
|
|
1768
|
+
"\u5468\u4E09",
|
|
1769
|
+
"\u5468\u56DB",
|
|
1770
|
+
"\u5468\u4E94",
|
|
1771
|
+
"\u5468\u516D",
|
|
1772
|
+
"\u5468\u65E5",
|
|
1773
|
+
"\u4E4B\u524D",
|
|
1774
|
+
"\u4E4B\u540E",
|
|
1775
|
+
"\u4EE5\u524D",
|
|
1776
|
+
"\u622A\u6B62",
|
|
1777
|
+
"the",
|
|
1778
|
+
"and",
|
|
1779
|
+
"for",
|
|
1780
|
+
"with",
|
|
1781
|
+
"from",
|
|
1782
|
+
"this",
|
|
1783
|
+
"that",
|
|
1784
|
+
"into",
|
|
1785
|
+
"todo",
|
|
1786
|
+
"task"
|
|
1787
|
+
]);
|
|
1788
|
+
isCjk = (ch) => /[㐀-鿿豈-]/u.test(ch);
|
|
1789
|
+
OVERLAP_HEADING = "\u76F8\u8FD1\u7684\u4E8B\u9879\uFF08\u7CFB\u7EDF\u7C97\u7B5B\uFF0C\u672A\u786E\u8BA4\uFF0C\u8BF7\u7528 id \u67E5\u8BE6\u60C5\u540E\u5224\u65AD\uFF09\uFF1A";
|
|
1790
|
+
OVERLAP_LOOKUP_HINT = "\u67E5\u8BE6\u60C5\uFF1A\u5F85\u529E oasis todo show <\u5F85\u529Eid>\uFF1B\u5DE5\u5355 oasis workorder <\u5DE5\u5355id>\uFF1B\u59D4\u6D3E oasis delegate --status <\u59D4\u6D3Eid>\uFF08\u522B\u4EBA\u5BF9\u8BDD\u91CC\u6D3E\u7684\u4E5F\u80FD\u67E5\u6458\u8981\uFF09";
|
|
1791
|
+
OVERLAP_HANDLING_HINT = "\u600E\u4E48\u7528\uFF1A\u9010\u6761\u67E5\u5B8C\u518D\u5224\u65AD\u662F\u4E0D\u662F\u540C\u4E00\u4EF6\u4E8B\uFF1B\u786E\u5B9E\u76F8\u5173\u624D\u544A\u8BC9\u7528\u6237\uFF0C\u4E0D\u76F8\u5173\u4E00\u4E2A\u5B57\u4E0D\u63D0\u3002\u5728\u505A\u7684\u5EFA\u8BAE\u7528\u6237\u5148\u95EE\u95EE\u5BF9\u65B9\uFF0C\u770B\u5408\u5E76\u8FD8\u662F\u5206\u5DE5\uFF1B\u505A\u5B8C\u7684\u628A\u7ED3\u679C\u7ED9\u7528\u6237\uFF0C\u95EE\u80FD\u4E0D\u80FD\u76F4\u63A5\u7528\u3002\u4E0D\u66FF\u7528\u6237\u5408\u5E76\u3001\u53D6\u6D88\u6216\u6539\u6D3E\u3002";
|
|
1792
|
+
who = (name, id) => name ?? id ?? "\uFF08\u672A\u77E5\uFF09";
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
|
|
1637
1796
|
// ../contract/src/credential-gap.ts
|
|
1638
1797
|
function buildCredentialGapDescription(opts) {
|
|
1639
1798
|
const { key: key2, scope: scope2, project, desc } = opts;
|
|
@@ -2140,6 +2299,21 @@ function trimRoundSummariesForReturn(summaries, recentRounds = DELEGATION_RETURN
|
|
|
2140
2299
|
return { round: summary.round, text: firstLine3, truncated: true };
|
|
2141
2300
|
});
|
|
2142
2301
|
}
|
|
2302
|
+
function delegationOverlapRowOf(record10, createdText) {
|
|
2303
|
+
return {
|
|
2304
|
+
id: record10.id,
|
|
2305
|
+
childSessionId: record10.childSessionId,
|
|
2306
|
+
parentSessionId: record10.parentSessionId,
|
|
2307
|
+
expertActorId: record10.expertActorId,
|
|
2308
|
+
state: record10.state === "done" ? "done" : "running",
|
|
2309
|
+
taskText: createdText?.trim() || record10.taskDigest || "",
|
|
2310
|
+
...record10.taskDigest ? { taskDigest: record10.taskDigest } : {},
|
|
2311
|
+
...record10.label ? { label: record10.label } : {},
|
|
2312
|
+
createdAt: record10.createdAt,
|
|
2313
|
+
...record10.settledAt ? { settledAt: record10.settledAt } : {},
|
|
2314
|
+
artifactCount: collectDelegationArtifacts(record10.roundSummaries).length
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2143
2317
|
function collectDelegationArtifacts(roundSummaries) {
|
|
2144
2318
|
const out = [];
|
|
2145
2319
|
for (const round of roundSummaries) {
|
|
@@ -2701,6 +2875,7 @@ var init_src = __esm({
|
|
|
2701
2875
|
init_variable_name();
|
|
2702
2876
|
init_time_zone();
|
|
2703
2877
|
init_todos();
|
|
2878
|
+
init_overlap();
|
|
2704
2879
|
init_credential_gap();
|
|
2705
2880
|
init_views();
|
|
2706
2881
|
init_telemetry();
|
|
@@ -21052,13 +21227,13 @@ async function persistFeishuUserTokens(store, actorId, data, nowMs) {
|
|
|
21052
21227
|
const { credentials: credentials2 } = parseFeishuTokenResponse(data, nowMs);
|
|
21053
21228
|
await persistRefreshedCredentials(store, new FeishuConnector(), actorId, credentials2);
|
|
21054
21229
|
}
|
|
21055
|
-
async function persistFeishuUserAuthorization(store, actorId, data, nowMs,
|
|
21230
|
+
async function persistFeishuUserAuthorization(store, actorId, data, nowMs, who2 = {}) {
|
|
21056
21231
|
await persistFeishuUserTokens(store, actorId, data, nowMs);
|
|
21057
21232
|
const scope2 = actorId ? { scope: "personal", actorId } : { scope: "global" };
|
|
21058
21233
|
const put3 = (key2, value2) => value2 ? store.putVariable({ key: key2, value: value2, ...scope2, connectorId: "feishu", encrypted: false }) : Promise.resolve();
|
|
21059
|
-
await put3(FEISHU_USER_OPEN_ID_VAR,
|
|
21060
|
-
await put3("FEISHU_USER_NAME",
|
|
21061
|
-
await put3(FEISHU_AUTHORIZED_BY_VAR,
|
|
21234
|
+
await put3(FEISHU_USER_OPEN_ID_VAR, who2.openId);
|
|
21235
|
+
await put3("FEISHU_USER_NAME", who2.userName);
|
|
21236
|
+
await put3(FEISHU_AUTHORIZED_BY_VAR, who2.authorizedBy);
|
|
21062
21237
|
await store.deleteVariable(FEISHU_USER_AUTH_INVALID_VAR, actorId);
|
|
21063
21238
|
}
|
|
21064
21239
|
async function readFeishuUserAuthInvalid(store, actorId) {
|
|
@@ -25000,15 +25175,15 @@ function createFeishuReauth(deps) {
|
|
|
25000
25175
|
return appId && appSecret ? { appId, appSecret } : null;
|
|
25001
25176
|
};
|
|
25002
25177
|
const settle = async (claims, store, data, sel, sendAsUserRequested, appId) => {
|
|
25003
|
-
const
|
|
25004
|
-
if (!
|
|
25178
|
+
const who2 = await (deps.identity ?? fetchFeishuUserIdentity)(String(data["access_token"] ?? ""));
|
|
25179
|
+
if (!who2.openId) {
|
|
25005
25180
|
return { state: "error", message: "\u6388\u6743\u5B8C\u6210\u4E86\uFF0C\u4F46\u6CA1\u80FD\u5411\u98DE\u4E66\u786E\u8BA4\u6388\u6743\u4EBA\u662F\u8C01\uFF0C\u672C\u6B21\u6388\u6743\u672A\u4FDD\u5B58\u3002\u8BF7\u7A0D\u540E\u91CD\u65B0\u70B9\u94FE\u63A5\u518D\u8BD5\u3002" };
|
|
25006
25181
|
}
|
|
25007
|
-
if (
|
|
25008
|
-
await deps.onRejected?.(claims,
|
|
25182
|
+
if (who2.openId !== claims.subject) {
|
|
25183
|
+
await deps.onRejected?.(claims, who2).catch((e5) => warn(`onRejected: ${String(e5)}`));
|
|
25009
25184
|
return {
|
|
25010
25185
|
state: "rejected",
|
|
25011
|
-
message: `\u8FD9\u4E2A\u94FE\u63A5\u53EA\u80FD\u7531\u539F\u6388\u6743\u4EBA\u672C\u4EBA\u4F7F\u7528\u3002\u4F60${
|
|
25186
|
+
message: `\u8FD9\u4E2A\u94FE\u63A5\u53EA\u80FD\u7531\u539F\u6388\u6743\u4EBA\u672C\u4EBA\u4F7F\u7528\u3002\u4F60${who2.name ? `\uFF08${who2.name}\uFF09` : ""}\u4E0D\u662F\u539F\u6388\u6743\u4EBA\uFF0C\u672C\u6B21\u6388\u6743\u672A\u4FDD\u5B58\uFF0C\u539F\u6388\u6743\u4FDD\u6301\u4E0D\u53D8\u3002`
|
|
25012
25187
|
};
|
|
25013
25188
|
}
|
|
25014
25189
|
const supplement = await withConnectorCredentialLock("feishu", claims.actorId, async () => {
|
|
@@ -25050,8 +25225,8 @@ function createFeishuReauth(deps) {
|
|
|
25050
25225
|
}
|
|
25051
25226
|
if (!kept) {
|
|
25052
25227
|
await persistFeishuUserAuthorization(store, claims.actorId, data, now(), {
|
|
25053
|
-
openId:
|
|
25054
|
-
...
|
|
25228
|
+
openId: who2.openId,
|
|
25229
|
+
...who2.name ? { userName: who2.name } : {},
|
|
25055
25230
|
...pending2?.applicant ? { authorizedBy: pending2.applicant } : {}
|
|
25056
25231
|
});
|
|
25057
25232
|
await store.putVariable({
|
|
@@ -25071,7 +25246,7 @@ function createFeishuReauth(deps) {
|
|
|
25071
25246
|
}
|
|
25072
25247
|
return outcome === null ? null : { outcome, kept };
|
|
25073
25248
|
});
|
|
25074
|
-
const userName =
|
|
25249
|
+
const userName = who2.name ? { userName: who2.name } : {};
|
|
25075
25250
|
if (supplement && supplement.outcome !== "complete") {
|
|
25076
25251
|
const saved = supplement.kept ? "\u4E3A\u4E0D\u5F71\u54CD\u5DF2\u6709\u7684\u98DE\u4E66\u80FD\u529B\uFF0C\u539F\u6388\u6743\u4FDD\u6301\u4E0D\u53D8\u3001\u8FD9\u6B21\u6388\u6743\u6CA1\u6709\u4FDD\u5B58\uFF08\u98DE\u4E66\u8FD9\u6B21\u7ED9\u7684\u6388\u6743\u4E0D\u5305\u542B\u4F60\u73B0\u6709\u6388\u6743\u7684\u5168\u90E8\u6743\u9650\uFF09\u3002" : "\u6388\u6743\u5DF2\u4FDD\u5B58\u3002";
|
|
25077
25252
|
const message = {
|
|
@@ -25081,8 +25256,8 @@ function createFeishuReauth(deps) {
|
|
|
25081
25256
|
}[supplement.outcome];
|
|
25082
25257
|
return { state: "incomplete", ...userName, message };
|
|
25083
25258
|
}
|
|
25084
|
-
await deps.onRestored?.(claims, { openId:
|
|
25085
|
-
return { state: "restored", ...
|
|
25259
|
+
await deps.onRestored?.(claims, { openId: who2.openId, ...userName }).catch((e5) => warn(`onRestored: ${String(e5)}`));
|
|
25260
|
+
return { state: "restored", ...who2.name ? { userName: who2.name } : {} };
|
|
25086
25261
|
};
|
|
25087
25262
|
const watch = async (deviceCode, entry, ctx) => {
|
|
25088
25263
|
while (now() < entry.expiresAtMs) {
|
|
@@ -152965,22 +153140,22 @@ function isRoundLimitParked(a5) {
|
|
|
152965
153140
|
}
|
|
152966
153141
|
return false;
|
|
152967
153142
|
}
|
|
152968
|
-
function latestMentionSeq(model, a5,
|
|
153143
|
+
function latestMentionSeq(model, a5, who2) {
|
|
152969
153144
|
const rootSeq = model.annotationSeq.get(a5.id) ?? 0;
|
|
152970
|
-
let seq = a5.mentions.includes(
|
|
153145
|
+
let seq = a5.mentions.includes(who2) ? rootSeq : -1;
|
|
152971
153146
|
for (const t of a5.thread) {
|
|
152972
|
-
if ((t.mentions ?? []).includes(
|
|
153147
|
+
if ((t.mentions ?? []).includes(who2) && (t.seq ?? rootSeq) > seq) seq = t.seq ?? rootSeq;
|
|
152973
153148
|
}
|
|
152974
153149
|
return seq;
|
|
152975
153150
|
}
|
|
152976
|
-
function repliedAfter(a5,
|
|
152977
|
-
return a5.thread.some((t) => t.author ===
|
|
153151
|
+
function repliedAfter(a5, who2, sinceSeq) {
|
|
153152
|
+
return a5.thread.some((t) => t.author === who2 && (t.seq ?? -1) > sinceSeq);
|
|
152978
153153
|
}
|
|
152979
|
-
function hasUnansweredMention(model, a5,
|
|
152980
|
-
const seq = latestMentionSeq(model, a5,
|
|
153154
|
+
function hasUnansweredMention(model, a5, who2) {
|
|
153155
|
+
const seq = latestMentionSeq(model, a5, who2);
|
|
152981
153156
|
if (seq < 0) return false;
|
|
152982
153157
|
if (seq <= (a5.resolvedAtSeq ?? Number.NEGATIVE_INFINITY)) return false;
|
|
152983
|
-
return !repliedAfter(a5,
|
|
153158
|
+
return !repliedAfter(a5, who2, seq);
|
|
152984
153159
|
}
|
|
152985
153160
|
function defaultRecipientOf(model, a5, owner) {
|
|
152986
153161
|
if (a5.mentions.length === 1) {
|
|
@@ -152990,10 +153165,10 @@ function defaultRecipientOf(model, a5, owner) {
|
|
|
152990
153165
|
}
|
|
152991
153166
|
return owner;
|
|
152992
153167
|
}
|
|
152993
|
-
function lastPostSeqOf(model, a5,
|
|
153168
|
+
function lastPostSeqOf(model, a5, who2) {
|
|
152994
153169
|
const rootSeq = model.annotationSeq.get(a5.id) ?? 0;
|
|
152995
|
-
let seq = a5.author ===
|
|
152996
|
-
for (const t of a5.thread) if (t.author ===
|
|
153170
|
+
let seq = a5.author === who2 ? rootSeq : Number.NEGATIVE_INFINITY;
|
|
153171
|
+
for (const t of a5.thread) if (t.author === who2 && (t.seq ?? rootSeq) > seq) seq = t.seq ?? rootSeq;
|
|
152997
153172
|
return seq;
|
|
152998
153173
|
}
|
|
152999
153174
|
function owesReplyOn(model, a5, recipient, owner) {
|
|
@@ -154435,11 +154610,11 @@ function anomalyLabel(a5) {
|
|
|
154435
154610
|
}
|
|
154436
154611
|
}
|
|
154437
154612
|
function renderLedgerMarkdown(ledger, opts = {}) {
|
|
154438
|
-
const
|
|
154613
|
+
const who2 = (id) => id === void 0 ? "\uFF08\u672A\u6307\u5B9A\uFF09" : opts.actorLabel?.(id) ?? id;
|
|
154439
154614
|
const out = [];
|
|
154440
154615
|
out.push(`## \u5DE5\u5355 ${ledger.workspace}${ledger.title ? ` \xB7 ${ledger.title}` : ""}`);
|
|
154441
154616
|
if (ledger.goal) out.push(`\u76EE\u6807\uFF1A${ledger.goal}`);
|
|
154442
|
-
out.push(`\u63D0\u5355\u4EBA ${
|
|
154617
|
+
out.push(`\u63D0\u5355\u4EBA ${who2(ledger.owner)} | \u7BA1\u7406\u8005 ${who2(ledger.manager)}`);
|
|
154443
154618
|
const span = ledger.startedAt && ledger.endedAt ? ` | ${ledger.startedAt} \u2192 ${ledger.endedAt}` : "";
|
|
154444
154619
|
out.push(`\u4EA7\u7269 ${ledger.artifactCount} \u4EFD | \u672A\u89E3\u7F3A\u53E3 ${ledger.unresolvedGapCount} | \u672A\u51B3\u6279\u6CE8 ${ledger.openAnnotationCount}${span}`);
|
|
154445
154620
|
if (ledger.briefId) out.push(`\u5DE5\u5355\u6B63\u6587\uFF1A\`oasis content ${ledger.briefId}\``);
|
|
@@ -154449,20 +154624,20 @@ function renderLedgerMarkdown(ledger, opts = {}) {
|
|
|
154449
154624
|
out.push(``, `### \u8282\u70B9\uFF08\u62D3\u6251\u5E8F\uFF09`);
|
|
154450
154625
|
ledger.nodes.forEach((n3, i5) => {
|
|
154451
154626
|
out.push(``);
|
|
154452
|
-
out.push(`[${i5 + 1}] ${n3.id} type=${n3.type} owner=${
|
|
154627
|
+
out.push(`[${i5 + 1}] ${n3.id} type=${n3.type} owner=${who2(n3.owner)}${n3.lifecycle !== "active" ? ` ${n3.lifecycle}` : ""}`);
|
|
154453
154628
|
if (n3.title) out.push(` ${n3.title}`);
|
|
154454
154629
|
const anomalies = n3.anomalies.length === 0 ? "0" : `${n3.anomalies.length}\uFF08${n3.anomalies.map(anomalyLabel).join("\u3001")}\uFF09`;
|
|
154455
154630
|
out.push(
|
|
154456
154631
|
` head=${shortRev(n3.head)} \u5DF2\u4EA4\u4ED8=${shortRev(n3.concludedHead)} \u7248\u672C ${n3.revisionCount} \u6253\u56DE ${n3.rejectedRounds} \u5F02\u5E38\u8BB0\u5F55 ${anomalies}`
|
|
154457
154632
|
);
|
|
154458
154633
|
for (const u of n3.upstreams) out.push(` \u4E0A\u6E38 ${u.to}@${shortRev(u.pinned)}${u.required ? " [required]" : ""}`);
|
|
154459
|
-
for (const g6 of n3.unresolvedGaps) out.push(` \u672A\u89E3\u7F3A\u53E3 by ${
|
|
154634
|
+
for (const g6 of n3.unresolvedGaps) out.push(` \u672A\u89E3\u7F3A\u53E3 by ${who2(g6.by)}\uFF1A${g6.description}`);
|
|
154460
154635
|
for (const a5 of n3.openAnnotations) {
|
|
154461
|
-
out.push(` \u672A\u51B3\u6279\u6CE8 [${a5.kind}] by ${
|
|
154636
|
+
out.push(` \u672A\u51B3\u6279\u6CE8 [${a5.kind}] by ${who2(a5.author)}${a5.stagedResolution ? `\uFF08\u5F85\u88C1\u51B3\uFF1A${a5.stagedResolution}\uFF09` : ""}\uFF1A${a5.body}`);
|
|
154462
154637
|
}
|
|
154463
154638
|
for (const r5 of n3.reviews) {
|
|
154464
154639
|
out.push(
|
|
154465
|
-
` \u7968 ${shortRev(r5.revisionId)} ${r5.verdict} ${r5.at} by ${
|
|
154640
|
+
` \u7968 ${shortRev(r5.revisionId)} ${r5.verdict} ${r5.at} by ${who2(r5.author)}` + (r5.hasNote ? `\uFF08\u8BC4\u8BED \`oasis content ${r5.noteRef}\`\uFF09` : "\uFF08\u65E0\u8BC4\u8BED\uFF09")
|
|
154466
154641
|
);
|
|
154467
154642
|
}
|
|
154468
154643
|
for (const r5 of n3.revisions) out.push(` reason ${shortRev(r5.id)}\uFF1A${r5.reason}`);
|
|
@@ -154934,7 +155109,7 @@ async function assembleContext(args) {
|
|
|
154934
155109
|
const detail = [];
|
|
154935
155110
|
for (const r5 of queued) {
|
|
154936
155111
|
const info = queuedParts.find((q4) => q4.revisionId === r5.id);
|
|
154937
|
-
const
|
|
155112
|
+
const who2 = r5.author === artifact.owner ? "\u4F60\u81EA\u5DF1\u4E0A\u4E00\u8F6E" : actorLabel(r5.author);
|
|
154938
155113
|
const baseC = await contentMapOf(r5.base ? model.revisions.get(r5.base) ?? null : null);
|
|
154939
155114
|
const newC = await contentMapOf(r5);
|
|
154940
155115
|
const dir = info?.dir ?? `competing/${slug3(r5.id.slice(9, 17))}`;
|
|
@@ -154951,7 +155126,7 @@ ${manifestDiff(baseC, newC)}
|
|
|
154951
155126
|
where = `\u5185\u5BB9\u89C1 \`${dir}/\`\uFF1B${queueHandler.diffFallback({ artifactId, contentRef: r5.contentRef, contentKind: r5.contentKind })}`;
|
|
154952
155127
|
}
|
|
154953
155128
|
detail.push(
|
|
154954
|
-
`- \`${r5.id.slice(9, 17)}\`\uFF08${
|
|
155129
|
+
`- \`${r5.id.slice(9, 17)}\`\uFF08${who2}${r5.part ? ` \xB7 \u90E8\u4EF6 ${r5.part}` : " \xB7 \u7ADE\u4E89\u7248"}\uFF09\uFF1A${r5.reason}
|
|
154955
155130
|
${where}`
|
|
154956
155131
|
);
|
|
154957
155132
|
}
|
|
@@ -161711,7 +161886,7 @@ var init_kernel_bridge = __esm({
|
|
|
161711
161886
|
const gap = gapId ? gapById(this.model, gapId) : null;
|
|
161712
161887
|
const hit = esc2?.resolved ? { kind: "escalation", id: esc2.escalationId, ...esc2.resolvedBy ? { resolvedBy: esc2.resolvedBy } : {}, ...esc2.resolvedAt ? { resolvedAt: esc2.resolvedAt } : {} } : gap?.resolved ? { kind: "gap", id: gap.gapId, ...gap.resolvedBy ? { resolvedBy: gap.resolvedBy } : {}, ...gap.resolvedAt ? { resolvedAt: gap.resolvedAt } : {} } : null;
|
|
161713
161888
|
if (!hit) continue;
|
|
161714
|
-
const
|
|
161889
|
+
const who2 = hit.resolvedBy ?? "\u7CFB\u7EDF";
|
|
161715
161890
|
const when = hit.resolvedAt ?? "\u66F4\u65E9";
|
|
161716
161891
|
out.push({
|
|
161717
161892
|
draftId,
|
|
@@ -161720,7 +161895,7 @@ var init_kernel_bridge = __esm({
|
|
|
161720
161895
|
proposedBy: card2.proposedBy,
|
|
161721
161896
|
origin: card2.origin ?? null,
|
|
161722
161897
|
target: hit,
|
|
161723
|
-
reason: `\u5DF2\u5931\u6548\uFF1A\u8FD9\u6761${hit.kind === "escalation" ? "\u4E0A\u62A5" : "\u7F3A\u53E3"}\uFF08${hit.id}\uFF09\u5DF2\u7531 ${
|
|
161898
|
+
reason: `\u5DF2\u5931\u6548\uFF1A\u8FD9\u6761${hit.kind === "escalation" ? "\u4E0A\u62A5" : "\u7F3A\u53E3"}\uFF08${hit.id}\uFF09\u5DF2\u7531 ${who2} \u4E8E ${when} \u5173\u95ED\uFF0C\u65E0\u9700\u518D\u5904\u7F6E\u3002`
|
|
161724
161899
|
});
|
|
161725
161900
|
}
|
|
161726
161901
|
return out;
|
|
@@ -183871,11 +184046,11 @@ function nodeReviewerReceiptLines(nodes5) {
|
|
|
183871
184046
|
return [
|
|
183872
184047
|
"\u5404\u8282\u70B9\u6700\u7EC8\u751F\u6548\u7684\u5BA1\u6838\u4EBA\uFF08\u300C\u6307\u5B9A\u300D= plan \u91CC reviewers \u7ED9\u7684\u4EBA\uFF0C\u5DF2\u66FF\u6362\u8BE5\u7C7B\u578B\u7684\u9ED8\u8BA4\u5BA1\u6838\u4EBA\uFF1B\u300C\u7C7B\u578B\u9ED8\u8BA4\u300D= \u6CA1\u6307\u5B9A\u3001\u6309\u8282\u70B9\u7C7B\u578B\u81EA\u5E26\uFF1B\u8DDF\u7528\u6237\u8BF4\u5BA1\u6838\u4EBA\u65F6\u4EE5\u8FD9\u91CC\u4E3A\u51C6\uFF09\uFF1A",
|
|
183873
184048
|
...nodes5.map((node2) => {
|
|
183874
|
-
const
|
|
184049
|
+
const who2 = (node2.reviewers ?? []).map((r5) => {
|
|
183875
184050
|
const name = r5.actor.name && r5.actor.name !== r5.actor.id ? `${r5.actor.name}\uFF08${r5.actor.id}\uFF0C` : `${r5.actor.id}\uFF08`;
|
|
183876
184051
|
return `${name}${REVIEWER_SOURCE_LABEL[r5.source]}\uFF09`;
|
|
183877
184052
|
});
|
|
183878
|
-
return ` ${node2.type}\u300C${node2.label}\u300D\uFF1A${
|
|
184053
|
+
return ` ${node2.type}\u300C${node2.label}\u300D\uFF1A${who2.length > 0 ? who2.join("\u3001") : "\u65E0\u5BA1\u6838\u4EBA"}`;
|
|
183879
184054
|
})
|
|
183880
184055
|
];
|
|
183881
184056
|
}
|
|
@@ -211478,6 +211653,53 @@ ${inboundBundle.paths.map((path50) => `- ${path50}`).join("\n")}` : text7,
|
|
|
211478
211653
|
...record10.settledAt ? { settledAt: record10.settledAt } : {}
|
|
211479
211654
|
};
|
|
211480
211655
|
}
|
|
211656
|
+
/**
|
|
211657
|
+
* `GET /api/delegations/:id/summary`(ADR 0640 第二批)——**本公司任何人**按 id 读一条委派的**摘要**:
|
|
211658
|
+
* 任务书、状态、专家、各轮小结、产出文件名、派活对话 id、子会话 id、派活人。
|
|
211659
|
+
*
|
|
211660
|
+
* 与 {@link get} 的分工:`get` 是协调者(派活那段对话)的工作口,`--status` / `--follow-up` 都靠它,**原样不动**;
|
|
211661
|
+
* 这条是给「别人对话里派出的委派」的只读口——防重叠比对的候选里带着委派 id,拿到了要能查。
|
|
211662
|
+
* - **不返回子会话的完整过程**(专家干活的原始记录,量大也用不上):任务书只取子会话第一轮那条输入,其余消息一条不读。
|
|
211663
|
+
* - 本公司:store 按调用者的公司取,别家公司的 id 在这里就是不存在(404,不区分「没有」与「不是你家的」)。
|
|
211664
|
+
* - 列表接口**不放开**:只能拿已知的 id 来读。
|
|
211665
|
+
*/
|
|
211666
|
+
async summary(delegationId, caller) {
|
|
211667
|
+
this.assertEnabled();
|
|
211668
|
+
const store = await this.options.resolveStore(caller.companyId);
|
|
211669
|
+
const record10 = await store.get(delegationId);
|
|
211670
|
+
if (!record10) throw new DelegationError(404, "DELEGATION_NOT_FOUND", `\u672C\u516C\u53F8\u6CA1\u6709 id \u4E3A ${delegationId} \u7684\u59D4\u6D3E\u3002`);
|
|
211671
|
+
const chatStore = await this.options.resolveChatSessions(caller.companyId).catch(() => null);
|
|
211672
|
+
const parent = chatStore ? await chatStore.getSession(record10.parentSessionId).catch(() => null) : null;
|
|
211673
|
+
if (parent?.companyId && caller.companyId && parent.companyId !== caller.companyId) {
|
|
211674
|
+
throw new DelegationError(404, "DELEGATION_NOT_FOUND", `\u672C\u516C\u53F8\u6CA1\u6709 id \u4E3A ${delegationId} \u7684\u59D4\u6D3E\u3002`);
|
|
211675
|
+
}
|
|
211676
|
+
const actors = await this.options.resolveActors(caller.companyId).catch(() => null);
|
|
211677
|
+
const nameOf2 = async (id) => id && actors ? (await actors.getActor(id).catch(() => null))?.name : void 0;
|
|
211678
|
+
const expertName = await nameOf2(record10.expertActorId);
|
|
211679
|
+
const delegator = parent?.humanActorId ?? void 0;
|
|
211680
|
+
const delegatorName = await nameOf2(delegator);
|
|
211681
|
+
const inputId = childRoundMessageIds(record10.childSessionId, 1).inputId;
|
|
211682
|
+
const firstInput = !chatStore ? null : chatStore.getMessage ? await chatStore.getMessage(inputId).catch(() => null) : (await chatStore.listMessages(record10.childSessionId).catch(() => [])).find((m4) => m4.id === inputId) ?? null;
|
|
211683
|
+
const task = firstInput?.sessionId === record10.childSessionId && firstInput.content ? firstInput.content : void 0;
|
|
211684
|
+
return {
|
|
211685
|
+
id: record10.id,
|
|
211686
|
+
parentSessionId: record10.parentSessionId,
|
|
211687
|
+
childSessionId: record10.childSessionId,
|
|
211688
|
+
...delegator ? { delegatorActorId: delegator } : {},
|
|
211689
|
+
...delegatorName ? { delegatorName } : {},
|
|
211690
|
+
expertActorId: record10.expertActorId,
|
|
211691
|
+
...expertName ? { expertName } : {},
|
|
211692
|
+
state: record10.state,
|
|
211693
|
+
...record10.failureKind ? { failureKind: record10.failureKind } : {},
|
|
211694
|
+
...record10.label ? { label: record10.label } : {},
|
|
211695
|
+
task: task ?? record10.taskDigest ?? "",
|
|
211696
|
+
...task ? {} : { taskTruncated: true },
|
|
211697
|
+
rounds: record10.roundSummaries.map((r5) => ({ round: r5.round, at: r5.at, text: r5.text, files: (r5.files ?? []).map((f6) => f6.name) })),
|
|
211698
|
+
artifacts: delegationArtifactsView(record10).map((a5) => a5.name),
|
|
211699
|
+
createdAt: record10.createdAt,
|
|
211700
|
+
...record10.settledAt ? { settledAt: record10.settledAt } : {}
|
|
211701
|
+
};
|
|
211702
|
+
}
|
|
211481
211703
|
/**
|
|
211482
211704
|
* `GET /api/delegations` —— **本父会话**的委派清单(`--list`)。
|
|
211483
211705
|
*
|
|
@@ -211654,6 +211876,13 @@ function delegationRoutes(service) {
|
|
|
211654
211876
|
rethrow(error3);
|
|
211655
211877
|
}
|
|
211656
211878
|
});
|
|
211879
|
+
router.get("/api/delegations/:id/summary", async (req) => {
|
|
211880
|
+
try {
|
|
211881
|
+
return { status: 200, body: await service.summary(req.params.id, callerOf(req)) };
|
|
211882
|
+
} catch (error3) {
|
|
211883
|
+
rethrow(error3);
|
|
211884
|
+
}
|
|
211885
|
+
});
|
|
211657
211886
|
router.get("/api/delegations/:id", async (req) => {
|
|
211658
211887
|
try {
|
|
211659
211888
|
return { status: 200, body: await service.get(req.params.id, callerOf(req)) };
|
|
@@ -211737,6 +211966,12 @@ var init_store2 = __esm({
|
|
|
211737
211966
|
async listByParent(parentSessionId, opts) {
|
|
211738
211967
|
return [...this.rows.values()].filter((r5) => r5.parentSessionId === parentSessionId && (!opts?.state || r5.state === opts.state)).sort((a5, b6) => a5.createdAt === b6.createdAt ? a5.id.localeCompare(b6.id) : a5.createdAt.localeCompare(b6.createdAt)).map((r5) => this.clone(r5));
|
|
211739
211968
|
}
|
|
211969
|
+
/** 防重叠比对的委派池(ADR 0640 第二批):与 PG 版同一口径——进行中与已交回的,失败的不给;任务书摘要取发起那次的流水。 */
|
|
211970
|
+
async listForOverlap() {
|
|
211971
|
+
const createdText = /* @__PURE__ */ new Map();
|
|
211972
|
+
for (const t of this.touches.values()) if (t.kind === "created") createdText.set(t.delegationId, t.textDigest);
|
|
211973
|
+
return [...this.rows.values()].filter((r5) => r5.state === "running" || r5.state === "done").sort((a5, b6) => a5.createdAt === b6.createdAt ? a5.id.localeCompare(b6.id) : b6.createdAt.localeCompare(a5.createdAt)).map((r5) => delegationOverlapRowOf(this.clone(r5), createdText.get(r5.id)));
|
|
211974
|
+
}
|
|
211740
211975
|
async patch(id, patch) {
|
|
211741
211976
|
const current = this.rows.get(id);
|
|
211742
211977
|
if (!current) return null;
|
|
@@ -212048,8 +212283,8 @@ function delegationReturnSource(record10) {
|
|
|
212048
212283
|
}
|
|
212049
212284
|
function delegationReturnText(terminal, opts) {
|
|
212050
212285
|
const { record: record10 } = terminal;
|
|
212051
|
-
const
|
|
212052
|
-
const name = record10.label ? `${
|
|
212286
|
+
const who2 = terminal.expertName ?? record10.expertActorId;
|
|
212287
|
+
const name = record10.label ? `${who2}\uFF08${record10.label}\uFF09` : who2;
|
|
212053
212288
|
const lastRoundText = record10.roundSummaries[record10.roundSummaries.length - 1]?.text;
|
|
212054
212289
|
const ending = delegationEnding(record10, {
|
|
212055
212290
|
movedFiles: opts.movedPaths.length,
|
|
@@ -214367,8 +214602,8 @@ async function runView(kernel, oplog, engineStore, blobs, name, artifactId, para
|
|
|
214367
214602
|
if (!rev) throw new Error(`\u7248\u672C\u4E0D\u5B58\u5728: ${revisionId}\uFF08\u8BC4\u5BA1\u7968 id \u7684\u524D\u534A\u6BB5\u5E94\u662F revision \u7684 uuid\uFF09`);
|
|
214368
214603
|
const mine = (model.reviews.get(revisionId) ?? []).filter((v2) => v2.author === author);
|
|
214369
214604
|
if (mine.length === 0) {
|
|
214370
|
-
const
|
|
214371
|
-
throw new Error(`${author} \u6CA1\u6709\u5728 ${revisionId} \u4E0A\u6295\u8FC7\u7968${
|
|
214605
|
+
const who2 = [...new Set((model.reviews.get(revisionId) ?? []).map((v2) => v2.author))].join("\u3001");
|
|
214606
|
+
throw new Error(`${author} \u6CA1\u6709\u5728 ${revisionId} \u4E0A\u6295\u8FC7\u7968${who2 ? `\uFF08\u8BE5\u7248\u672C\u7684\u6295\u7968\u4EBA\uFF1A${who2}\uFF09` : "\uFF08\u8BE5\u7248\u672C\u65E0\u4EBA\u6295\u7968\uFF09"}`);
|
|
214372
214607
|
}
|
|
214373
214608
|
const owner = model.artifacts.get(rev.artifactId);
|
|
214374
214609
|
return {
|
|
@@ -214893,10 +215128,10 @@ async function startOasisServer(opts) {
|
|
|
214893
215128
|
...fp(p4)
|
|
214894
215129
|
}))
|
|
214895
215130
|
] : [];
|
|
214896
|
-
const { randomUUID:
|
|
215131
|
+
const { randomUUID: randomUUID53 } = await import("node:crypto");
|
|
214897
215132
|
try {
|
|
214898
215133
|
await store.enqueuePendingMessage({
|
|
214899
|
-
id:
|
|
215134
|
+
id: randomUUID53(),
|
|
214900
215135
|
chatSessionId: input.chatSessionId,
|
|
214901
215136
|
text: input.text,
|
|
214902
215137
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -214929,11 +215164,11 @@ async function startOasisServer(opts) {
|
|
|
214929
215164
|
...f6?.mtime ? { srcMtime: f6.mtime } : {}
|
|
214930
215165
|
};
|
|
214931
215166
|
});
|
|
214932
|
-
const { randomUUID:
|
|
215167
|
+
const { randomUUID: randomUUID53 } = await import("node:crypto");
|
|
214933
215168
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
214934
215169
|
try {
|
|
214935
215170
|
await store.enqueuePendingMessage({
|
|
214936
|
-
id:
|
|
215171
|
+
id: randomUUID53(),
|
|
214937
215172
|
chatSessionId: input.chatSessionId,
|
|
214938
215173
|
text: "",
|
|
214939
215174
|
createdAt: nowIso,
|
|
@@ -216427,7 +216662,7 @@ async function startOasisServer(opts) {
|
|
|
216427
216662
|
const openRoom = async () => {
|
|
216428
216663
|
let chatSessionId2;
|
|
216429
216664
|
if (chatStore) {
|
|
216430
|
-
const { randomUUID:
|
|
216665
|
+
const { randomUUID: randomUUID53 } = await import("node:crypto");
|
|
216431
216666
|
const known = discussSessions.get(itemKey);
|
|
216432
216667
|
const knownSession = known ? await chatStore.getSession(known) : null;
|
|
216433
216668
|
if (knownSession && knownSession.workspace === ctx.workspace && knownSession.humanActorId === ctx.ownerId && (!body2.escalationId || knownSession.escalationId === body2.escalationId)) chatSessionId2 = known;
|
|
@@ -216436,7 +216671,7 @@ async function startOasisServer(opts) {
|
|
|
216436
216671
|
chatSessionId2 = existing[0]?.id;
|
|
216437
216672
|
}
|
|
216438
216673
|
if (!chatSessionId2) {
|
|
216439
|
-
chatSessionId2 =
|
|
216674
|
+
chatSessionId2 = randomUUID53();
|
|
216440
216675
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
216441
216676
|
const title = `\u89E3\u51B3\uFF1A${ctx.seed.slice(ctx.seed.indexOf("\uFF1A") + 1, ctx.seed.indexOf("\uFF1A") + 25) || "\u5DE5\u5355\u5361\u70B9"}`;
|
|
216442
216677
|
const reg0 = (await resolveEngine(currentCompanyId).catch(() => null))?.registry ?? opts.registry;
|
|
@@ -217657,7 +217892,7 @@ ${composed}`;
|
|
|
217657
217892
|
if (rejectedLedger.failures === 0 && retriedRow) {
|
|
217658
217893
|
turnPersisted = true;
|
|
217659
217894
|
} else if (rejectedLedger.failures === 0) {
|
|
217660
|
-
const { randomUUID:
|
|
217895
|
+
const { randomUUID: randomUUID53 } = await import("node:crypto");
|
|
217661
217896
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
217662
217897
|
const rejectedAttachments = effectiveAttachments.map((a5) => ({
|
|
217663
217898
|
name: a5.name,
|
|
@@ -217665,7 +217900,7 @@ ${composed}`;
|
|
|
217665
217900
|
...a5.contentType !== void 0 ? { contentType: a5.contentType } : {}
|
|
217666
217901
|
}));
|
|
217667
217902
|
await chatStore.appendMessage({
|
|
217668
|
-
id:
|
|
217903
|
+
id: randomUUID53(),
|
|
217669
217904
|
sessionId: persistTarget.id,
|
|
217670
217905
|
role: "user",
|
|
217671
217906
|
content: persistedUserMessage,
|
|
@@ -217750,14 +217985,14 @@ ${composed}`;
|
|
|
217750
217985
|
runtimeSessionId: session.nativeSessionId ?? session.id
|
|
217751
217986
|
}).catch(() => void 0);
|
|
217752
217987
|
}
|
|
217753
|
-
const { randomUUID:
|
|
217988
|
+
const { randomUUID: randomUUID53 } = await import("node:crypto");
|
|
217754
217989
|
const persistAttachments = effectiveAttachments.map((a5) => ({
|
|
217755
217990
|
name: a5.name,
|
|
217756
217991
|
...a5.blobRef !== void 0 ? { blobRef: a5.blobRef } : {},
|
|
217757
217992
|
...a5.contentType !== void 0 ? { contentType: a5.contentType } : {}
|
|
217758
217993
|
}));
|
|
217759
217994
|
if (!retriedRow) await chatStore.appendMessage({
|
|
217760
|
-
id:
|
|
217995
|
+
id: randomUUID53(),
|
|
217761
217996
|
sessionId: persistTarget.id,
|
|
217762
217997
|
role: "user",
|
|
217763
217998
|
content: persistedUserMessage,
|
|
@@ -218409,8 +218644,8 @@ ${composed}`;
|
|
|
218409
218644
|
res.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: `\u56DE\u8C03\u5730\u5740\u4E0D\u53EF\u7528\uFF0C\u5DF2\u4E2D\u6B62\uFF08\u907F\u514D\u5728 GitHub \u4E0A\u7559\u4E0B\u5B64\u513F App\uFF09\uFF1A${e5.message}` }));
|
|
218410
218645
|
return;
|
|
218411
218646
|
}
|
|
218412
|
-
const { randomUUID:
|
|
218413
|
-
const state2 =
|
|
218647
|
+
const { randomUUID: randomUUID53 } = await import("node:crypto");
|
|
218648
|
+
const state2 = randomUUID53();
|
|
218414
218649
|
const nameSlug = (actorName || actorId?.split(":").pop() || owner?.login || "bot").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "").slice(0, 24) || "bot";
|
|
218415
218650
|
const nameSuffix = await chooseAppNameSuffix(
|
|
218416
218651
|
{ employeeSlug: nameSlug, namePrefix: "oasis" },
|
|
@@ -219202,10 +219437,10 @@ ${composed}`;
|
|
|
219202
219437
|
await svc.putVariable({ key: "FEISHU_APP_ID", value: appId, scope: "global", connectorId: "feishu", encrypted: true });
|
|
219203
219438
|
await svc.upsertConnector({ id: "feishu", name: "\u98DE\u4E66", mode: "oauth", status: "connected", account: appId });
|
|
219204
219439
|
}
|
|
219205
|
-
const
|
|
219440
|
+
const who2 = await fetchFeishuUserIdentity(String(data["access_token"]));
|
|
219206
219441
|
await withConnectorCredentialLock("feishu", actorId, () => persistFeishuUserAuthorization(svc, actorId, data, Date.now(), {
|
|
219207
|
-
...
|
|
219208
|
-
...
|
|
219442
|
+
...who2.openId ? { openId: who2.openId } : {},
|
|
219443
|
+
...who2.name ? { userName: who2.name } : {},
|
|
219209
219444
|
...isHumanActorId(actor) ? { authorizedBy: actor } : {}
|
|
219210
219445
|
}));
|
|
219211
219446
|
const nameScope = actorId ? { scope: "personal", actorId } : { scope: "global" };
|
|
@@ -219235,7 +219470,7 @@ ${composed}`;
|
|
|
219235
219470
|
console.error(`[feishu-oauth] \u5F85\u5BA1\u6279\u8BB0\u5F55\u5199\u5165\u5931\u8D25: ${String(e5)}`);
|
|
219236
219471
|
}
|
|
219237
219472
|
}
|
|
219238
|
-
if (!
|
|
219473
|
+
if (!who2.openId) console.error("[feishu-oauth] user_info \u672A\u53D6\u5230\u6388\u6743\u4EBA open_id\uFF1A\u6388\u6743\u5931\u6548\u65F6\u65E0\u6CD5\u79C1\u4FE1\u672C\u4EBA\u3001\u4E5F\u7B7E\u4E0D\u51FA\u4E00\u952E\u91CD\u65B0\u6388\u6743\u94FE\u63A5");
|
|
219239
219474
|
try {
|
|
219240
219475
|
const secret = await svc.revealResolvedVariable("FEISHU_APP_SECRET", actorId);
|
|
219241
219476
|
if (secret) {
|
|
@@ -230841,10 +231076,10 @@ async function scanZeroOutputBreaker(deps) {
|
|
|
230841
231076
|
closingRemark
|
|
230842
231077
|
});
|
|
230843
231078
|
tripped.push(b6.artifactId);
|
|
230844
|
-
const
|
|
231079
|
+
const who2 = axis === "count" ? `${b6.actorId}\uFF08${b6.cls}\uFF09` : "\u8BE5\u8282\u70B9\u5168\u90E8\u6267\u884C\u4EBA\u5408\u8BA1";
|
|
230845
231080
|
const cidTag = deps.defaultCompanyId && b6.companyId !== deps.defaultCompanyId ? ` [${b6.companyId}]` : "";
|
|
230846
231081
|
deps.log?.(
|
|
230847
|
-
`[zero-output-breaker] ${b6.artifactId}${cidTag}\uFF1A\u6700\u8FD1 ${Math.round(deps.windowMs / 6e4)} \u5206\u949F\u5185 ${
|
|
231082
|
+
`[zero-output-breaker] ${b6.artifactId}${cidTag}\uFF1A\u6700\u8FD1 ${Math.round(deps.windowMs / 6e4)} \u5206\u949F\u5185 ${who2} \u7D2F\u8BA1 ${b6.count} \u6B21\u96F6\u4EA7\u51FA\uFF08${b6.rounds.size} \u8F6E\uFF0C\u7EA6 $${(b6.costUsdMicros / 1e6).toFixed(1)}\uFF09\u2192 ${axis} \u8F74\u8DF3\u95F8`
|
|
230848
231083
|
);
|
|
230849
231084
|
};
|
|
230850
231085
|
const byKey = (a5, b6) => a5.artifactId.localeCompare(b6.artifactId) || (a5.actorId ?? "").localeCompare(b6.actorId ?? "");
|
|
@@ -230881,9 +231116,9 @@ ${t.closingRemark.trim()}` : "";
|
|
|
230881
231116
|
|
|
230882
231117
|
` + tail;
|
|
230883
231118
|
}
|
|
230884
|
-
const
|
|
231119
|
+
const who2 = t.cls === "review" ? `\u8BC4\u5BA1\u5458 ${t.actorId}` : `\u6267\u884C\u4EBA ${t.actorId}`;
|
|
230885
231120
|
const what = t.cls === "review" ? `\u5DF2\u505C\u6389\u8FD9\u540D\u8BC4\u5BA1\u5458\u5728\u672C\u8282\u70B9\u4E0A\u7684\u8BC4\u5BA1\uFF08**\u4EA4\u4ED8\u5185\u5BB9\u539F\u6837\u4FDD\u7559**\uFF0C\u6062\u590D\u540E\u53EF\u7EE7\u7EED\u6295\u7968\uFF09` : `\u5DF2\u81EA\u52A8\u6682\u505C\u8BE5\u4EA7\u7269\u7684\u6D3E\u53D1\u4EE5\u6B62\u635F`;
|
|
230886
|
-
return `${
|
|
231121
|
+
return `${who2} \u5728\u6700\u8FD1 ${mins} \u5206\u949F\u5185\u4E3A\u8FD9\u4E2A\u4EA7\u7269\u8DD1\u4E86 ${t.workCount} \u8F6E\uFF0C**\u6BCF\u4E00\u8F6E\u90FD\u4EC0\u4E48\u90FD\u6CA1\u4EA4\u51FA\u6765**\uFF08${runs}\u8FD9\u4E9B\u7A7A\u8DD1\u7D2F\u8BA1\u82B1\u8D39\u7EA6 $${usd2}\uFF09\uFF0C${what}\u3002
|
|
230887
231122
|
|
|
230888
231123
|
` + tail;
|
|
230889
231124
|
}
|
|
@@ -242337,9 +242572,9 @@ function buildWorkorderActivity(input) {
|
|
|
242337
242572
|
if (!worded.length) continue;
|
|
242338
242573
|
const last = worded.at(-1);
|
|
242339
242574
|
const name = nodeName(card2.nodeId);
|
|
242340
|
-
const
|
|
242575
|
+
const who2 = personOf(card2.executorId);
|
|
242341
242576
|
const n3 = last.count ?? card2.foldedRounds ?? card2.traceWorkIds?.length ?? 1;
|
|
242342
|
-
const sentence = last.kind === "retry_exhausted" ? ACTIVITY_COPY.retryExhausted(
|
|
242577
|
+
const sentence = last.kind === "retry_exhausted" ? ACTIVITY_COPY.retryExhausted(who2, name, n3, lastFailureOf(card2, last) ?? last.lastReason) : ACTIVITY_COPY.outputStalled(who2, name, n3, last.cost);
|
|
242343
242578
|
card2.status = worded.length > 1 ? ACTIVITY_COPY.stopLossAgain(sentence, worded.length) : sentence;
|
|
242344
242579
|
}
|
|
242345
242580
|
const reviewedWorkIds = new Set([...snap.reviews, ...activityReviews(snap, events)].map((r5) => r5.targetWorkId));
|
|
@@ -243451,7 +243686,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
243451
243686
|
const gaps = unresolvedGapsOf(model, a5.id);
|
|
243452
243687
|
const escalations = unresolvedEscalationsOf(model, a5.id);
|
|
243453
243688
|
const representedEscalations = /* @__PURE__ */ new Set();
|
|
243454
|
-
const
|
|
243689
|
+
const who2 = isOwnerRecipient ? "\uFF08\u4F60\u662F\u5DE5\u5355\u5F52\u5C5E\u4EBA\uFF09" : "\uFF08\u4F60\u662F\u5361\u4F4F\u8282\u70B9 owner \u7684\u4E0A\u7EA7\uFF09";
|
|
243455
243690
|
for (const gap of gaps) {
|
|
243456
243691
|
const byGapId = escalations.filter((entry) => entry.gapId === gap.gapId);
|
|
243457
243692
|
const samePartGaps = gaps.filter((candidate) => candidate.part === gap.part);
|
|
@@ -243510,7 +243745,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
243510
243745
|
// ADR-0108 D10:**不再截到 100 字**。熔断升级卡走的正是这条「无 gap」分支,而 D10 刚
|
|
243511
243746
|
// 往里放进了真正有用的东西(末次失败原文、哪台机器死了多久、去哪改绑)——一刀切到 100 字
|
|
243512
243747
|
// 会把它们全砍掉,只剩「连败 N 次」这种人早就知道的部分。前端按卡片排版自己收,不在这里截。
|
|
243513
|
-
summary: `\u300C${nodeLabel(a5)}\u300D\u9700\u8981\u4F60\u5904\u7406${
|
|
243748
|
+
summary: `\u300C${nodeLabel(a5)}\u300D\u9700\u8981\u4F60\u5904\u7406${who2}\uFF1A${e5.reason}`
|
|
243514
243749
|
});
|
|
243515
243750
|
}
|
|
243516
243751
|
}
|
|
@@ -243972,7 +244207,7 @@ function sessionLabel(s3) {
|
|
|
243972
244207
|
const t = (s3.title ?? "").trim();
|
|
243973
244208
|
return t.length > 0 ? t : "\u672A\u547D\u540D\u4F1A\u8BDD";
|
|
243974
244209
|
}
|
|
243975
|
-
async function buildChatPreview(chatStore, sessionId,
|
|
244210
|
+
async function buildChatPreview(chatStore, sessionId, who2) {
|
|
243976
244211
|
let msgs;
|
|
243977
244212
|
if (chatStore.listRecentTurns) {
|
|
243978
244213
|
msgs = (await chatStore.listRecentTurns(sessionId, 1)).messages;
|
|
@@ -243983,7 +244218,7 @@ async function buildChatPreview(chatStore, sessionId, who) {
|
|
|
243983
244218
|
const lastAsst = [...msgs].reverse().find((m4) => m4.role === "assistant" && m4.content.trim().length > 0);
|
|
243984
244219
|
const lines = [];
|
|
243985
244220
|
if (lastUser) lines.push({ label: "\u4F60", text: clip3(lastUser.content) });
|
|
243986
|
-
if (lastAsst) lines.push({ label:
|
|
244221
|
+
if (lastAsst) lines.push({ label: who2, text: clip3(lastAsst.content) });
|
|
243987
244222
|
return lines.length ? { lines } : void 0;
|
|
243988
244223
|
}
|
|
243989
244224
|
async function buildChatInbox(chatStore, markers, me, resolveActor, excludeChildSessions) {
|
|
@@ -243995,10 +244230,10 @@ async function buildChatInbox(chatStore, markers, me, resolveActor, excludeChild
|
|
|
243995
244230
|
let previewsFetched = 0;
|
|
243996
244231
|
for (const s3 of unread) {
|
|
243997
244232
|
if (excluded.has(s3.id)) continue;
|
|
243998
|
-
const
|
|
243999
|
-
const whoText = resolveActor?.(s3.aiActorId)?.name ? `${atActorName(
|
|
244233
|
+
const who2 = resolveActor?.(s3.aiActorId)?.name ?? "\u52A9\u7406";
|
|
244234
|
+
const whoText = resolveActor?.(s3.aiActorId)?.name ? `${atActorName(who2)} ` : who2;
|
|
244000
244235
|
const abnormal = s3.lastTurnQuality === "abnormal";
|
|
244001
|
-
const preview2 = previewsFetched < PREVIEW_FETCH_CAP ? await buildChatPreview(chatStore, s3.id,
|
|
244236
|
+
const preview2 = previewsFetched < PREVIEW_FETCH_CAP ? await buildChatPreview(chatStore, s3.id, who2) : void 0;
|
|
244002
244237
|
if (preview2) previewsFetched++;
|
|
244003
244238
|
out.push({
|
|
244004
244239
|
kind: abnormal ? "chat-interrupted" : "chat-replied",
|
|
@@ -251504,9 +251739,9 @@ var init_allocate = __esm({
|
|
|
251504
251739
|
function describeRejections(rejections) {
|
|
251505
251740
|
return rejections.map((r5) => `${r5.nodeName} \xB7 ${r5.runtimeKind}\uFF08${CAUSE_TEXT[r5.cause]}${r5.detail ? `\uFF1A${r5.detail}` : ""}\uFF09`).join("\uFF1B");
|
|
251506
251741
|
}
|
|
251507
|
-
function describeAllocationFailure(result,
|
|
251508
|
-
const subject =
|
|
251509
|
-
const what =
|
|
251742
|
+
function describeAllocationFailure(result, who2) {
|
|
251743
|
+
const subject = who2?.actorName?.trim() ? `${atActorName(who2.actorName.trim())} ` : "\u8FD9\u4F4D Agent";
|
|
251744
|
+
const what = who2?.what?.trim() ? `${who2.what.trim()}\uFF1A` : "";
|
|
251510
251745
|
const detail = describeRejections(result.rejections);
|
|
251511
251746
|
if (result.reason === "no-candidates") {
|
|
251512
251747
|
return {
|
|
@@ -251528,9 +251763,9 @@ function describeAllocationFailure(result, who) {
|
|
|
251528
251763
|
message: `${what}${subject}\u7684\u8FD0\u884C\u65F6\u76EE\u524D\u90FD\u4E0D\u53EF\u7528\uFF0C\u672C\u6B21\u6CA1\u6709\u6D3E\u51FA\uFF1A${detail}\u3002\u8BF7\u786E\u8BA4\u90A3\u4E9B\u673A\u5668\u5F00\u7740\u3001\u8282\u70B9\u7A0B\u5E8F\u5728\u8FD0\u884C\u3001\u8FD0\u884C\u65F6\u5DF2\u767B\u5F55\u4E14\u989D\u5EA6\u672A\u8017\u5C3D\uFF1B\u6216\u5728\u5458\u5DE5\u8BE6\u60C5\u9875\u52A0\u4E00\u6761\u522B\u7684\u5019\u9009\u8FD0\u884C\u65F6\u3002`
|
|
251529
251764
|
};
|
|
251530
251765
|
}
|
|
251531
|
-
function requireAllocation(result,
|
|
251766
|
+
function requireAllocation(result, who2) {
|
|
251532
251767
|
if (result.ok) return result;
|
|
251533
|
-
const failure2 = describeAllocationFailure(result,
|
|
251768
|
+
const failure2 = describeAllocationFailure(result, who2);
|
|
251534
251769
|
throw new RuntimeAllocationError(failure2.code, failure2.message, result.rejections, failure2.status);
|
|
251535
251770
|
}
|
|
251536
251771
|
var RuntimeAllocationError, CAUSE_TEXT;
|
|
@@ -252371,8 +252606,8 @@ function resolvedByMe(row, evs, me, onNode) {
|
|
|
252371
252606
|
function resolvedByOther(row, evs, me, onNode) {
|
|
252372
252607
|
const gen = generationOfKey(row.sourceKey);
|
|
252373
252608
|
for (const rec2 of evs) {
|
|
252374
|
-
const
|
|
252375
|
-
if (
|
|
252609
|
+
const who2 = doerOf(rec2);
|
|
252610
|
+
if (who2 === me) continue;
|
|
252376
252611
|
switch (row.kind) {
|
|
252377
252612
|
case "review-request":
|
|
252378
252613
|
case "review-waiting": {
|
|
@@ -252382,14 +252617,14 @@ function resolvedByOther(row, evs, me, onNode) {
|
|
|
252382
252617
|
const vv = payload(x2, "review.response");
|
|
252383
252618
|
return !!vv && vv.targetWorkId === gen && vv.reviewerActorId !== me;
|
|
252384
252619
|
});
|
|
252385
|
-
return found(rec2, invalidated("handled-by-other", rec2.createdAt, decider ? doerOf(decider) :
|
|
252620
|
+
return found(rec2, invalidated("handled-by-other", rec2.createdAt, decider ? doerOf(decider) : who2));
|
|
252386
252621
|
}
|
|
252387
252622
|
break;
|
|
252388
252623
|
}
|
|
252389
252624
|
case "gap-escalation":
|
|
252390
252625
|
case "pushback": {
|
|
252391
252626
|
const r5 = payload(rec2, "issue.resolve");
|
|
252392
|
-
if (r5 && issueIdsOf(row).has(r5.issueId)) return found(rec2, invalidated("handled-by-other", rec2.createdAt,
|
|
252627
|
+
if (r5 && issueIdsOf(row).has(r5.issueId)) return found(rec2, invalidated("handled-by-other", rec2.createdAt, who2));
|
|
252393
252628
|
break;
|
|
252394
252629
|
}
|
|
252395
252630
|
case "needs-staffing": {
|
|
@@ -252402,7 +252637,7 @@ function resolvedByOther(row, evs, me, onNode) {
|
|
|
252402
252637
|
case "stale":
|
|
252403
252638
|
case "work-waiting": {
|
|
252404
252639
|
const acc = payload(rec2, "work.accept");
|
|
252405
|
-
if (acc && onNode(rec2)) return found(rec2, invalidated("handled-by-other", rec2.createdAt,
|
|
252640
|
+
if (acc && onNode(rec2)) return found(rec2, invalidated("handled-by-other", rec2.createdAt, who2));
|
|
252406
252641
|
break;
|
|
252407
252642
|
}
|
|
252408
252643
|
default:
|
|
@@ -255848,13 +256083,13 @@ function stallFacts(body2) {
|
|
|
255848
256083
|
const rawCost = /约\s*\$([\d.]+)/.exec(body2)?.[1];
|
|
255849
256084
|
const cost = rawCost !== void 0 && Number.isFinite(Number(rawCost)) ? `$${Number(rawCost).toFixed(2)}` : void 0;
|
|
255850
256085
|
const remark = body2.split("\u6700\u8FD1\u4E00\u6B21\u8FD0\u884C\u7684\u6536\u5C3E\u53D1\u8A00\uFF08\u5F80\u5F80\u76F4\u63A5\u5199\u7740\u5361\u5728\u54EA\uFF09\uFF1A\n")[1]?.trim();
|
|
255851
|
-
const
|
|
256086
|
+
const who2 = /^(执行人|评审员)\s+(actor:\S+)/.exec(body2.trim());
|
|
255852
256087
|
return {
|
|
255853
256088
|
...rounds !== void 0 ? { count: { n: rounds, unit: "\u8F6E" } } : runs !== void 0 ? { count: { n: runs, unit: "\u6B21\u8FD0\u884C" } } : {},
|
|
255854
256089
|
...minutes !== void 0 ? { minutes } : {},
|
|
255855
256090
|
...cost ? { cost } : {},
|
|
255856
256091
|
...remark ? { remark } : {},
|
|
255857
|
-
...
|
|
256092
|
+
...who2 ? { actorId: who2[2], stalled: who2[1] === "\u8BC4\u5BA1\u5458" ? "review" : "produce" } : {}
|
|
255858
256093
|
};
|
|
255859
256094
|
}
|
|
255860
256095
|
function firstSentence2(text7) {
|
|
@@ -255872,17 +256107,17 @@ function reviewerUnavailableFacts(body2) {
|
|
|
255872
256107
|
}
|
|
255873
256108
|
function missingNodeFacts(body2) {
|
|
255874
256109
|
const m4 = /指向(已删除|未注册)的节点\s+(\S+?)。/.exec(body2);
|
|
255875
|
-
const
|
|
255876
|
-
return { ...m4 ? { gone: m4[1], runtimeNode: m4[2] } : {}, ...
|
|
256110
|
+
const who2 = /为执行人\s+(actor:\S+)\s+选择/.exec(body2);
|
|
256111
|
+
return { ...m4 ? { gone: m4[1], runtimeNode: m4[2] } : {}, ...who2 ? { executorId: who2[1] } : {} };
|
|
255877
256112
|
}
|
|
255878
256113
|
function renderEscalationOpeningBody(facts) {
|
|
255879
256114
|
const body2 = facts.body.trim();
|
|
255880
|
-
const
|
|
256115
|
+
const who2 = facts.actorName ? plainActor(facts.actorName) : void 0;
|
|
255881
256116
|
if (facts.kind === "reviewer_unavailable") {
|
|
255882
256117
|
const { reviewerId, role } = reviewerUnavailableFacts(body2);
|
|
255883
256118
|
if (!reviewerId) return body2;
|
|
255884
256119
|
return [
|
|
255885
|
-
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u9501\u5B9A\u7684\u5BA1\u6838\u4EBA${
|
|
256120
|
+
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u9501\u5B9A\u7684\u5BA1\u6838\u4EBA${who2 ? ` ${who2}` : ""}\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`,
|
|
255886
256121
|
"\u9700\u8981\u4F60\u5B9A\u4E00\u4E0B\uFF1A\u6362\u4E00\u4E2A\u5BA1\u6838\u4EBA\uFF0C\u8FD8\u662F\u7B49\u539F\u5BA1\u6838\u4EBA\u6062\u590D\u3002"
|
|
255887
256122
|
].join("\n\n");
|
|
255888
256123
|
}
|
|
@@ -255890,7 +256125,7 @@ function renderEscalationOpeningBody(facts) {
|
|
|
255890
256125
|
const { gone, runtimeNode } = missingNodeFacts(body2);
|
|
255891
256126
|
if (!runtimeNode) return body2;
|
|
255892
256127
|
return [
|
|
255893
|
-
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u8FD8\u6CA1\u6709\u542F\u52A8\uFF1A${
|
|
256128
|
+
`\u300C${facts.nodeLabel ?? "\u8FD9\u4E00\u6B65"}\u300D\u8FD8\u6CA1\u6709\u542F\u52A8\uFF1A${who2 ?? "\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`,
|
|
255894
256129
|
"\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"
|
|
255895
256130
|
].join("\n\n");
|
|
255896
256131
|
}
|
|
@@ -255899,7 +256134,7 @@ function renderEscalationOpeningBody(facts) {
|
|
|
255899
256134
|
const { count: count3, lastReason } = retryFacts(body2);
|
|
255900
256135
|
if (!count3) return body2;
|
|
255901
256136
|
return [
|
|
255902
|
-
`${
|
|
256137
|
+
`${who2 ?? "\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`,
|
|
255903
256138
|
...lastReason ? [`\u6700\u540E\u4E00\u6B21\u5931\u8D25\u8BB0\u4E0B\u7684\u539F\u56E0\uFF1A${lastReason}`] : [],
|
|
255904
256139
|
"\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"
|
|
255905
256140
|
].join("\n\n");
|
|
@@ -255914,7 +256149,7 @@ function renderEscalationOpeningBody(facts) {
|
|
|
255914
256149
|
}
|
|
255915
256150
|
const { count: count2, minutes, cost, remark, stalled } = stallFacts(body2);
|
|
255916
256151
|
if (!count2) return body2;
|
|
255917
|
-
const subject = stalled ? `${
|
|
256152
|
+
const subject = stalled ? `${who2 ?? (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`;
|
|
255918
256153
|
const window3 = minutes !== void 0 ? `\u6700\u8FD1 ${minutes} \u5206\u949F\u91CC` : "\u6700\u8FD1\u4E00\u6BB5\u65F6\u95F4\u91CC";
|
|
255919
256154
|
const spent = cost ? `\uFF08\u8FD9\u4E9B\u7A7A\u8DD1\u5408\u8BA1\u5DF2\u7ECF\u82B1\u6389\u7EA6 ${cost}\uFF09` : "";
|
|
255920
256155
|
const each = count2.unit === "\u8F6E" ? "\u6BCF\u4E00\u8F6E" : "\u6BCF\u4E00\u6B21";
|
|
@@ -257681,20 +257916,20 @@ function shown(field, v2, nameOf2) {
|
|
|
257681
257916
|
if (field === "assignee") return nameOf2(v2);
|
|
257682
257917
|
return clip4(v2);
|
|
257683
257918
|
}
|
|
257684
|
-
function assignedTitle(
|
|
257685
|
-
return `${
|
|
257919
|
+
function assignedTitle(who2, todo) {
|
|
257920
|
+
return `${who2} \u6D3E\u7ED9\u4F60\uFF1A${todo.title}\uFF0C${formatTodoSpan(todo)}`;
|
|
257686
257921
|
}
|
|
257687
257922
|
function unseenTitle(assigneeName, todo) {
|
|
257688
257923
|
return `${assigneeName} \u8FD8\u6CA1\u770B\u8FC7\u8FD9\u6761\uFF1A${todo.title}\uFF0C\u660E\u5929\u622A\u6B62`;
|
|
257689
257924
|
}
|
|
257690
|
-
function changedTitle(
|
|
257925
|
+
function changedTitle(who2, todo, changes, nameOf2) {
|
|
257691
257926
|
const parts = changes.map((c5) => `${FIELD_LABEL[c5.field] ?? c5.field} ${shown(c5.field, c5.oldValue, nameOf2)} \u2192 ${shown(c5.field, c5.newValue, nameOf2)}`);
|
|
257692
257927
|
const reason = changes.find((c5) => c5.reason)?.reason;
|
|
257693
|
-
return `${
|
|
257928
|
+
return `${who2} \u6539\u4E86\u300C${todo.title}\u300D\uFF1A${parts.join("\uFF1B")}${reason ? `\uFF1B\u539F\u56E0\uFF1A${clip4(reason)}` : ""}`;
|
|
257694
257929
|
}
|
|
257695
|
-
function statusTitle(
|
|
257930
|
+
function statusTitle(who2, todo, kind, reason, result) {
|
|
257696
257931
|
const verb = kind === "todo-done" ? "\u5B8C\u6210\u4E86" : kind === "todo-reopened" ? "\u91CD\u65B0\u6253\u5F00\u4E86" : "\u53D6\u6D88\u4E86";
|
|
257697
|
-
return `${
|
|
257932
|
+
return `${who2} ${verb}\u300C${todo.title}\u300D${result ? `\uFF1B\u7ED3\u679C\uFF1A${clip4(result)}` : ""}${reason ? `\uFF1B\u539F\u56E0\uFF1A${clip4(reason)}` : ""}`;
|
|
257698
257933
|
}
|
|
257699
257934
|
var VALUE_MAX, FIELD_LABEL, clip4, todoAssignedSourceKey, todoChangeSourceKey, todoUnseenSourceKey;
|
|
257700
257935
|
var init_notices = __esm({
|
|
@@ -257710,7 +257945,8 @@ var init_notices = __esm({
|
|
|
257710
257945
|
dueDate: "\u622A\u6B62\u65E5",
|
|
257711
257946
|
dueTime: "\u622A\u6B62\u65F6\u523B",
|
|
257712
257947
|
linkedWorkorderId: "\u5173\u8054\u5DE5\u5355",
|
|
257713
|
-
assignee: "\u627F\u63A5\u4EBA"
|
|
257948
|
+
assignee: "\u627F\u63A5\u4EBA",
|
|
257949
|
+
result: "\u7ED3\u679C\u5728\u54EA"
|
|
257714
257950
|
};
|
|
257715
257951
|
clip4 = (v2) => v2.length > VALUE_MAX ? `${v2.slice(0, VALUE_MAX)}\u2026` : v2;
|
|
257716
257952
|
todoAssignedSourceKey = (todoId) => `todo:${todoId}@assigned`;
|
|
@@ -257745,7 +257981,7 @@ function assertStartBeforeDue(t) {
|
|
|
257745
257981
|
throw new ApiError(400, "TODO_START_AFTER_DUE", `\u5F00\u59CB\uFF08${fmt(t.startDate, t.startTime)}\uFF09\u4E0D\u80FD\u665A\u4E8E\u622A\u6B62\uFF08${fmt(t.dueDate, t.dueTime)}\uFF09`);
|
|
257746
257982
|
}
|
|
257747
257983
|
}
|
|
257748
|
-
var import_node_crypto71, TITLE_MAX, NOTE_MAX, REASON_MAX, LIST_MAX, clean2, TodoService;
|
|
257984
|
+
var import_node_crypto71, TITLE_MAX, NOTE_MAX, REASON_MAX, RESULT_MAX, LIST_MAX, clean2, TodoService;
|
|
257749
257985
|
var init_service10 = __esm({
|
|
257750
257986
|
"../server/src/domains/todos/service.ts"() {
|
|
257751
257987
|
"use strict";
|
|
@@ -257756,6 +257992,7 @@ var init_service10 = __esm({
|
|
|
257756
257992
|
TITLE_MAX = 200;
|
|
257757
257993
|
NOTE_MAX = 4e3;
|
|
257758
257994
|
REASON_MAX = 500;
|
|
257995
|
+
RESULT_MAX = 500;
|
|
257759
257996
|
LIST_MAX = 500;
|
|
257760
257997
|
clean2 = (v2) => {
|
|
257761
257998
|
const t = v2?.trim();
|
|
@@ -258023,6 +258260,11 @@ var init_service10 = __esm({
|
|
|
258023
258260
|
set("dueTime", input.dueTime ?? void 0);
|
|
258024
258261
|
}
|
|
258025
258262
|
if (input.linkedWorkorderId !== void 0) set("linkedWorkorderId", clean2(input.linkedWorkorderId));
|
|
258263
|
+
if (input.result !== void 0) {
|
|
258264
|
+
const result = clean2(input.result);
|
|
258265
|
+
if (result && result.length > RESULT_MAX) throw new ApiError(400, "TODO_INVALID", `result \u4E0D\u80FD\u8D85\u8FC7 ${RESULT_MAX} \u5B57`);
|
|
258266
|
+
set("result", result);
|
|
258267
|
+
}
|
|
258026
258268
|
if (input.assignee !== void 0) {
|
|
258027
258269
|
if (!isTodoUnsent(before)) throw new ApiError(400, "TODO_ASSIGNEE_LOCKED", "\u5DF2\u7ECF\u53D1\u51FA\u7684\u5F85\u529E\u4E0D\u80FD\u6362\u627F\u63A5\u4EBA\uFF1A\u53D6\u6D88\u8FD9\u6761\uFF08\u5E26\u539F\u56E0\uFF09\uFF0C\u518D\u91CD\u65B0\u6D3E\u4E00\u6761\u3002");
|
|
258028
258270
|
const assignee = await this.resolvePerson(input.assignee, caller);
|
|
@@ -258060,15 +258302,22 @@ var init_service10 = __esm({
|
|
|
258060
258302
|
/**
|
|
258061
258303
|
* 完成 / 取消 / 重新打开。草案(从没发出过的):不能完成;取消了也仍只有发起人看得到;重新打开回到草案、不会因此发出去。
|
|
258062
258304
|
* 别人派给我的,取消必须带原因(ADR 0640 D9)。派给别人且已发出的,动完通知另一方。
|
|
258305
|
+
*
|
|
258306
|
+
* 标完成可以顺带记「结果在哪」(`result`,ADR 0640 第二批):与状态同一次写入,单独一条 `field=result` 的变更记录;
|
|
258307
|
+
* 不给就不动原来的值(重开再完成不会把上次记的抹掉)。别的动作带 `result` 400——要改结果走 edit。
|
|
258063
258308
|
*/
|
|
258064
|
-
async setStatus(caller, id, requested, reason) {
|
|
258309
|
+
async setStatus(caller, id, requested, reason, resultIn) {
|
|
258065
258310
|
const before = await this.getForChange(caller, id);
|
|
258066
258311
|
const why = clean2(reason);
|
|
258067
258312
|
if (why && why.length > REASON_MAX) throw new ApiError(400, "TODO_INVALID", `reason \u4E0D\u80FD\u8D85\u8FC7 ${REASON_MAX} \u5B57`);
|
|
258313
|
+
const result = clean2(resultIn);
|
|
258314
|
+
if (result && requested !== "done") throw new ApiError(400, "TODO_INVALID", "result \u53EA\u5728\u6807\u5B8C\u6210\u65F6\u5E26\uFF1B\u8981\u6539\u7ED3\u679C\u5728\u54EA\u7528 oasis todo edit --result");
|
|
258315
|
+
if (result && result.length > RESULT_MAX) throw new ApiError(400, "TODO_INVALID", `result \u4E0D\u80FD\u8D85\u8FC7 ${RESULT_MAX} \u5B57`);
|
|
258068
258316
|
const unsent = isTodoUnsent(before);
|
|
258069
258317
|
if (unsent && requested === "done") throw new ApiError(400, "TODO_NOT_SENT", "\u8FD9\u6761\u8FD8\u662F\u8349\u6848\uFF08\u6CA1\u53D1\u51FA\uFF09\uFF0C\u4E0D\u80FD\u6807\u5B8C\u6210\uFF1A\u5148\u5728\u8349\u6848\u5361\u4E0A\u70B9\u300C\u53D1\u51FA\u300D\uFF0C\u6216\u53D6\u6D88\u5B83\u3002");
|
|
258070
258318
|
if (before.status === "draft" && requested === "open") throw new ApiError(400, "TODO_NOT_SENT", "\u8FD9\u6761\u662F\u8349\u6848\uFF1A\u8981\u751F\u6548\u8BF7\u53D1\u8D77\u4EBA\u5728\u8349\u6848\u5361\u4E0A\u70B9\u300C\u53D1\u51FA\u300D\u3002");
|
|
258071
258319
|
const status = unsent && requested === "open" ? "draft" : requested;
|
|
258320
|
+
if (before.status === status && status === "done" && result && result !== before.result) return this.edit(caller, id, { result });
|
|
258072
258321
|
if (before.status === status) return this.respond(before);
|
|
258073
258322
|
if (status === "cancelled" && !why && isTodoAssignedToByOther(before, caller.principal)) {
|
|
258074
258323
|
throw new ApiError(400, "TODO_REASON_REQUIRED", "\u8FD9\u6761\u662F\u522B\u4EBA\u6D3E\u7ED9\u4F60\u7684\uFF1A\u53D6\u6D88\u8981\u5199\u539F\u56E0\uFF08--reason\uFF09\uFF0C\u53D1\u8D77\u4EBA\u4F1A\u6536\u5230\u901A\u77E5\u3002");
|
|
@@ -258080,7 +258329,12 @@ var init_service10 = __esm({
|
|
|
258080
258329
|
if (status === "done") next.doneAt = at2;
|
|
258081
258330
|
if (status === "cancelled") next.cancelledAt = at2;
|
|
258082
258331
|
const change = this.change(id, caller, at2, "status", before.status, status, why);
|
|
258083
|
-
const
|
|
258332
|
+
const changes = [change];
|
|
258333
|
+
if (result && result !== before.result) {
|
|
258334
|
+
next.result = result;
|
|
258335
|
+
changes.push(this.change(id, caller, at2, "result", before.result, result));
|
|
258336
|
+
}
|
|
258337
|
+
const out = await this.save(caller, before, next, changes);
|
|
258084
258338
|
const kind = status === "done" ? "todo-done" : status === "cancelled" ? "todo-cancelled" : "todo-reopened";
|
|
258085
258339
|
await this.notice(
|
|
258086
258340
|
out.todo,
|
|
@@ -258088,7 +258342,7 @@ var init_service10 = __esm({
|
|
|
258088
258342
|
this.counterparts(out.todo, caller),
|
|
258089
258343
|
kind,
|
|
258090
258344
|
todoChangeSourceKey(id, change.id),
|
|
258091
|
-
statusTitle(await this.nameOf(caller.principal), out.todo, kind, why),
|
|
258345
|
+
statusTitle(await this.nameOf(caller.principal), out.todo, kind, why, status === "done" ? result : void 0),
|
|
258092
258346
|
at2
|
|
258093
258347
|
);
|
|
258094
258348
|
return out;
|
|
@@ -258239,7 +258493,7 @@ function todosDomain(options) {
|
|
|
258239
258493
|
}));
|
|
258240
258494
|
const status = (path50, to) => router.post(`/api/todos/:id/${path50}`, wrap(async (req, service, caller) => {
|
|
258241
258495
|
const body2 = statusBody.parse(req.body ?? {});
|
|
258242
|
-
return { status: 200, body: await service.setStatus(caller, req.params.id, to, body2.reason) };
|
|
258496
|
+
return { status: 200, body: await service.setStatus(caller, req.params.id, to, body2.reason, body2.result) };
|
|
258243
258497
|
}));
|
|
258244
258498
|
status("done", "done");
|
|
258245
258499
|
status("cancel", "cancelled");
|
|
@@ -258271,9 +258525,10 @@ var init_routes11 = __esm({
|
|
|
258271
258525
|
startTime: external_exports.string().nullable().optional(),
|
|
258272
258526
|
linkedWorkorderId: external_exports.string().nullable().optional(),
|
|
258273
258527
|
assignee: external_exports.string().optional(),
|
|
258528
|
+
result: external_exports.string().nullable().optional(),
|
|
258274
258529
|
reason: external_exports.string().optional()
|
|
258275
258530
|
}).strict();
|
|
258276
|
-
statusBody = external_exports.object({ reason: external_exports.string().optional() }).strict();
|
|
258531
|
+
statusBody = external_exports.object({ reason: external_exports.string().optional(), result: external_exports.string().optional() }).strict();
|
|
258277
258532
|
}
|
|
258278
258533
|
});
|
|
258279
258534
|
|
|
@@ -275189,6 +275444,19 @@ var init_postgres_delegations = __esm({
|
|
|
275189
275444
|
);
|
|
275190
275445
|
return r5.rows.map(toRecord2);
|
|
275191
275446
|
}
|
|
275447
|
+
/**
|
|
275448
|
+
* 防重叠比对的委派池(ADR 0640 第二批):进行中与已交回的,失败的不给;任务书摘要取发起那次的流水(`kind='created'`)。
|
|
275449
|
+
* 只给服务端内部的比对服务用——委派列表接口不放开。
|
|
275450
|
+
*/
|
|
275451
|
+
async listForOverlap() {
|
|
275452
|
+
const r5 = await this.pool.query(
|
|
275453
|
+
`SELECT d.*, t.text_digest AS created_text FROM ${this.s}.chat_session_delegations d
|
|
275454
|
+
LEFT JOIN ${this.s}.chat_session_delegation_touches t ON t.delegation_id = d.id AND t.kind = 'created'
|
|
275455
|
+
WHERE d.state IN ('running', 'done')
|
|
275456
|
+
ORDER BY d.created_at DESC, d.id`
|
|
275457
|
+
);
|
|
275458
|
+
return r5.rows.map((row) => delegationOverlapRowOf(toRecord2(row), row.created_text));
|
|
275459
|
+
}
|
|
275192
275460
|
async patch(id, patch) {
|
|
275193
275461
|
const sets = [];
|
|
275194
275462
|
const vals = [];
|
|
@@ -305968,11 +306236,11 @@ var require_dist_cjs9 = __commonJS({
|
|
|
305968
306236
|
throw new TokenProviderError2(`Value not present for '${key2}' in SSO Token${forRefresh ? ". Cannot refresh" : ""}. ${REFRESH_MESSAGE}`, false);
|
|
305969
306237
|
}
|
|
305970
306238
|
};
|
|
305971
|
-
var { writeFile:
|
|
306239
|
+
var { writeFile: writeFile14 } = promises5;
|
|
305972
306240
|
var writeSSOTokenToFile = (id, ssoToken) => {
|
|
305973
306241
|
const tokenFilepath = getSSOTokenFilepath2(id);
|
|
305974
306242
|
const tokenString = JSON.stringify(ssoToken, null, 2);
|
|
305975
|
-
return
|
|
306243
|
+
return writeFile14(tokenFilepath, tokenString);
|
|
305976
306244
|
};
|
|
305977
306245
|
var lastRefreshAttemptTimes = /* @__PURE__ */ new Map();
|
|
305978
306246
|
var fromSso = (init = {}) => async ({ callerClientConfig } = {}) => {
|
|
@@ -309075,7 +309343,7 @@ var require_dist_cjs11 = __commonJS({
|
|
|
309075
309343
|
var { createHash: createHash56, createPrivateKey: createPrivateKey2, createPublicKey, sign: sign6 } = require("node:crypto");
|
|
309076
309344
|
var { promises: promises5 } = require("node:fs");
|
|
309077
309345
|
var { homedir: homedir14 } = require("node:os");
|
|
309078
|
-
var { dirname:
|
|
309346
|
+
var { dirname: dirname42, join: join54 } = require("node:path");
|
|
309079
309347
|
var LoginCredentialsFetcher = class _LoginCredentialsFetcher {
|
|
309080
309348
|
profileData;
|
|
309081
309349
|
init;
|
|
@@ -309231,7 +309499,7 @@ var require_dist_cjs11 = __commonJS({
|
|
|
309231
309499
|
}
|
|
309232
309500
|
async saveToken(token2) {
|
|
309233
309501
|
const tokenFilePath = this.getTokenFilePath();
|
|
309234
|
-
const directory =
|
|
309502
|
+
const directory = dirname42(tokenFilePath);
|
|
309235
309503
|
try {
|
|
309236
309504
|
await promises5.mkdir(directory, { recursive: true });
|
|
309237
309505
|
} catch (error3) {
|
|
@@ -323812,14 +324080,14 @@ init_src();
|
|
|
323812
324080
|
var os16 = __toESM(require("node:os"));
|
|
323813
324081
|
var path49 = __toESM(require("node:path"));
|
|
323814
324082
|
var import_node_child_process23 = require("node:child_process");
|
|
323815
|
-
var
|
|
324083
|
+
var import_node_crypto112 = require("node:crypto");
|
|
323816
324084
|
|
|
323817
324085
|
// ../cli/src/cli.ts
|
|
323818
324086
|
init_src();
|
|
323819
324087
|
var fs48 = __toESM(require("node:fs"), 1);
|
|
323820
324088
|
var os13 = __toESM(require("node:os"), 1);
|
|
323821
324089
|
var path42 = __toESM(require("node:path"), 1);
|
|
323822
|
-
var
|
|
324090
|
+
var import_node_crypto110 = require("node:crypto");
|
|
323823
324091
|
|
|
323824
324092
|
// ../cli/src/serve.ts
|
|
323825
324093
|
init_src11();
|
|
@@ -323833,7 +324101,7 @@ var fs40 = __toESM(require("node:fs"), 1);
|
|
|
323833
324101
|
var os9 = __toESM(require("node:os"), 1);
|
|
323834
324102
|
var path32 = __toESM(require("node:path"), 1);
|
|
323835
324103
|
var import_node_child_process15 = require("node:child_process");
|
|
323836
|
-
var
|
|
324104
|
+
var import_node_crypto104 = require("node:crypto");
|
|
323837
324105
|
var import_node_url7 = require("node:url");
|
|
323838
324106
|
|
|
323839
324107
|
// ../cli/src/artifact-discovery-source.ts
|
|
@@ -325963,6 +326231,289 @@ function createTodoRuntime(options) {
|
|
|
325963
326231
|
};
|
|
325964
326232
|
}
|
|
325965
326233
|
|
|
326234
|
+
// ../cli/src/overlap-wiring.ts
|
|
326235
|
+
init_src();
|
|
326236
|
+
init_workorders();
|
|
326237
|
+
|
|
326238
|
+
// ../server/src/domains/overlap/service.ts
|
|
326239
|
+
var import_node_crypto101 = require("node:crypto");
|
|
326240
|
+
init_src();
|
|
326241
|
+
var QUERY_MAX = 4e3;
|
|
326242
|
+
var WORKORDER_ACTIVE = /* @__PURE__ */ new Set(["awaiting_dispatch", "not_started", "executing", "pending", "blocked", "held"]);
|
|
326243
|
+
var OverlapService = class {
|
|
326244
|
+
constructor(deps) {
|
|
326245
|
+
this.deps = deps;
|
|
326246
|
+
}
|
|
326247
|
+
warn(error3) {
|
|
326248
|
+
this.deps.warn?.(error3);
|
|
326249
|
+
}
|
|
326250
|
+
async safe(what, run) {
|
|
326251
|
+
if (!run) return void 0;
|
|
326252
|
+
try {
|
|
326253
|
+
return await run();
|
|
326254
|
+
} catch (error3) {
|
|
326255
|
+
this.warn(new Error(`\u6BD4\u5BF9\u6C60\u300C${what}\u300D\u8BFB\u4E0D\u51FA\u6765\uFF0C\u8FD9\u4E00\u7C7B\u5148\u4E0D\u6BD4\uFF1A${String(error3)}`));
|
|
326256
|
+
return void 0;
|
|
326257
|
+
}
|
|
326258
|
+
}
|
|
326259
|
+
async check(companyId, caller, input) {
|
|
326260
|
+
if (!this.deps.enabled()) return { enabled: false, active: [], done: [] };
|
|
326261
|
+
const config2 = this.deps.config();
|
|
326262
|
+
const query = overlapTokens(input.text.slice(0, QUERY_MAX));
|
|
326263
|
+
const timeZone = await this.deps.timeZone?.(companyId).catch(() => void 0);
|
|
326264
|
+
const tz = timeZone ? { timeZone } : {};
|
|
326265
|
+
if (query.size === 0) return { enabled: true, active: [], done: [], ...tz };
|
|
326266
|
+
const sources = this.deps.sources(companyId);
|
|
326267
|
+
const subject = input.subjectId?.trim();
|
|
326268
|
+
const session = input.chatSessionId?.trim();
|
|
326269
|
+
const pool = [];
|
|
326270
|
+
const keep = (score) => score >= config2.minScore;
|
|
326271
|
+
for (const t of await this.safe("\u5F85\u529E", sources.todos) ?? []) {
|
|
326272
|
+
if (t.status !== "open" && t.status !== "done") continue;
|
|
326273
|
+
if (t.creatorActorId !== t.assigneeActorId && !t.sentAt) continue;
|
|
326274
|
+
if (subject && t.id === subject) continue;
|
|
326275
|
+
const score = overlapScore(query, t.title, [t.note, t.result].filter(Boolean).join("\n"));
|
|
326276
|
+
if (!keep(score)) continue;
|
|
326277
|
+
const c5 = {
|
|
326278
|
+
kind: "todo",
|
|
326279
|
+
phase: t.status === "open" ? "active" : "done",
|
|
326280
|
+
score,
|
|
326281
|
+
title: t.title,
|
|
326282
|
+
todoId: t.id,
|
|
326283
|
+
creatorActorId: t.creatorActorId,
|
|
326284
|
+
assigneeActorId: t.assigneeActorId,
|
|
326285
|
+
...t.sourceChatSessionId ? { sourceChatSessionId: t.sourceChatSessionId } : {},
|
|
326286
|
+
...t.status === "open" ? { dueDate: t.dueDate } : {},
|
|
326287
|
+
...t.status === "done" && t.doneAt ? { doneAt: t.doneAt } : {},
|
|
326288
|
+
...t.status === "done" && t.result ? { result: t.result } : {}
|
|
326289
|
+
};
|
|
326290
|
+
pool.push({ candidate: c5, updatedAt: t.updatedAt });
|
|
326291
|
+
}
|
|
326292
|
+
for (const w2 of await this.safe("\u5DE5\u5355", sources.workorders) ?? []) {
|
|
326293
|
+
if (subject && w2.id === subject) continue;
|
|
326294
|
+
const delivered = w2.progressExcludingBrief?.concluded ?? 0;
|
|
326295
|
+
const phase = WORKORDER_ACTIVE.has(w2.stage) ? "active" : w2.stage === "concluded" && delivered > 0 ? "done" : void 0;
|
|
326296
|
+
if (!phase) continue;
|
|
326297
|
+
const score = overlapScore(query, w2.title, [w2.goal, w2.description].filter(Boolean).join("\n"));
|
|
326298
|
+
if (!keep(score)) continue;
|
|
326299
|
+
const c5 = {
|
|
326300
|
+
kind: "workorder",
|
|
326301
|
+
phase,
|
|
326302
|
+
score,
|
|
326303
|
+
title: w2.title,
|
|
326304
|
+
workorderId: w2.id,
|
|
326305
|
+
...w2.owner?.id ? { initiatorActorId: w2.owner.id } : {},
|
|
326306
|
+
...w2.owner?.name ? { initiatorName: w2.owner.name } : {},
|
|
326307
|
+
// 引擎没有单独的「结束时间」:已结束的工单取最后一次变动时刻(结束后不会再动)。
|
|
326308
|
+
...phase === "done" && w2.updatedAt ? { endedAt: w2.updatedAt } : {},
|
|
326309
|
+
...phase === "done" ? { deliverableCount: delivered } : {}
|
|
326310
|
+
};
|
|
326311
|
+
pool.push({ candidate: c5, updatedAt: w2.updatedAt });
|
|
326312
|
+
}
|
|
326313
|
+
for (const d5 of await this.safe("\u59D4\u6D3E", sources.delegations) ?? []) {
|
|
326314
|
+
if (subject && d5.id === subject) continue;
|
|
326315
|
+
if (session && d5.parentSessionId === session) continue;
|
|
326316
|
+
if (d5.state === "done" && d5.artifactCount === 0) continue;
|
|
326317
|
+
const title = d5.taskDigest || d5.taskText.slice(0, 60);
|
|
326318
|
+
const score = overlapScore(query, title, [d5.taskText, d5.label].filter(Boolean).join("\n"));
|
|
326319
|
+
if (!keep(score)) continue;
|
|
326320
|
+
const c5 = {
|
|
326321
|
+
kind: "delegation",
|
|
326322
|
+
phase: d5.state === "running" ? "active" : "done",
|
|
326323
|
+
score,
|
|
326324
|
+
title,
|
|
326325
|
+
delegationId: d5.id,
|
|
326326
|
+
childSessionId: d5.childSessionId,
|
|
326327
|
+
parentSessionId: d5.parentSessionId,
|
|
326328
|
+
expertActorId: d5.expertActorId,
|
|
326329
|
+
artifactCount: d5.artifactCount,
|
|
326330
|
+
...d5.state === "done" && d5.settledAt ? { settledAt: d5.settledAt } : {}
|
|
326331
|
+
};
|
|
326332
|
+
pool.push({ candidate: c5, updatedAt: d5.settledAt ?? d5.createdAt });
|
|
326333
|
+
}
|
|
326334
|
+
const rank = (a5, b6) => b6.candidate.score - a5.candidate.score || (a5.updatedAt < b6.updatedAt ? 1 : a5.updatedAt > b6.updatedAt ? -1 : 0);
|
|
326335
|
+
const active = pool.filter((s3) => s3.candidate.phase === "active").sort(rank).slice(0, config2.maxActive).map((s3) => s3.candidate);
|
|
326336
|
+
const done = pool.filter((s3) => s3.candidate.phase === "done").sort(rank).slice(0, config2.maxDone).map((s3) => s3.candidate);
|
|
326337
|
+
const picked = [...active, ...done];
|
|
326338
|
+
if (picked.length > 0) {
|
|
326339
|
+
await this.fillPeople(sources, picked);
|
|
326340
|
+
await this.record(companyId, caller, input, picked, config2.minScore);
|
|
326341
|
+
}
|
|
326342
|
+
return { enabled: true, active, done, ...tz };
|
|
326343
|
+
}
|
|
326344
|
+
/** 只给挑出来的那几条补人名与派活人(池子可能上百条,不为它们逐条查)。 */
|
|
326345
|
+
async fillPeople(sources, picked) {
|
|
326346
|
+
const delegations = picked.filter((c5) => c5.kind === "delegation");
|
|
326347
|
+
const delegators = delegations.length ? await this.safe("\u6D3E\u6D3B\u4EBA", sources.delegators ? () => sources.delegators(delegations.map((d5) => d5.parentSessionId)) : void 0) ?? {} : {};
|
|
326348
|
+
for (const d5 of delegations) {
|
|
326349
|
+
const who2 = delegators[d5.parentSessionId];
|
|
326350
|
+
if (who2) d5.delegatorActorId = who2;
|
|
326351
|
+
}
|
|
326352
|
+
const ids2 = /* @__PURE__ */ new Set();
|
|
326353
|
+
for (const c5 of picked) {
|
|
326354
|
+
if (c5.kind === "todo") {
|
|
326355
|
+
ids2.add(c5.creatorActorId);
|
|
326356
|
+
ids2.add(c5.assigneeActorId);
|
|
326357
|
+
} else if (c5.kind === "workorder") {
|
|
326358
|
+
if (c5.initiatorActorId && !c5.initiatorName) ids2.add(c5.initiatorActorId);
|
|
326359
|
+
} else {
|
|
326360
|
+
ids2.add(c5.expertActorId);
|
|
326361
|
+
if (c5.delegatorActorId) ids2.add(c5.delegatorActorId);
|
|
326362
|
+
}
|
|
326363
|
+
}
|
|
326364
|
+
const names = await this.safe("\u663E\u793A\u540D", sources.names ? () => sources.names([...ids2]) : void 0) ?? {};
|
|
326365
|
+
for (const c5 of picked) {
|
|
326366
|
+
if (c5.kind === "todo") {
|
|
326367
|
+
if (names[c5.creatorActorId]) c5.creatorName = names[c5.creatorActorId];
|
|
326368
|
+
if (names[c5.assigneeActorId]) c5.assigneeName = names[c5.assigneeActorId];
|
|
326369
|
+
} else if (c5.kind === "workorder") {
|
|
326370
|
+
if (!c5.initiatorName && c5.initiatorActorId && names[c5.initiatorActorId]) c5.initiatorName = names[c5.initiatorActorId];
|
|
326371
|
+
} else {
|
|
326372
|
+
if (names[c5.expertActorId]) c5.expertName = names[c5.expertActorId];
|
|
326373
|
+
if (c5.delegatorActorId && names[c5.delegatorActorId]) c5.delegatorName = names[c5.delegatorActorId];
|
|
326374
|
+
}
|
|
326375
|
+
}
|
|
326376
|
+
}
|
|
326377
|
+
async record(companyId, caller, input, picked, minScore) {
|
|
326378
|
+
if (!this.deps.events) return;
|
|
326379
|
+
const event = {
|
|
326380
|
+
id: `ovl_${(0, import_node_crypto101.randomUUID)()}`,
|
|
326381
|
+
at: new Date(this.deps.now?.() ?? Date.now()).toISOString(),
|
|
326382
|
+
principalActorId: caller.principal,
|
|
326383
|
+
actorId: caller.actor,
|
|
326384
|
+
action: input.action,
|
|
326385
|
+
...input.subjectId?.trim() ? { subjectId: input.subjectId.trim() } : {},
|
|
326386
|
+
...input.chatSessionId?.trim() ? { chatSessionId: input.chatSessionId.trim() } : {},
|
|
326387
|
+
candidates: picked.map((c5) => ({ kind: c5.kind, phase: c5.phase, id: overlapCandidateId(c5), score: c5.score })),
|
|
326388
|
+
minScore
|
|
326389
|
+
};
|
|
326390
|
+
try {
|
|
326391
|
+
await (await this.deps.events(companyId)).append(event);
|
|
326392
|
+
} catch (error3) {
|
|
326393
|
+
this.warn(new Error(`\u6BD4\u5BF9\u4E8B\u4EF6\u6CA1\u8BB0\u4E0A\uFF08\u5019\u9009\u7167\u5E38\u8FD4\u56DE\uFF09\uFF1A${String(error3)}`));
|
|
326394
|
+
}
|
|
326395
|
+
}
|
|
326396
|
+
async recentEvents(companyId, limit) {
|
|
326397
|
+
if (!this.deps.events) return [];
|
|
326398
|
+
return (await this.deps.events(companyId)).listRecent(limit);
|
|
326399
|
+
}
|
|
326400
|
+
};
|
|
326401
|
+
|
|
326402
|
+
// ../server/src/domains/overlap/routes.ts
|
|
326403
|
+
init_zod();
|
|
326404
|
+
init_src();
|
|
326405
|
+
init_router();
|
|
326406
|
+
var checkBody = external_exports.object({
|
|
326407
|
+
action: external_exports.enum([...OVERLAP_ACTIONS]),
|
|
326408
|
+
text: external_exports.string().max(2e4),
|
|
326409
|
+
subjectId: external_exports.string().max(200).optional(),
|
|
326410
|
+
chatSessionId: external_exports.string().max(200).optional()
|
|
326411
|
+
}).strict();
|
|
326412
|
+
function overlapDomain(options) {
|
|
326413
|
+
const wrap = (fn) => async (req) => {
|
|
326414
|
+
try {
|
|
326415
|
+
const companyId = req.auth.companyId ?? options.defaultCompanyId();
|
|
326416
|
+
return await fn(req, companyId, await options.resolveCaller(req.auth.actor, req.auth.companyId));
|
|
326417
|
+
} catch (e5) {
|
|
326418
|
+
if (e5 instanceof ZodError) throw new ApiError(400, "OVERLAP_INVALID", e5.issues.map((i5) => `${i5.path.join(".")}: ${i5.message}`).join("; "));
|
|
326419
|
+
throw e5;
|
|
326420
|
+
}
|
|
326421
|
+
};
|
|
326422
|
+
return (router) => {
|
|
326423
|
+
router.post("/api/overlap/candidates", wrap(async (req, companyId, caller) => {
|
|
326424
|
+
const body2 = checkBody.parse(req.body ?? {});
|
|
326425
|
+
const chatSessionId = req.auth.dispatch?.chatSessionId ?? body2.chatSessionId;
|
|
326426
|
+
return {
|
|
326427
|
+
status: 200,
|
|
326428
|
+
body: await options.service.check(companyId, caller, {
|
|
326429
|
+
action: body2.action,
|
|
326430
|
+
text: body2.text,
|
|
326431
|
+
...body2.subjectId ? { subjectId: body2.subjectId } : {},
|
|
326432
|
+
...chatSessionId ? { chatSessionId } : {}
|
|
326433
|
+
})
|
|
326434
|
+
};
|
|
326435
|
+
}));
|
|
326436
|
+
router.get("/api/overlap/events", wrap(async (req, companyId) => {
|
|
326437
|
+
const raw = Number(req.query.get("limit") ?? 50);
|
|
326438
|
+
const limit = Number.isInteger(raw) && raw > 0 ? Math.min(raw, 500) : 50;
|
|
326439
|
+
return { status: 200, body: { items: await options.service.recentEvents(companyId, limit) } };
|
|
326440
|
+
}));
|
|
326441
|
+
};
|
|
326442
|
+
}
|
|
326443
|
+
|
|
326444
|
+
// ../server/src/domains/overlap/flag.ts
|
|
326445
|
+
function overlapCheckEnabledFromEnv(env2 = process.env) {
|
|
326446
|
+
const raw = (env2["OASIS_OVERLAP_CHECK"] ?? "").trim().toLowerCase();
|
|
326447
|
+
return !(raw === "off" || raw === "0" || raw === "false");
|
|
326448
|
+
}
|
|
326449
|
+
var OVERLAP_DEFAULTS = { maxActive: 5, maxDone: 3, minScore: 0.3 };
|
|
326450
|
+
function intIn(raw, fallback2, max) {
|
|
326451
|
+
if (raw === void 0 || raw.trim() === "") return fallback2;
|
|
326452
|
+
const n3 = Number(raw);
|
|
326453
|
+
return Number.isInteger(n3) && n3 >= 0 && n3 <= max ? n3 : fallback2;
|
|
326454
|
+
}
|
|
326455
|
+
function scoreIn(raw, fallback2) {
|
|
326456
|
+
if (raw === void 0 || raw.trim() === "") return fallback2;
|
|
326457
|
+
const n3 = Number(raw);
|
|
326458
|
+
return Number.isFinite(n3) && n3 > 0 && n3 <= 1 ? n3 : fallback2;
|
|
326459
|
+
}
|
|
326460
|
+
function overlapConfigFromEnv(env2 = process.env) {
|
|
326461
|
+
return {
|
|
326462
|
+
maxActive: intIn(env2["OASIS_OVERLAP_MAX_ACTIVE"], OVERLAP_DEFAULTS.maxActive, 50),
|
|
326463
|
+
maxDone: intIn(env2["OASIS_OVERLAP_MAX_DONE"], OVERLAP_DEFAULTS.maxDone, 50),
|
|
326464
|
+
minScore: scoreIn(env2["OASIS_OVERLAP_MIN_SCORE"], OVERLAP_DEFAULTS.minScore)
|
|
326465
|
+
};
|
|
326466
|
+
}
|
|
326467
|
+
|
|
326468
|
+
// ../cli/src/overlap-wiring.ts
|
|
326469
|
+
var TODO_POOL_MAX = 5e3;
|
|
326470
|
+
function createOverlapRuntime(options) {
|
|
326471
|
+
const sources = (companyId) => ({
|
|
326472
|
+
todos: async () => (await options.todos(companyId)).search({
|
|
326473
|
+
statuses: ["open", "done"],
|
|
326474
|
+
// viewer 不是任何人:从没发出过的草案一条都不进池子(草案只有发起人看得到,也不该被比出来)。
|
|
326475
|
+
viewer: "actor:system:overlap",
|
|
326476
|
+
limit: TODO_POOL_MAX
|
|
326477
|
+
}),
|
|
326478
|
+
workorders: async () => buildWorkorderSummaries(await options.workorderModel(companyId)),
|
|
326479
|
+
delegations: async () => await (await options.delegations(companyId)).listForOverlap?.() ?? [],
|
|
326480
|
+
names: async (ids2) => {
|
|
326481
|
+
const out = {};
|
|
326482
|
+
const people = await options.people(companyId).catch(() => []);
|
|
326483
|
+
for (const p4 of people) if (ids2.includes(p4.actorId)) out[p4.actorId] = p4.name;
|
|
326484
|
+
for (const id of ids2) {
|
|
326485
|
+
if (out[id] || isHumanActorId(id)) continue;
|
|
326486
|
+
const name = await options.actorName(companyId, id).catch(() => void 0);
|
|
326487
|
+
if (name) out[id] = name;
|
|
326488
|
+
}
|
|
326489
|
+
return out;
|
|
326490
|
+
},
|
|
326491
|
+
delegators: async (sessionIds) => {
|
|
326492
|
+
const out = {};
|
|
326493
|
+
for (const id of new Set(sessionIds)) {
|
|
326494
|
+
const human = await options.sessionHuman(companyId, id).catch(() => void 0);
|
|
326495
|
+
if (human) out[id] = human;
|
|
326496
|
+
}
|
|
326497
|
+
return out;
|
|
326498
|
+
}
|
|
326499
|
+
});
|
|
326500
|
+
const service = new OverlapService({
|
|
326501
|
+
sources,
|
|
326502
|
+
events: options.events,
|
|
326503
|
+
config: () => overlapConfigFromEnv(),
|
|
326504
|
+
enabled: options.enabled ?? (() => overlapCheckEnabledFromEnv()),
|
|
326505
|
+
timeZone: options.timeZone,
|
|
326506
|
+
warn: options.warn
|
|
326507
|
+
});
|
|
326508
|
+
const resolveCaller = async (actorId, companyId) => {
|
|
326509
|
+
if (isHumanActorId(actorId)) return { principal: actorId, actor: actorId };
|
|
326510
|
+
const human = await options.boundHuman(actorId, companyId ?? options.defaultCompanyId()).catch(() => null);
|
|
326511
|
+
return { principal: human ?? actorId, actor: actorId };
|
|
326512
|
+
};
|
|
326513
|
+
const register = overlapDomain({ service, resolveCaller, defaultCompanyId: options.defaultCompanyId });
|
|
326514
|
+
return { service, register, resolveCaller };
|
|
326515
|
+
}
|
|
326516
|
+
|
|
325966
326517
|
// ../cli/src/connector-renewal-wiring.ts
|
|
325967
326518
|
init_src();
|
|
325968
326519
|
init_src3();
|
|
@@ -326004,7 +326555,7 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326004
326555
|
const deliverInvalidNotice = async (companyId, store, actorId, marker) => {
|
|
326005
326556
|
const prev = marker.notice ?? { inApp: false, dm: "pending", attempts: 0 };
|
|
326006
326557
|
const state2 = { ...prev, attempts: prev.attempts + 1 };
|
|
326007
|
-
const
|
|
326558
|
+
const who2 = `actor=${actorId ?? "-"} \u7B2C ${state2.attempts}/${MAX_NOTICE_ATTEMPTS} \u6B21`;
|
|
326008
326559
|
const name = await agentName(companyId, actorId);
|
|
326009
326560
|
const { recipients, authorizer } = await recipientsFor(companyId, store, actorId);
|
|
326010
326561
|
const unverified = !authorizer && !await store.revealVariable(FEISHU_USER_OPEN_ID_VAR, actorId).catch(() => "?");
|
|
@@ -326029,7 +326580,7 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326029
326580
|
options.onNotifications?.(companyId, rows);
|
|
326030
326581
|
state2.inApp = true;
|
|
326031
326582
|
} catch (err) {
|
|
326032
|
-
options.warn(new Error(`\u98DE\u4E66\u6388\u6743\u5931\u6548\u7AD9\u5185\u901A\u77E5\u672A\u5199\u5165\uFF08${
|
|
326583
|
+
options.warn(new Error(`\u98DE\u4E66\u6388\u6743\u5931\u6548\u7AD9\u5185\u901A\u77E5\u672A\u5199\u5165\uFF08${who2}\uFF0C\u4E0B\u4E00\u62CD\u91CD\u8BD5\uFF09: ${String(err)}`));
|
|
326033
326584
|
}
|
|
326034
326585
|
}
|
|
326035
326586
|
if (state2.dm === "pending") {
|
|
@@ -326054,7 +326605,7 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326054
326605
|
state2.dm = "sent";
|
|
326055
326606
|
}
|
|
326056
326607
|
} catch (err) {
|
|
326057
|
-
options.warn(new Error(`\u98DE\u4E66\u6388\u6743\u5931\u6548\u79C1\u4FE1\u53D1\u9001\u5931\u8D25\uFF08${
|
|
326608
|
+
options.warn(new Error(`\u98DE\u4E66\u6388\u6743\u5931\u6548\u79C1\u4FE1\u53D1\u9001\u5931\u8D25\uFF08${who2}\uFF0C\u4E0B\u4E00\u62CD\u91CD\u8BD5\uFF09: ${String(err)}`));
|
|
326058
326609
|
}
|
|
326059
326610
|
}
|
|
326060
326611
|
if ((!state2.inApp || state2.dm === "pending") && state2.attempts >= MAX_NOTICE_ATTEMPTS) {
|
|
@@ -326107,7 +326658,7 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326107
326658
|
const deliverApprovalNotice = async (companyId, store, actorId, pending, app) => {
|
|
326108
326659
|
const prev = pending.notice ?? { inApp: false, dm: "pending", attempts: 0 };
|
|
326109
326660
|
const state2 = { ...prev, attempts: prev.attempts + 1 };
|
|
326110
|
-
const
|
|
326661
|
+
const who2 = `actor=${actorId ?? "-"} \u7B2C ${state2.attempts}/${MAX_NOTICE_ATTEMPTS} \u6B21`;
|
|
326111
326662
|
const name = await agentName(companyId, actorId);
|
|
326112
326663
|
const modules = feishuPendingApprovalModules(pending);
|
|
326113
326664
|
if (!state2.inApp) {
|
|
@@ -326132,7 +326683,7 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326132
326683
|
options.onNotifications?.(companyId, rows);
|
|
326133
326684
|
state2.inApp = true;
|
|
326134
326685
|
} catch (err) {
|
|
326135
|
-
options.warn(new Error(`\u98DE\u4E66\u6743\u9650\u6279\u51C6\u7AD9\u5185\u901A\u77E5\u672A\u5199\u5165\uFF08${
|
|
326686
|
+
options.warn(new Error(`\u98DE\u4E66\u6743\u9650\u6279\u51C6\u7AD9\u5185\u901A\u77E5\u672A\u5199\u5165\uFF08${who2}\uFF0C\u4E0B\u4E00\u62CD\u91CD\u8BD5\uFF09: ${String(err)}`));
|
|
326136
326687
|
}
|
|
326137
326688
|
}
|
|
326138
326689
|
if (state2.dm === "pending") {
|
|
@@ -326154,7 +326705,7 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326154
326705
|
state2.dm = "sent";
|
|
326155
326706
|
}
|
|
326156
326707
|
} catch (err) {
|
|
326157
|
-
options.warn(new Error(`\u98DE\u4E66\u6743\u9650\u6279\u51C6\u79C1\u4FE1\u53D1\u9001\u5931\u8D25\uFF08${
|
|
326708
|
+
options.warn(new Error(`\u98DE\u4E66\u6743\u9650\u6279\u51C6\u79C1\u4FE1\u53D1\u9001\u5931\u8D25\uFF08${who2}\uFF0C\u4E0B\u4E00\u62CD\u91CD\u8BD5\uFF09: ${String(err)}`));
|
|
326158
326709
|
}
|
|
326159
326710
|
}
|
|
326160
326711
|
if ((!state2.inApp || state2.dm === "pending") && state2.attempts >= MAX_NOTICE_ATTEMPTS) {
|
|
@@ -326218,11 +326769,11 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326218
326769
|
if (await store.revealVariable(FEISHU_USER_OPEN_ID_VAR, e5.actorId)) return;
|
|
326219
326770
|
const accessToken = e5.outcome.credentials?.["user_access_token"];
|
|
326220
326771
|
if (!accessToken) return;
|
|
326221
|
-
const
|
|
326222
|
-
if (!
|
|
326772
|
+
const who2 = await fetchFeishuUserIdentity(accessToken);
|
|
326773
|
+
if (!who2.openId) return;
|
|
326223
326774
|
await store.putVariable({
|
|
326224
326775
|
key: FEISHU_USER_OPEN_ID_VAR,
|
|
326225
|
-
value:
|
|
326776
|
+
value: who2.openId,
|
|
326226
326777
|
...e5.actorId ? { scope: "personal", actorId: e5.actorId } : { scope: "global" },
|
|
326227
326778
|
connectorId: "feishu",
|
|
326228
326779
|
encrypted: false
|
|
@@ -326272,14 +326823,14 @@ function createConnectorRenewalRuntime(options) {
|
|
|
326272
326823
|
const name = await agentName(claims.companyId, claims.actorId);
|
|
326273
326824
|
await notifyFeishuUser(store, claims.actorId, claims.purpose === "supplement" ? `\u300C${name}\u300D\u7684\u98DE\u4E66\u6743\u9650\u5DF2\u8865\u4E0A\uFF0C\u7BA1\u7406\u5458\u6279\u51C6\u7684\u529F\u80FD\u73B0\u5728\u53EF\u4EE5\u4F7F\u7528\u4E86\u3002` : `\u300C${name}\u300D\u7684\u98DE\u4E66\u7528\u6237\u6388\u6743\u5DF2\u6062\u590D\u3002`).catch(() => void 0);
|
|
326274
326825
|
},
|
|
326275
|
-
onRejected: async (claims,
|
|
326826
|
+
onRejected: async (claims, who2) => {
|
|
326276
326827
|
const store = await options.actors(claims.companyId);
|
|
326277
326828
|
if (!store) return;
|
|
326278
326829
|
const name = await agentName(claims.companyId, claims.actorId);
|
|
326279
326830
|
await notifyFeishuUser(
|
|
326280
326831
|
store,
|
|
326281
326832
|
claims.actorId,
|
|
326282
|
-
`\u6709\u4EBA\u7528\u53E6\u4E00\u4E2A\u98DE\u4E66\u8D26\u53F7${
|
|
326833
|
+
`\u6709\u4EBA\u7528\u53E6\u4E00\u4E2A\u98DE\u4E66\u8D26\u53F7${who2.userName ? `\uFF08${who2.userName}\uFF09` : ""}\u6253\u5F00\u4E86\u300C${name}\u300D\u7684\u91CD\u65B0\u6388\u6743\u94FE\u63A5\uFF0C\u5DF2\u88AB\u62D2\u7EDD\uFF0C\u6388\u6743\u672A\u6539\u53D8\u3002`,
|
|
326283
326834
|
claims.subject
|
|
326284
326835
|
).catch(() => void 0);
|
|
326285
326836
|
}
|
|
@@ -326332,6 +326883,7 @@ var PostgresTodoStore = class _PostgresTodoStore {
|
|
|
326332
326883
|
await pool.query(`ALTER TABLE ${store.s}.todos ADD COLUMN IF NOT EXISTS sent_at timestamptz`);
|
|
326333
326884
|
await pool.query(`ALTER TABLE ${store.s}.todos ADD COLUMN IF NOT EXISTS first_viewed_at timestamptz`);
|
|
326334
326885
|
await pool.query(`ALTER TABLE ${store.s}.todos ADD COLUMN IF NOT EXISTS source_run_id text`);
|
|
326886
|
+
await pool.query(`ALTER TABLE ${store.s}.todos ADD COLUMN IF NOT EXISTS result text`);
|
|
326335
326887
|
const check2 = await pool.query(`SELECT pg_get_constraintdef(c.oid) AS def FROM pg_constraint c
|
|
326336
326888
|
JOIN pg_class t ON t.oid = c.conrelid JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
326337
326889
|
WHERE n.nspname = $1 AND t.relname = 'todos' AND c.conname = 'todos_status_check'`, [schema]);
|
|
@@ -326386,8 +326938,8 @@ var PostgresTodoStore = class _PostgresTodoStore {
|
|
|
326386
326938
|
return this.tx(async (client) => {
|
|
326387
326939
|
const r5 = await client.query(`INSERT INTO ${this.s}.todos (id,title,note,creator_actor_id,assignee_actor_id,recorded_by_actor_id,
|
|
326388
326940
|
due_date,due_time,status,done_at,cancelled_at,source_chat_session_id,linked_workorder_id,created_at,updated_at,start_date,start_time,
|
|
326389
|
-
sent_at,first_viewed_at,source_run_id)
|
|
326390
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20) RETURNING *`, rowValues(todo));
|
|
326941
|
+
sent_at,first_viewed_at,source_run_id,result)
|
|
326942
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21) RETURNING *`, rowValues(todo));
|
|
326391
326943
|
await this.insertChanges(client, changes);
|
|
326392
326944
|
return fromRow3(r5.rows[0]);
|
|
326393
326945
|
});
|
|
@@ -326401,8 +326953,8 @@ var PostgresTodoStore = class _PostgresTodoStore {
|
|
|
326401
326953
|
const r5 = await client.query(`UPDATE ${this.s}.todos SET title=$2,note=$3,creator_actor_id=$4,assignee_actor_id=$5,
|
|
326402
326954
|
recorded_by_actor_id=$6,due_date=$7,due_time=$8,status=$9,done_at=$10,cancelled_at=$11,source_chat_session_id=$12,
|
|
326403
326955
|
linked_workorder_id=$13,created_at=$14,updated_at=$15,start_date=$16,start_time=$17,
|
|
326404
|
-
sent_at=$18,first_viewed_at=COALESCE(first_viewed_at,$19),source_run_id=$20
|
|
326405
|
-
WHERE id=$1 AND updated_at=$
|
|
326956
|
+
sent_at=$18,first_viewed_at=COALESCE(first_viewed_at,$19),source_run_id=$20,result=$21
|
|
326957
|
+
WHERE id=$1 AND updated_at=$22::timestamptz RETURNING *`, [...rowValues(next), expectedUpdatedAt]);
|
|
326406
326958
|
if (!r5.rows[0]) return null;
|
|
326407
326959
|
await this.insertChanges(client, changes);
|
|
326408
326960
|
return fromRow3(r5.rows[0]);
|
|
@@ -326480,7 +327032,8 @@ function rowValues(t) {
|
|
|
326480
327032
|
t.startTime ?? null,
|
|
326481
327033
|
t.sentAt ?? null,
|
|
326482
327034
|
t.firstViewedAt ?? null,
|
|
326483
|
-
t.sourceRunId ?? null
|
|
327035
|
+
t.sourceRunId ?? null,
|
|
327036
|
+
t.result ?? null
|
|
326484
327037
|
];
|
|
326485
327038
|
}
|
|
326486
327039
|
function fromRow3(row) {
|
|
@@ -326506,12 +327059,103 @@ function fromRow3(row) {
|
|
|
326506
327059
|
["linkedWorkorderId", row["linked_workorder_id"]],
|
|
326507
327060
|
["sentAt", iso8(row["sent_at"])],
|
|
326508
327061
|
["firstViewedAt", iso8(row["first_viewed_at"])],
|
|
326509
|
-
["sourceRunId", row["source_run_id"]]
|
|
327062
|
+
["sourceRunId", row["source_run_id"]],
|
|
327063
|
+
["result", row["result"]]
|
|
326510
327064
|
];
|
|
326511
327065
|
for (const [k6, v2] of opt) if (v2 !== void 0 && v2 !== null) t[k6] = v2;
|
|
326512
327066
|
return t;
|
|
326513
327067
|
}
|
|
326514
327068
|
|
|
327069
|
+
// ../storage/src/postgres-overlap-events.ts
|
|
327070
|
+
init_pg_ident();
|
|
327071
|
+
init_schema_ddl_lock();
|
|
327072
|
+
var PostgresOverlapEventStore = class _PostgresOverlapEventStore {
|
|
327073
|
+
constructor(pool, schema) {
|
|
327074
|
+
this.pool = pool;
|
|
327075
|
+
this.s = quoteIdent2(schema);
|
|
327076
|
+
}
|
|
327077
|
+
s;
|
|
327078
|
+
static async open(pool, schema) {
|
|
327079
|
+
const store = new _PostgresOverlapEventStore(pool, schema);
|
|
327080
|
+
await withSchemaDdlLock(pool, schema, async () => {
|
|
327081
|
+
await pool.query(`CREATE SCHEMA IF NOT EXISTS ${store.s}`);
|
|
327082
|
+
await pool.query(`CREATE TABLE IF NOT EXISTS ${store.s}.overlap_events (
|
|
327083
|
+
id text PRIMARY KEY,
|
|
327084
|
+
at timestamptz NOT NULL,
|
|
327085
|
+
principal_actor_id text NOT NULL,
|
|
327086
|
+
actor_id text NOT NULL,
|
|
327087
|
+
action text NOT NULL,
|
|
327088
|
+
subject_id text,
|
|
327089
|
+
chat_session_id text,
|
|
327090
|
+
candidates jsonb NOT NULL,
|
|
327091
|
+
min_score double precision NOT NULL
|
|
327092
|
+
)`);
|
|
327093
|
+
await pool.query(`CREATE INDEX IF NOT EXISTS overlap_events_at_idx ON ${store.s}.overlap_events (at DESC)`);
|
|
327094
|
+
});
|
|
327095
|
+
return store;
|
|
327096
|
+
}
|
|
327097
|
+
async append(e5) {
|
|
327098
|
+
await this.pool.query(
|
|
327099
|
+
`INSERT INTO ${this.s}.overlap_events (id,at,principal_actor_id,actor_id,action,subject_id,chat_session_id,candidates,min_score)
|
|
327100
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8::jsonb,$9) ON CONFLICT (id) DO NOTHING`,
|
|
327101
|
+
[e5.id, e5.at, e5.principalActorId, e5.actorId, e5.action, e5.subjectId ?? null, e5.chatSessionId ?? null, JSON.stringify(e5.candidates), e5.minScore]
|
|
327102
|
+
);
|
|
327103
|
+
}
|
|
327104
|
+
async listRecent(limit) {
|
|
327105
|
+
const r5 = await this.pool.query(`SELECT * FROM ${this.s}.overlap_events ORDER BY at DESC, id LIMIT $1`, [limit]);
|
|
327106
|
+
return r5.rows.map((row) => ({
|
|
327107
|
+
id: row.id,
|
|
327108
|
+
at: (row.at instanceof Date ? row.at : new Date(row.at)).toISOString(),
|
|
327109
|
+
principalActorId: row.principal_actor_id,
|
|
327110
|
+
actorId: row.actor_id,
|
|
327111
|
+
action: row.action,
|
|
327112
|
+
...row.subject_id ? { subjectId: row.subject_id } : {},
|
|
327113
|
+
...row.chat_session_id ? { chatSessionId: row.chat_session_id } : {},
|
|
327114
|
+
candidates: row.candidates,
|
|
327115
|
+
minScore: Number(row.min_score)
|
|
327116
|
+
}));
|
|
327117
|
+
}
|
|
327118
|
+
};
|
|
327119
|
+
|
|
327120
|
+
// ../server/src/domains/overlap/store.ts
|
|
327121
|
+
var import_node_crypto102 = require("node:crypto");
|
|
327122
|
+
var import_promises24 = require("node:fs/promises");
|
|
327123
|
+
var import_node_path36 = require("node:path");
|
|
327124
|
+
var MemoryOverlapEventStore = class _MemoryOverlapEventStore {
|
|
327125
|
+
constructor(filename) {
|
|
327126
|
+
this.filename = filename;
|
|
327127
|
+
}
|
|
327128
|
+
rows = [];
|
|
327129
|
+
tail = Promise.resolve();
|
|
327130
|
+
static async open(filename) {
|
|
327131
|
+
const store = new _MemoryOverlapEventStore(filename);
|
|
327132
|
+
try {
|
|
327133
|
+
store.rows = JSON.parse(await (0, import_promises24.readFile)(filename, "utf8"));
|
|
327134
|
+
} catch (error3) {
|
|
327135
|
+
if (error3.code !== "ENOENT") throw error3;
|
|
327136
|
+
}
|
|
327137
|
+
return store;
|
|
327138
|
+
}
|
|
327139
|
+
append(event) {
|
|
327140
|
+
const pending = this.tail.then(async () => {
|
|
327141
|
+
const next = [...this.rows, structuredClone(event)];
|
|
327142
|
+
if (this.filename) {
|
|
327143
|
+
await (0, import_promises24.mkdir)((0, import_node_path36.dirname)(this.filename), { recursive: true });
|
|
327144
|
+
const temp = `${this.filename}.${(0, import_node_crypto102.randomUUID)()}.tmp`;
|
|
327145
|
+
await (0, import_promises24.writeFile)(temp, JSON.stringify(next), "utf8");
|
|
327146
|
+
await (0, import_promises24.rename)(temp, this.filename);
|
|
327147
|
+
}
|
|
327148
|
+
this.rows = next;
|
|
327149
|
+
});
|
|
327150
|
+
this.tail = pending.catch(() => void 0);
|
|
327151
|
+
return pending;
|
|
327152
|
+
}
|
|
327153
|
+
async listRecent(limit) {
|
|
327154
|
+
await this.tail;
|
|
327155
|
+
return [...this.rows].sort((a5, b6) => a5.at < b6.at ? 1 : a5.at > b6.at ? -1 : 0).slice(0, limit).map((e5) => structuredClone(e5));
|
|
327156
|
+
}
|
|
327157
|
+
};
|
|
327158
|
+
|
|
326515
327159
|
// ../cli/src/rebuild-artifact-projections-per-company.ts
|
|
326516
327160
|
init_src11();
|
|
326517
327161
|
var DEFAULT_LOGGER = {
|
|
@@ -326568,7 +327212,7 @@ init_src5();
|
|
|
326568
327212
|
init_chat_exit();
|
|
326569
327213
|
|
|
326570
327214
|
// ../cli/src/chat-task-header.ts
|
|
326571
|
-
var
|
|
327215
|
+
var import_node_crypto103 = require("node:crypto");
|
|
326572
327216
|
init_src11();
|
|
326573
327217
|
init_src();
|
|
326574
327218
|
var BRAINSTORM_LEGACY_LINE = "\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";
|
|
@@ -326629,7 +327273,7 @@ function buildChatTurnPrompts(input) {
|
|
|
326629
327273
|
};
|
|
326630
327274
|
}
|
|
326631
327275
|
function chatSystemPromptFingerprint(systemPrompt) {
|
|
326632
|
-
return (0,
|
|
327276
|
+
return (0, import_node_crypto103.createHash)("sha256").update(systemPrompt ?? "").digest("hex").slice(0, 16);
|
|
326633
327277
|
}
|
|
326634
327278
|
|
|
326635
327279
|
// ../cli/src/chat-task-md.ts
|
|
@@ -327483,7 +328127,7 @@ function oasisWrapperScript() {
|
|
|
327483
328127
|
const repoRoot = (0, import_node_url7.fileURLToPath)(new URL("../../../", __esm_import_meta_url));
|
|
327484
328128
|
const tsx = path32.join(repoRoot, "node_modules/.bin/tsx");
|
|
327485
328129
|
const main = path32.join(repoRoot, "packages/cli/src/main.ts");
|
|
327486
|
-
const key2 = (0,
|
|
328130
|
+
const key2 = (0, import_node_crypto104.createHash)("sha256").update(repoRoot).digest("hex").slice(0, 12);
|
|
327487
328131
|
const uid = typeof process.getuid === "function" ? process.getuid() : "na";
|
|
327488
328132
|
const stable = path32.join(os9.tmpdir(), `oasis-cli-wrapper-${uid}-${key2}`);
|
|
327489
328133
|
let dir;
|
|
@@ -327911,7 +328555,7 @@ async function startServe(opts) {
|
|
|
327911
328555
|
if (!hub) return Promise.resolve({ ok: false, reason: "\u672C\u8FDB\u7A0B\u6CA1\u6709\u8282\u70B9\u7F51\u5173" });
|
|
327912
328556
|
const online = hub.connectedDaemons().some((d5) => d5.daemonId === nodeId);
|
|
327913
328557
|
if (!online) return Promise.resolve({ ok: false, reason: "\u8282\u70B9\u5F53\u524D\u4E0D\u5728\u7EBF\uFF0C\u7528\u7684\u662F\u5B83\u4E0A\u6B21\u62A5\u7684\u6E05\u5355" });
|
|
327914
|
-
const requestId = (0,
|
|
328558
|
+
const requestId = (0, import_node_crypto104.randomUUID)();
|
|
327915
328559
|
const task = new Promise((resolve13) => {
|
|
327916
328560
|
const timer = setTimeout(() => {
|
|
327917
328561
|
modelRefreshWaiters.delete(requestId);
|
|
@@ -328760,7 +329404,7 @@ async function startServe(opts) {
|
|
|
328760
329404
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
328761
329405
|
if (buf || session.runId) {
|
|
328762
329406
|
await turnStore.appendMessage({
|
|
328763
|
-
id: (0,
|
|
329407
|
+
id: (0, import_node_crypto104.randomUUID)(),
|
|
328764
329408
|
sessionId: chatSessionId,
|
|
328765
329409
|
role: "assistant",
|
|
328766
329410
|
content: buf,
|
|
@@ -328806,7 +329450,7 @@ async function startServe(opts) {
|
|
|
328806
329450
|
chatTargets: {
|
|
328807
329451
|
inspect: inspectChatTarget,
|
|
328808
329452
|
createTargetSession: async ({ companyId, agentId, ownerHumanActorId, title }) => {
|
|
328809
|
-
const sessionId = (0,
|
|
329453
|
+
const sessionId = (0, import_node_crypto104.randomUUID)();
|
|
328810
329454
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
328811
329455
|
const binding = await registryStore.getBinding(agentId).catch(() => null);
|
|
328812
329456
|
await (await chatStoreFor(companyId)).createSession({
|
|
@@ -329976,7 +330620,7 @@ async function startServe(opts) {
|
|
|
329976
330620
|
onQuotaExhausted: (t) => {
|
|
329977
330621
|
const daemon = hub?.connectedDaemons().find((d5) => d5.daemonId === t.nodeId);
|
|
329978
330622
|
if (!daemon?.meta.supportsQuotaRefresh) return;
|
|
329979
|
-
hub?.dispatch(t.nodeId, { type: "refresh_quotas", requestId: (0,
|
|
330623
|
+
hub?.dispatch(t.nodeId, { type: "refresh_quotas", requestId: (0, import_node_crypto104.randomUUID)() });
|
|
329980
330624
|
},
|
|
329981
330625
|
actorName: async (actorId) => (await (await actors.resolveCtx(companyId)).service.getActor(actorId).catch(() => null))?.name ?? null
|
|
329982
330626
|
});
|
|
@@ -330092,17 +330736,18 @@ async function startServe(opts) {
|
|
|
330092
330736
|
warn: (error3) => console.warn(`[discussions] ${String(error3)}`)
|
|
330093
330737
|
});
|
|
330094
330738
|
const todoStores = /* @__PURE__ */ new Map();
|
|
330739
|
+
const todoStoreFor = (companyId) => {
|
|
330740
|
+
let store = todoStores.get(companyId);
|
|
330741
|
+
if (!store) {
|
|
330742
|
+
store = pgPool ? PostgresTodoStore.open(pgPool, engineSchemaFor(companyId)) : MemoryTodoStore.open(path32.join(opts.dir, "companies", companyEngineDirName(companyId), "todos.json"));
|
|
330743
|
+
todoStores.set(companyId, store);
|
|
330744
|
+
void store.catch(() => todoStores.delete(companyId));
|
|
330745
|
+
}
|
|
330746
|
+
return store;
|
|
330747
|
+
};
|
|
330095
330748
|
const todoRuntime = createTodoRuntime({
|
|
330096
330749
|
companies: async () => (await controlPlaneStore.listCompanies()).filter((c5) => c5.status === "active").map((c5) => c5.id),
|
|
330097
|
-
store:
|
|
330098
|
-
let store = todoStores.get(companyId);
|
|
330099
|
-
if (!store) {
|
|
330100
|
-
store = pgPool ? PostgresTodoStore.open(pgPool, engineSchemaFor(companyId)) : MemoryTodoStore.open(path32.join(opts.dir, "companies", companyEngineDirName(companyId), "todos.json"));
|
|
330101
|
-
todoStores.set(companyId, store);
|
|
330102
|
-
void store.catch(() => todoStores.delete(companyId));
|
|
330103
|
-
}
|
|
330104
|
-
return store;
|
|
330105
|
-
},
|
|
330750
|
+
store: todoStoreFor,
|
|
330106
330751
|
timeZone: (companyId) => companies.service.effectiveTimeZoneOf(companyId),
|
|
330107
330752
|
boundHuman: async (agentId, companyId) => (await (await resolveAssistantsCtx(companyId)).service.getByAgent(agentId))?.humanActorId ?? null,
|
|
330108
330753
|
notifications: (companyId) => notificationStoreFor(companyId),
|
|
@@ -330122,6 +330767,31 @@ async function startServe(opts) {
|
|
|
330122
330767
|
defaultCompanyId: () => defaultCompanyId,
|
|
330123
330768
|
warn: (error3) => console.warn(`[todos] ${String(error3)}`)
|
|
330124
330769
|
});
|
|
330770
|
+
const overlapEventStores = /* @__PURE__ */ new Map();
|
|
330771
|
+
const overlapRuntime = createOverlapRuntime({
|
|
330772
|
+
todos: todoStoreFor,
|
|
330773
|
+
workorderModel: async (companyId) => (await getEngine(companyId)).kernel.model,
|
|
330774
|
+
delegations: (companyId) => delegationStoreFor(companyId),
|
|
330775
|
+
people: async (companyId) => (await companies.service.listMemberViews(companyId)).map((m4) => ({
|
|
330776
|
+
actorId: m4.actorId,
|
|
330777
|
+
name: m4.displayName?.trim() || m4.name?.trim() || m4.email || m4.actorId
|
|
330778
|
+
})),
|
|
330779
|
+
actorName: async (companyId, actorId) => (await (await actors.resolveCtx(companyId)).service.getActor(actorId))?.name,
|
|
330780
|
+
sessionHuman: async (companyId, chatSessionId) => (await (await chatStoreFor(companyId)).getSession(chatSessionId))?.humanActorId,
|
|
330781
|
+
boundHuman: async (agentId, companyId) => (await (await resolveAssistantsCtx(companyId)).service.getByAgent(agentId))?.humanActorId ?? null,
|
|
330782
|
+
events: (companyId) => {
|
|
330783
|
+
let store = overlapEventStores.get(companyId);
|
|
330784
|
+
if (!store) {
|
|
330785
|
+
store = pgPool ? PostgresOverlapEventStore.open(pgPool, engineSchemaFor(companyId)) : MemoryOverlapEventStore.open(path32.join(opts.dir, "companies", companyEngineDirName(companyId), "overlap-events.json"));
|
|
330786
|
+
overlapEventStores.set(companyId, store);
|
|
330787
|
+
void store.catch(() => overlapEventStores.delete(companyId));
|
|
330788
|
+
}
|
|
330789
|
+
return store;
|
|
330790
|
+
},
|
|
330791
|
+
timeZone: (companyId) => companies.service.effectiveTimeZoneOf(companyId),
|
|
330792
|
+
defaultCompanyId: () => defaultCompanyId,
|
|
330793
|
+
warn: (error3) => console.warn(`[overlap] ${String(error3)}`)
|
|
330794
|
+
});
|
|
330125
330795
|
const connectorRenewal = createConnectorRenewalRuntime({
|
|
330126
330796
|
companies: async () => (await controlPlaneStore.listCompanies()).filter((c5) => c5.status === "active").map((c5) => c5.id),
|
|
330127
330797
|
actors: async (companyId) => (await actors.resolveCtx(companyId)).service,
|
|
@@ -330360,7 +331030,7 @@ async function startServe(opts) {
|
|
|
330360
331030
|
}));
|
|
330361
331031
|
}
|
|
330362
331032
|
const limits = { wallClockMs: wallClockForKind("planner") };
|
|
330363
|
-
const artifactId = `artifact:planner:${(0,
|
|
331033
|
+
const artifactId = `artifact:planner:${(0, import_node_crypto104.randomUUID)()}`;
|
|
330364
331034
|
const handle = await chatRemoteAdapter.spawn({
|
|
330365
331035
|
actor: planner.id,
|
|
330366
331036
|
// companyId 同协调者:planner 用的就是默认公司的 actors 服务,漏签会让它一调公司域端点就 404。
|
|
@@ -330403,6 +331073,7 @@ async function startServe(opts) {
|
|
|
330403
331073
|
projectsDomain2.register,
|
|
330404
331074
|
discussionRuntime.register,
|
|
330405
331075
|
todoRuntime.register,
|
|
331076
|
+
overlapRuntime.register,
|
|
330406
331077
|
typesDomain({
|
|
330407
331078
|
admin: typesAdmin,
|
|
330408
331079
|
resolveAdmin: async (companyId) => {
|
|
@@ -331285,10 +331956,10 @@ async function startServe(opts) {
|
|
|
331285
331956
|
if (isDeletedActor(dispatchTarget)) {
|
|
331286
331957
|
throw new ApiError(409, ACTOR_DELETED_ERROR_CODE, ACTOR_DELETED_CHAT_MESSAGE);
|
|
331287
331958
|
}
|
|
331288
|
-
const runtimeSessionId = sessionId ?? (requestDispatchId ? deterministicUuid(retargetClaimedDispatch ? `chat-runtime:${requestDispatchId}:retry:${(0,
|
|
331959
|
+
const runtimeSessionId = sessionId ?? (requestDispatchId ? deterministicUuid(retargetClaimedDispatch ? `chat-runtime:${requestDispatchId}:retry:${(0, import_node_crypto104.randomUUID)()}` : `chat-runtime:${requestDispatchId}`) : (0, import_node_crypto104.randomUUID)());
|
|
331289
331960
|
const resumeRuntimeSession = Boolean(sessionId);
|
|
331290
|
-
const traceRunId = requestDispatchId ? stableChatTraceRunId(requestDispatchId) : `chat-run:${(0,
|
|
331291
|
-
const artifactId = requestDispatchId ? `artifact:chat:${deterministicUuid(`chat-artifact:${requestDispatchId}`)}` : `artifact:chat:${(0,
|
|
331961
|
+
const traceRunId = requestDispatchId ? stableChatTraceRunId(requestDispatchId) : `chat-run:${(0, import_node_crypto104.randomUUID)()}`;
|
|
331962
|
+
const artifactId = requestDispatchId ? `artifact:chat:${deterministicUuid(`chat-artifact:${requestDispatchId}`)}` : `artifact:chat:${(0, import_node_crypto104.randomUUID)()}`;
|
|
331292
331963
|
let stableDispatch = requestDispatchId ? await resolveStableChatDispatch({ store: await traceStoreFor(runCompanyId), runId: traceRunId }) : null;
|
|
331293
331964
|
const retargetClaim = Boolean(retargetClaimedDispatch && stableDispatch && allocatedTurn);
|
|
331294
331965
|
if (stableDispatch && !stableDispatch.shouldDispatch && !retargetClaim) {
|
|
@@ -332953,7 +333624,7 @@ async function startServe(opts) {
|
|
|
332953
333624
|
console.log(`[new-engine] dispatchWork ${workId} \u662F human work\u2014\u2014\u4E0D\u6D3E runtime\uFF0C\u7B49\u5F85\u4EBA\u5DE5\u5904\u7406`);
|
|
332954
333625
|
return;
|
|
332955
333626
|
}
|
|
332956
|
-
const ledgerId = opts2?.protocolRecovery?.dispatchId ?? `dispatch:${(0,
|
|
333627
|
+
const ledgerId = opts2?.protocolRecovery?.dispatchId ?? `dispatch:${(0, import_node_crypto104.randomUUID)()}`;
|
|
332957
333628
|
try {
|
|
332958
333629
|
const inserted = await (await dispatchLedgerFor(companyId)).insertOpen({
|
|
332959
333630
|
id: ledgerId,
|
|
@@ -333053,7 +333724,7 @@ async function startServe(opts) {
|
|
|
333053
333724
|
const kernelModel = newKernel.model;
|
|
333054
333725
|
const art = kernelModel.artifacts.get(nodeId);
|
|
333055
333726
|
const revWid = art?.workspace ?? "";
|
|
333056
|
-
const ledgerId = `dispatch:${(0,
|
|
333727
|
+
const ledgerId = `dispatch:${(0, import_node_crypto104.randomUUID)()}`;
|
|
333057
333728
|
try {
|
|
333058
333729
|
await (await dispatchLedgerFor(companyId)).insertOpen({
|
|
333059
333730
|
id: ledgerId,
|
|
@@ -333424,7 +334095,7 @@ async function startServe(opts) {
|
|
|
333424
334095
|
resolveSupplementalContext: server.knowledgeGovernance ? async ({ actorId, artifactId, workOrderId, action, part, runtimeKind, taskMarkdown }) => {
|
|
333425
334096
|
try {
|
|
333426
334097
|
const governance = server.knowledgeGovernance;
|
|
333427
|
-
const taskFingerprint = (0,
|
|
334098
|
+
const taskFingerprint = (0, import_node_crypto104.createHash)("sha256").update(JSON.stringify({ artifactId, workOrderId, action, part: part ?? null, taskMarkdown })).digest("hex");
|
|
333428
334099
|
const requestContext = {
|
|
333429
334100
|
organizationId: companyId,
|
|
333430
334101
|
actorId,
|
|
@@ -335929,9 +336600,9 @@ function readCodexQuota(binary, signal, timeoutMs = 15e3) {
|
|
|
335929
336600
|
|
|
335930
336601
|
// ../cli/src/daemon/quota/claude.ts
|
|
335931
336602
|
var import_node_child_process18 = require("node:child_process");
|
|
335932
|
-
var
|
|
336603
|
+
var import_promises25 = require("node:fs/promises");
|
|
335933
336604
|
var import_node_os14 = require("node:os");
|
|
335934
|
-
var
|
|
336605
|
+
var import_node_path37 = require("node:path");
|
|
335935
336606
|
var import_node_util5 = require("node:util");
|
|
335936
336607
|
var exec = (0, import_node_util5.promisify)(import_node_child_process18.execFile);
|
|
335937
336608
|
var USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
|
|
@@ -335950,9 +336621,9 @@ async function credentials(env2, signal) {
|
|
|
335950
336621
|
}
|
|
335951
336622
|
}
|
|
335952
336623
|
if (!raw) {
|
|
335953
|
-
const file = (0,
|
|
335954
|
-
if ((await (0,
|
|
335955
|
-
raw = await (0,
|
|
336624
|
+
const file = (0, import_node_path37.join)(env2.CLAUDE_CONFIG_DIR || (0, import_node_path37.join)((0, import_node_os14.homedir)(), ".claude"), ".credentials.json");
|
|
336625
|
+
if ((await (0, import_promises25.stat)(file)).size > 256 * 1024) return void 0;
|
|
336626
|
+
raw = await (0, import_promises25.readFile)(file, { encoding: "utf8", ...signal ? { signal } : {} });
|
|
335956
336627
|
}
|
|
335957
336628
|
const oauth = object6(object6(JSON.parse(raw)).claudeAiOauth);
|
|
335958
336629
|
if (typeof oauth.expiresAt === "number" && oauth.expiresAt <= Date.now()) return void 0;
|
|
@@ -336021,18 +336692,18 @@ async function readClaudeQuota(binary, signal, deps = {}) {
|
|
|
336021
336692
|
}
|
|
336022
336693
|
|
|
336023
336694
|
// ../cli/src/daemon/quota/shared-cache.ts
|
|
336024
|
-
var
|
|
336695
|
+
var import_node_crypto105 = require("node:crypto");
|
|
336025
336696
|
var import_node_fs27 = require("node:fs");
|
|
336026
336697
|
var import_node_os15 = require("node:os");
|
|
336027
|
-
var
|
|
336698
|
+
var import_node_path38 = require("node:path");
|
|
336028
336699
|
init_src();
|
|
336029
336700
|
function profileOf(kind, env2) {
|
|
336030
|
-
if (kind === "codex") return `codex:${env2.CODEX_HOME || (0,
|
|
336031
|
-
if (env2.CLAUDE_CODE_OAUTH_TOKEN) return `claude-token:${(0,
|
|
336032
|
-
return `claude:${env2.CLAUDE_CONFIG_DIR || (0,
|
|
336701
|
+
if (kind === "codex") return `codex:${env2.CODEX_HOME || (0, import_node_path38.join)((0, import_node_os15.homedir)(), ".codex")}`;
|
|
336702
|
+
if (env2.CLAUDE_CODE_OAUTH_TOKEN) return `claude-token:${(0, import_node_crypto105.createHash)("sha256").update(env2.CLAUDE_CODE_OAUTH_TOKEN).digest("hex")}`;
|
|
336703
|
+
return `claude:${env2.CLAUDE_CONFIG_DIR || (0, import_node_path38.join)((0, import_node_os15.homedir)(), ".claude")}`;
|
|
336033
336704
|
}
|
|
336034
336705
|
function fileQuotaCache(dir, env2 = process.env) {
|
|
336035
|
-
const file = (kind) => (0,
|
|
336706
|
+
const file = (kind) => (0, import_node_path38.join)(dir, `${kind}-${(0, import_node_crypto105.createHash)("sha256").update(profileOf(kind, env2)).digest("hex").slice(0, 16)}.json`);
|
|
336036
336707
|
return {
|
|
336037
336708
|
get(kind) {
|
|
336038
336709
|
try {
|
|
@@ -336214,7 +336885,7 @@ var RuntimeQuotaMonitor = class _RuntimeQuotaMonitor {
|
|
|
336214
336885
|
init_wrapper();
|
|
336215
336886
|
init_src();
|
|
336216
336887
|
var import_node_os16 = require("node:os");
|
|
336217
|
-
var
|
|
336888
|
+
var import_node_crypto107 = require("node:crypto");
|
|
336218
336889
|
init_src3();
|
|
336219
336890
|
init_src2();
|
|
336220
336891
|
|
|
@@ -336279,9 +336950,9 @@ function detectRuntimes() {
|
|
|
336279
336950
|
}
|
|
336280
336951
|
|
|
336281
336952
|
// ../cli/src/daemon/workdir-handler.ts
|
|
336282
|
-
var
|
|
336953
|
+
var import_node_crypto106 = require("node:crypto");
|
|
336283
336954
|
var import_node_fs28 = __toESM(require("node:fs"), 1);
|
|
336284
|
-
var
|
|
336955
|
+
var import_node_path39 = __toESM(require("node:path"), 1);
|
|
336285
336956
|
init_src2();
|
|
336286
336957
|
init_src();
|
|
336287
336958
|
var WORKDIR_READ_MAX_BYTES = 2 * 1024 * 1024;
|
|
@@ -336302,10 +336973,10 @@ function isSensitiveSegment(segment) {
|
|
|
336302
336973
|
}
|
|
336303
336974
|
function relPathIsSensitive(rel) {
|
|
336304
336975
|
if (!rel) return false;
|
|
336305
|
-
return rel.split(
|
|
336976
|
+
return rel.split(import_node_path39.default.sep).some((seg) => seg.length > 0 && isSensitiveSegment(seg));
|
|
336306
336977
|
}
|
|
336307
336978
|
function withinBase(p4, base) {
|
|
336308
|
-
return p4 === base || p4.startsWith(base +
|
|
336979
|
+
return p4 === base || p4.startsWith(base + import_node_path39.default.sep);
|
|
336309
336980
|
}
|
|
336310
336981
|
function normalizeRel(raw) {
|
|
336311
336982
|
const trimmed = (raw ?? "").trim();
|
|
@@ -336322,7 +336993,7 @@ async function trustedCanonicalContainer(req, logicalBase, dirKind) {
|
|
|
336322
336993
|
} catch {
|
|
336323
336994
|
return null;
|
|
336324
336995
|
}
|
|
336325
|
-
return isLegacy ?
|
|
336996
|
+
return isLegacy ? import_node_path39.default.join(trustedRootReal, "oasis-chat-sessions") : import_node_path39.default.join(trustedRootReal, "sessions", dirKind);
|
|
336326
336997
|
}
|
|
336327
336998
|
async function resolveWithinWorkdir(req) {
|
|
336328
336999
|
const dirKind = sessionDirKind(req.runtimeKind);
|
|
@@ -336340,11 +337011,11 @@ async function resolveWithinWorkdir(req) {
|
|
|
336340
337011
|
} catch {
|
|
336341
337012
|
return { ok: false, code: "NOT_FOUND" };
|
|
336342
337013
|
}
|
|
336343
|
-
if (
|
|
337014
|
+
if (import_node_path39.default.dirname(base) !== canonicalContainer) return { ok: false, code: "PATH_ESCAPE" };
|
|
336344
337015
|
const rel = normalizeRel(req.path);
|
|
336345
|
-
const requested =
|
|
337016
|
+
const requested = import_node_path39.default.resolve(base, rel);
|
|
336346
337017
|
if (!withinBase(requested, base)) return { ok: false, code: "PATH_ESCAPE" };
|
|
336347
|
-
const cleanRel = base === requested ? "" :
|
|
337018
|
+
const cleanRel = base === requested ? "" : import_node_path39.default.relative(base, requested);
|
|
336348
337019
|
if (relPathIsSensitive(cleanRel)) return { ok: false, code: "SENSITIVE" };
|
|
336349
337020
|
let real;
|
|
336350
337021
|
try {
|
|
@@ -336354,7 +337025,7 @@ async function resolveWithinWorkdir(req) {
|
|
|
336354
337025
|
return { ok: false, code: "PATH_ESCAPE" };
|
|
336355
337026
|
}
|
|
336356
337027
|
if (!withinBase(real, base)) return { ok: false, code: "PATH_ESCAPE" };
|
|
336357
|
-
const realRel = base === real ? "" :
|
|
337028
|
+
const realRel = base === real ? "" : import_node_path39.default.relative(base, real);
|
|
336358
337029
|
if (relPathIsSensitive(realRel)) return { ok: false, code: "SENSITIVE" };
|
|
336359
337030
|
return { ok: true, base, real };
|
|
336360
337031
|
}
|
|
@@ -336390,7 +337061,7 @@ async function handleWorkdirList(req) {
|
|
|
336390
337061
|
const slice = truncated ? visible.slice(0, WORKDIR_LIST_MAX_ENTRIES) : visible;
|
|
336391
337062
|
const entries = [];
|
|
336392
337063
|
for (const d5 of slice) {
|
|
336393
|
-
const abs =
|
|
337064
|
+
const abs = import_node_path39.default.join(anchor, d5.name);
|
|
336394
337065
|
try {
|
|
336395
337066
|
const st = await import_node_fs28.default.promises.lstat(abs);
|
|
336396
337067
|
if (st.isSymbolicLink()) continue;
|
|
@@ -336457,7 +337128,7 @@ async function verifyOpenedFd(fh, base, fallback2) {
|
|
|
336457
337128
|
const fdReal = await fdCanonicalPath(fh);
|
|
336458
337129
|
if (fdReal === null) return { anchor: fallback2 };
|
|
336459
337130
|
if (!withinBase(fdReal, base)) return { error: { ok: false, code: "PATH_ESCAPE" } };
|
|
336460
|
-
const fdRel = base === fdReal ? "" :
|
|
337131
|
+
const fdRel = base === fdReal ? "" : import_node_path39.default.relative(base, fdReal);
|
|
336461
337132
|
if (relPathIsSensitive(fdRel)) return { error: { ok: false, code: "SENSITIVE" } };
|
|
336462
337133
|
return { anchor: `/proc/self/fd/${fh.fd}` };
|
|
336463
337134
|
}
|
|
@@ -336528,7 +337199,7 @@ async function handleWorkdirHash(req) {
|
|
|
336528
337199
|
const maxBytes = req.maxBytes ?? WORKDIR_READ_MAX_BYTES;
|
|
336529
337200
|
return withVerifiedRegularFile(req, async (fh, st) => {
|
|
336530
337201
|
if (st.size > maxBytes) return { ok: false, code: "TOO_LARGE", size: st.size };
|
|
336531
|
-
const hash3 = (0,
|
|
337202
|
+
const hash3 = (0, import_node_crypto106.createHash)("sha256");
|
|
336532
337203
|
const buf = Buffer.allocUnsafe(WORKDIR_HASH_CHUNK_BYTES);
|
|
336533
337204
|
let total = 0;
|
|
336534
337205
|
for (; ; ) {
|
|
@@ -336578,7 +337249,7 @@ function looksBinary(bytes2) {
|
|
|
336578
337249
|
function contentTypeFor(absPath, bytes2) {
|
|
336579
337250
|
const sniffed = sniffContentType(bytes2);
|
|
336580
337251
|
if (sniffed) return sniffed;
|
|
336581
|
-
const ext =
|
|
337252
|
+
const ext = import_node_path39.default.extname(absPath).toLowerCase();
|
|
336582
337253
|
if (EXT_CONTENT_TYPE[ext]) return EXT_CONTENT_TYPE[ext];
|
|
336583
337254
|
return looksBinary(bytes2) ? "application/octet-stream" : "text/plain; charset=utf-8";
|
|
336584
337255
|
}
|
|
@@ -337173,7 +337844,7 @@ var DaemonWsClient = class {
|
|
|
337173
337844
|
*/
|
|
337174
337845
|
async queryArtifactStates(artifactIds, timeoutMs = 15e3) {
|
|
337175
337846
|
if (artifactIds.length === 0) return {};
|
|
337176
|
-
const requestId = (0,
|
|
337847
|
+
const requestId = (0, import_node_crypto107.randomUUID)();
|
|
337177
337848
|
return new Promise((resolve13, reject) => {
|
|
337178
337849
|
const timer = setTimeout(() => {
|
|
337179
337850
|
this.gcPending.delete(requestId);
|
|
@@ -337355,17 +338026,17 @@ var RuntimeRouterAdapter = class {
|
|
|
337355
338026
|
// ../cli/src/daemon/reap-claude-projects.ts
|
|
337356
338027
|
var import_node_fs29 = __toESM(require("node:fs"), 1);
|
|
337357
338028
|
var import_node_os17 = __toESM(require("node:os"), 1);
|
|
337358
|
-
var
|
|
338029
|
+
var import_node_path40 = __toESM(require("node:path"), 1);
|
|
337359
338030
|
function claudeProjectSlug(cwd) {
|
|
337360
338031
|
return cwd.replace(/[^a-zA-Z0-9]/g, "-");
|
|
337361
338032
|
}
|
|
337362
338033
|
function claudeProjectsRoot() {
|
|
337363
|
-
const configDir = process.env["CLAUDE_CONFIG_DIR"] ||
|
|
337364
|
-
return
|
|
338034
|
+
const configDir = process.env["CLAUDE_CONFIG_DIR"] || import_node_path40.default.join(import_node_os17.default.homedir(), ".claude");
|
|
338035
|
+
return import_node_path40.default.join(configDir, "projects");
|
|
337365
338036
|
}
|
|
337366
338037
|
function reapClaudeProjects(workdir, runtimeKind) {
|
|
337367
338038
|
if (runtimeKind !== "claude" && runtimeKind !== "claude-code") return;
|
|
337368
|
-
const dir =
|
|
338039
|
+
const dir = import_node_path40.default.join(claudeProjectsRoot(), claudeProjectSlug(workdir));
|
|
337369
338040
|
if (!import_node_fs29.default.existsSync(dir)) return;
|
|
337370
338041
|
try {
|
|
337371
338042
|
import_node_fs29.default.rmSync(dir, { recursive: true, force: true });
|
|
@@ -337374,7 +338045,7 @@ function reapClaudeProjects(workdir, runtimeKind) {
|
|
|
337374
338045
|
}
|
|
337375
338046
|
function measureClaudeProjects(workdir, runtimeKind) {
|
|
337376
338047
|
if (runtimeKind !== "claude" && runtimeKind !== "claude-code") return 0;
|
|
337377
|
-
const dir =
|
|
338048
|
+
const dir = import_node_path40.default.join(claudeProjectsRoot(), claudeProjectSlug(workdir));
|
|
337378
338049
|
return dirSizeBytes2(dir);
|
|
337379
338050
|
}
|
|
337380
338051
|
function dirSizeBytes2(dir) {
|
|
@@ -337386,7 +338057,7 @@ function dirSizeBytes2(dir) {
|
|
|
337386
338057
|
return 0;
|
|
337387
338058
|
}
|
|
337388
338059
|
for (const e5 of entries) {
|
|
337389
|
-
const p4 =
|
|
338060
|
+
const p4 = import_node_path40.default.join(dir, e5.name);
|
|
337390
338061
|
if (e5.isSymbolicLink()) continue;
|
|
337391
338062
|
if (e5.isDirectory()) {
|
|
337392
338063
|
total += dirSizeBytes2(p4);
|
|
@@ -337403,7 +338074,7 @@ function dirSizeBytes2(dir) {
|
|
|
337403
338074
|
// ../cli/src/node.ts
|
|
337404
338075
|
init_src2();
|
|
337405
338076
|
var import_node_os18 = __toESM(require("node:os"), 1);
|
|
337406
|
-
var
|
|
338077
|
+
var import_node_path41 = __toESM(require("node:path"), 1);
|
|
337407
338078
|
var idleFor = (runtimeKind) => CODE_DEFAULT_POLICY.resolve({ executor: "agent", scenario: "runtime-idle", runtimeKind }).idleTimeoutMs ?? 0;
|
|
337408
338079
|
var RESILIENCE = {
|
|
337409
338080
|
codex: { idleTimeoutMs: idleFor("codex") }
|
|
@@ -337475,7 +338146,7 @@ async function startNode(opts) {
|
|
|
337475
338146
|
const client = new DaemonWsClient(opts.serverUrl, opts.nodeId, sessions, adapters, opts.token, runtimes, opts.nodeName, opts.reportRuntimes ?? false, true, opts.onUpdate, opts.daemonVersion, {
|
|
337476
338147
|
...opts.daemonPkg ? { daemonPkg: opts.daemonPkg } : {},
|
|
337477
338148
|
// 同一个 OS 用户下的所有实例(~/.oasis/instances/*)共用一份额度采集结果:同账号 5 分钟只问一次上游。
|
|
337478
|
-
quotaCacheDir:
|
|
338149
|
+
quotaCacheDir: import_node_path41.default.join(import_node_os18.default.homedir(), ".oasis", "quota-cache"),
|
|
337479
338150
|
// chat 文件浏览 handler 用它定位会话目录;production 不传 = 与 adapter 同款默认根(~/.oasis/work)。
|
|
337480
338151
|
...opts.workRoot !== void 0 ? { workRoot: opts.workRoot } : {},
|
|
337481
338152
|
...opts.spawnSessionProcess ? { spawnSessionProcess: opts.spawnSessionProcess } : {},
|
|
@@ -337594,7 +338265,7 @@ function forwardSignal(child, sig, killGroup = (pgid, signal) => {
|
|
|
337594
338265
|
// ../cli/src/daemon/machine-id.ts
|
|
337595
338266
|
var import_node_child_process20 = require("node:child_process");
|
|
337596
338267
|
var import_node_fs30 = require("node:fs");
|
|
337597
|
-
var
|
|
338268
|
+
var import_node_crypto108 = require("node:crypto");
|
|
337598
338269
|
var import_node_os19 = require("node:os");
|
|
337599
338270
|
function linuxMachineId() {
|
|
337600
338271
|
for (const p4 of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
@@ -337660,7 +338331,7 @@ var defaultSources = {
|
|
|
337660
338331
|
function resolveNodeId(sources = {}) {
|
|
337661
338332
|
const s3 = { ...defaultSources, ...sources };
|
|
337662
338333
|
const material = `${s3.machineFingerprint()}:${s3.osUser()}`;
|
|
337663
|
-
const digest3 = (0,
|
|
338334
|
+
const digest3 = (0, import_node_crypto108.createHash)("sha256").update(material).digest("hex").slice(0, 12);
|
|
337664
338335
|
return `node-${digest3}`;
|
|
337665
338336
|
}
|
|
337666
338337
|
|
|
@@ -337962,8 +338633,8 @@ var COMMAND_DECLS = {
|
|
|
337962
338633
|
},
|
|
337963
338634
|
delegate: {
|
|
337964
338635
|
group: "\u59D4\u6D3E\u4E13\u5BB6",
|
|
337965
|
-
usage: 'oasis delegate --to <role|actorId> --task "<\u4EFB\u52A1\u4E66>" [--as <\u77ED\u540D>] [--file <\u8DEF\u5F84>]... [--json true]\n oasis delegate --follow-up <\u5F15\u7528> --text "<...>" [--file <\u8DEF\u5F84>]...\n oasis delegate --status <\u5F15\u7528> [--json true]\n oasis delegate --list [--all] [--json true]',
|
|
337966
|
-
description: "\u628A\u4E00\u4EF6\u4E8B\u4EA4\u7ED9\u7EC4\u7EC7\u91CC\u5BF9\u53E3\u7684\u4E13\u5BB6\u53BB\u505A\uFF08\u5F02\u6B65\uFF09\u3002\u547D\u4EE4\u7ACB\u5373\u8FD4\u56DE\uFF0C\u4E13\u5BB6\u5E72\u5B8C\u4E86\u7ED3\u679C\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\u2014\u2014**\u4E0D\u8981\u5728\u8FD9\u91CC\u7B49**\u3002",
|
|
338636
|
+
usage: 'oasis delegate --to <role|actorId> --task "<\u4EFB\u52A1\u4E66>" [--as <\u77ED\u540D>] [--file <\u8DEF\u5F84>]... [--json true]\n oasis delegate --follow-up <\u5F15\u7528> --text "<...>" [--file <\u8DEF\u5F84>]...\n oasis delegate --status <\u5F15\u7528|\u59D4\u6D3Eid> [--json true]\n oasis delegate --list [--all] [--json true]',
|
|
338637
|
+
description: "\u628A\u4E00\u4EF6\u4E8B\u4EA4\u7ED9\u7EC4\u7EC7\u91CC\u5BF9\u53E3\u7684\u4E13\u5BB6\u53BB\u505A\uFF08\u5F02\u6B65\uFF09\u3002\u547D\u4EE4\u7ACB\u5373\u8FD4\u56DE\uFF0C\u4E13\u5BB6\u5E72\u5B8C\u4E86\u7ED3\u679C\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\u2014\u2014**\u4E0D\u8981\u5728\u8FD9\u91CC\u7B49**\u3002\u6210\u529F\u540E\u5982\u679C\u672C\u516C\u53F8\u6709\u4EBA\u5728\u505A\u6216\u505A\u8FC7\u76F8\u8FD1\u7684\u4E8B\uFF0C\u8F93\u51FA\u672B\u5C3E\u4F1A\u591A\u4E00\u6BB5\u300C\u76F8\u8FD1\u7684\u4E8B\u9879\uFF08\u7CFB\u7EDF\u7C97\u7B5B\uFF0C\u672A\u786E\u8BA4\uFF0C\u8BF7\u7528 id \u67E5\u8BE6\u60C5\u540E\u5224\u65AD\uFF09\u300D\uFF0C\u6BCF\u6761\u5E26 id\uFF1A\u7528 id \u9010\u6761\u67E5\u8BE6\u60C5\uFF08\u5F85\u529E oasis todo show\u3001\u5DE5\u5355 oasis workorder\u3001\u59D4\u6D3E oasis delegate --status\uFF09\uFF0C\u5224\u65AD\u662F\u4E0D\u662F\u540C\u4E00\u4EF6\u4E8B\uFF1B\u786E\u5B9E\u76F8\u5173\u624D\u544A\u8BC9\u7528\u6237\uFF0C\u4E0D\u76F8\u5173\u4E00\u4E2A\u5B57\u90FD\u4E0D\u63D0\uFF1B\u5728\u505A\u7684\u5EFA\u8BAE\u7528\u6237\u5148\u95EE\u95EE\u5BF9\u65B9\uFF0C\u770B\u5408\u5E76\u8FD8\u662F\u5206\u5DE5\uFF1B\u505A\u5B8C\u7684\u628A\u7ED3\u679C\u7ED9\u7528\u6237\uFF0C\u95EE\u80FD\u4E0D\u80FD\u76F4\u63A5\u7528\uFF1B\u4E0D\u66FF\u7528\u6237\u505C\u6389\u8FD9\u6B21\u59D4\u6D3E\u3001\u5408\u5E76\u3001\u53D6\u6D88\u6216\u6539\u6D3E\u3002\u6CA1\u6709\u8FD9\u4E00\u6BB5\u5C31\u662F\u6CA1\u6BD4\u51FA\u6765\uFF0C\u6BD4\u5BF9\u51FA\u4E86\u95EE\u9898\u4E5F\u53EA\u662F\u6CA1\u6709\u8FD9\u4E00\u6BB5\uFF0C\u547D\u4EE4\u7167\u6837\u7B97\u6210\u529F\u3002",
|
|
337967
338638
|
flags: [
|
|
337968
338639
|
{ name: "to", desc: "\u6D3E\u7ED9\u8C01\uFF1A\u5C97\u4F4D\u540D\u6216 actorId\uFF08\u5C97\u4F4D 0 \u4EBA\u5728\u5C97 / \u7ED1\u5B9A\u4E0D\u53EF\u7528\u4F1A\u5F53\u573A\u62A5\u9519\uFF0C\u90A3\u65F6\u81EA\u5DF1\u505A\uFF09" },
|
|
337969
338640
|
{ name: "task", desc: "\u4EFB\u52A1\u4E66\u5168\u6587\u2014\u2014\u4E13\u5BB6**\u552F\u4E00**\u7684\u4E0A\u4E0B\u6587\u6765\u6E90\uFF0C\u5199\u5168\uFF1B\u4E0D\u8BBE\u957F\u5EA6\u4E0A\u9650\u3001\u4E0D\u622A\u65AD" },
|
|
@@ -337971,7 +338642,7 @@ var COMMAND_DECLS = {
|
|
|
337971
338642
|
{ name: "file", desc: "\u4E00\u8D77\u5E26\u8FC7\u53BB\u7684\u6587\u4EF6\uFF08\u4F60\u5DE5\u4F5C\u76EE\u5F55\u4E0B\u7684\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u53EF\u7ED9\u591A\u6B21\uFF1B\u5355\u4E2A \u22642MB\u3001\u4E00\u6B21 \u226420 \u4E2A / 20MB\uFF09" },
|
|
337972
338643
|
{ name: "follow-up", desc: "\u5F80\u5DF2\u6709\u59D4\u6D3E\u91CC\u518D\u8FFD\u95EE/\u8F6C\u8FBE\u4E00\u53E5\uFF1A\u7ED9 label / \u4E13\u5BB6\u540D / delegationId \u524D\u7F00" },
|
|
337973
338644
|
{ name: "text", desc: "\u8FFD\u95EE\u5185\u5BB9\uFF08\u914D --follow-up\uFF09\u3002\u6539\u65B9\u5411\u5C31\u660E\u8BF4\u300C\u6539\u65B9\u5411\u300D\uFF0C\u4E13\u5BB6\u4F1A\u81EA\u5DF1\u5224\u65AD\u8981\u4E0D\u8981\u653E\u5F03\u624B\u4E0A\u90A3\u6BB5\u3002**\u770B\u56DE\u6267**\uFF1A\u63D2\u8FDB\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E / \u8D77\u4E86\u65B0\u7684\u4E00\u8F6E / \u8FD8\u6392\u5728\u961F\u5217\u91CC\u2014\u2014\u6392\u961F\u65F6\u4E13\u5BB6\u8981\u7B49\u672C\u8F6E\u8DD1\u5B8C\u624D\u770B\u89C1\uFF0C\u8BE5\u8DDF\u7528\u6237\u8BF4\u4E00\u58F0" },
|
|
337974
|
-
{ name: "status", desc: "\u770B\u4E00\u4E2A\u59D4\u6D3E\u7684\u8BE6\u60C5\uFF1A\u5168\u91CF\u5404\u8F6E\u5C0F\u7ED3 + \u4EA7\u7269\u6E05\u5355" },
|
|
338645
|
+
{ name: "status", desc: "\u770B\u4E00\u4E2A\u59D4\u6D3E\u7684\u8BE6\u60C5\uFF1A\u5168\u91CF\u5404\u8F6E\u5C0F\u7ED3 + \u4EA7\u7269\u6E05\u5355\u3002\u7ED9\u7684\u662F**\u5B8C\u6574\u59D4\u6D3E id** \u4E14\u4E0D\u662F\u672C\u6BB5\u5BF9\u8BDD\u6D3E\u51FA\u7684\uFF08\u6BD4\u5982\u300C\u76F8\u8FD1\u7684\u4E8B\u9879\u300D\u91CC\u522B\u4EBA\u6D3E\u7684\uFF09\uFF0C\u9000\u5230\u53EA\u8BFB\u6458\u8981\uFF1A\u4EFB\u52A1\u4E66\u3001\u72B6\u6001\u3001\u4E13\u5BB6\u3001\u5404\u8F6E\u5C0F\u7ED3\u3001\u4EA7\u51FA\u6587\u4EF6\u540D\u3001\u6D3E\u6D3B\u5BF9\u8BDD\u3001\u5B50\u4F1A\u8BDD\uFF08\u4E0D\u542B\u5B50\u4F1A\u8BDD\u8FC7\u7A0B\uFF0C\u4E0D\u80FD --follow-up\uFF09" },
|
|
337975
338646
|
{ name: "list", desc: "\u5217\u51FA\u8FD9\u6761\u5BF9\u8BDD\u6D3E\u51FA\u53BB\u7684\u6D3B\uFF1B\u9ED8\u8BA4\u53EA\u7ED9\u8FDB\u884C\u4E2D + \u6700\u8FD1 10 \u6761", boolean: true },
|
|
337976
338647
|
{ name: "all", desc: "\u914D --list\uFF1A\u8FDE\u5386\u53F2\u59D4\u6D3E\u4E00\u8D77\u5217", boolean: true },
|
|
337977
338648
|
{ name: "json", desc: "\u8F93\u51FA JSON" }
|
|
@@ -337981,7 +338652,8 @@ var COMMAND_DECLS = {
|
|
|
337981
338652
|
'oasis delegate --to \u8BBE\u8BA1\u5E08 --task "\u6309\u8FD9\u5F20\u53C2\u8003\u56FE\u91CD\u753B" --file inputs/attachments/ref.png',
|
|
337982
338653
|
'oasis delegate --follow-up \u767B\u5F55\u9875 --text "\u7528\u6237\u6539\u65B9\u5411\uFF1A\u4E3B\u8272\u6362\u6210\u7EFF\u8272\uFF08\u624B\u4E0A\u8FD9\u6BB5\u53EF\u80FD\u8981\u4F5C\u5E9F\uFF0C\u4F60\u81EA\u5DF1\u5224\u65AD\uFF09"',
|
|
337983
338654
|
"oasis delegate --list",
|
|
337984
|
-
"oasis delegate --status \u767B\u5F55\u9875"
|
|
338655
|
+
"oasis delegate --status \u767B\u5F55\u9875",
|
|
338656
|
+
"oasis delegate --status 3f6c2a1e-8b4d-4c55-9a2e-1d7f0b9c4e21"
|
|
337985
338657
|
]
|
|
337986
338658
|
},
|
|
337987
338659
|
"node-token": {
|
|
@@ -338007,7 +338679,7 @@ var COMMAND_DECLS = {
|
|
|
338007
338679
|
"run-playbook": {
|
|
338008
338680
|
group: "\u5DE5\u5355",
|
|
338009
338681
|
usage: "oasis run-playbook <ref> --title <t> --description <t> [--manager <actorId>] [--project <projectId>] [--attach <path> [--attach-type <mime>]]... [--dispatch true | --hold true]",
|
|
338010
|
-
description: "\u6309\u5267\u672C\u5EFA\u5355\u3002\u7F3A\u7701\u751F\u6210\u8349\u6848\uFF08\u5F85\u4EBA\u786E\u8BA4\uFF09\uFF1B--dispatch \u76F4\u63A5\u6D3E\u53D1\uFF1B--hold \u6682\u505C\u6D3E\u53D1\u3002",
|
|
338682
|
+
description: "\u6309\u5267\u672C\u5EFA\u5355\u3002\u7F3A\u7701\u751F\u6210\u8349\u6848\uFF08\u5F85\u4EBA\u786E\u8BA4\uFF09\uFF1B--dispatch \u76F4\u63A5\u6D3E\u53D1\uFF1B--hold \u6682\u505C\u6D3E\u53D1\u3002\u6210\u529F\u540E\u5982\u679C\u672C\u516C\u53F8\u6709\u4EBA\u5728\u505A\u6216\u505A\u8FC7\u76F8\u8FD1\u7684\u4E8B\uFF0C\u8F93\u51FA\u672B\u5C3E\u4F1A\u591A\u4E00\u6BB5\u300C\u76F8\u8FD1\u7684\u4E8B\u9879\uFF08\u7CFB\u7EDF\u7C97\u7B5B\uFF0C\u672A\u786E\u8BA4\uFF0C\u8BF7\u7528 id \u67E5\u8BE6\u60C5\u540E\u5224\u65AD\uFF09\u300D\uFF0C\u6BCF\u6761\u5E26 id\u2014\u2014\u9010\u6761\u67E5\u8BE6\u60C5\u518D\u5224\u65AD\u662F\u4E0D\u662F\u540C\u4E00\u4EF6\u4E8B\uFF0C\u786E\u5B9E\u76F8\u5173\u624D\u544A\u8BC9\u7528\u6237\uFF08\u89C1\u6280\u80FD\uFF09\uFF1B\u6CA1\u6709\u8FD9\u4E00\u6BB5\u5C31\u662F\u6CA1\u6BD4\u51FA\u6765\uFF0C\u6BD4\u5BF9\u51FA\u4E86\u95EE\u9898\u4E5F\u53EA\u662F\u6CA1\u6709\u8FD9\u4E00\u6BB5\uFF0C\u547D\u4EE4\u7167\u6837\u7B97\u6210\u529F\u3002",
|
|
338011
338683
|
positional: [
|
|
338012
338684
|
{ name: "<ref>", required: true, desc: "\u5267\u672C\u5F15\u7528\u540D" }
|
|
338013
338685
|
],
|
|
@@ -339012,7 +339684,7 @@ var COMMAND_DECLS = {
|
|
|
339012
339684
|
"create-workorder": {
|
|
339013
339685
|
group: "\u5DE5\u5355",
|
|
339014
339686
|
usage: "oasis create-workorder --type <t> --title <\u6807\u9898> [--brief <\u63CF\u8FF0>] [--workspace <ws>] [--owner <humanActorId>] [--dispatch true|false] [--attachment <\u672C\u5730\u6587\u4EF6> [--attach-type <mime>]]\u2026",
|
|
339015
|
-
description: "\u5EFA\u5355 agent \u628A\u5BF9\u8BDD\u6572\u5B9A\u7684\u5DE5\u5355\u7ED3\u6784\u5316\u6682\u5B58\u6210\u8349\u6848\u3002--dispatch true \u8DF3\u8FC7\u8349\u6848\u76F4\u63A5\u5EFA\u771F\u5355\u5E76\u6D3E\u53D1\uFF1B--dispatch false \u843D\u8349\u6848\u5E76\u6807\u8BB0\u7A0D\u540E\u6D3E\u53D1\u3002--attachment \u53EF\u91CD\u590D\uFF0C\u5355\u6587\u4EF6 \u226410MB\u3001\u6700\u591A 20 \u4E2A\u3002",
|
|
339687
|
+
description: "\u5EFA\u5355 agent \u628A\u5BF9\u8BDD\u6572\u5B9A\u7684\u5DE5\u5355\u7ED3\u6784\u5316\u6682\u5B58\u6210\u8349\u6848\u3002--dispatch true \u8DF3\u8FC7\u8349\u6848\u76F4\u63A5\u5EFA\u771F\u5355\u5E76\u6D3E\u53D1\uFF1B--dispatch false \u843D\u8349\u6848\u5E76\u6807\u8BB0\u7A0D\u540E\u6D3E\u53D1\u3002--attachment \u53EF\u91CD\u590D\uFF0C\u5355\u6587\u4EF6 \u226410MB\u3001\u6700\u591A 20 \u4E2A\u3002\u6210\u529F\u540E\u5982\u679C\u672C\u516C\u53F8\u6709\u4EBA\u5728\u505A\u6216\u505A\u8FC7\u76F8\u8FD1\u7684\u4E8B\uFF0C\u8F93\u51FA\u672B\u5C3E\u4F1A\u591A\u4E00\u6BB5\u300C\u76F8\u8FD1\u7684\u4E8B\u9879\uFF08\u7CFB\u7EDF\u7C97\u7B5B\uFF0C\u672A\u786E\u8BA4\uFF0C\u8BF7\u7528 id \u67E5\u8BE6\u60C5\u540E\u5224\u65AD\uFF09\u300D\uFF0C\u6BCF\u6761\u5E26 id\u2014\u2014\u9010\u6761\u67E5\u8BE6\u60C5\u518D\u5224\u65AD\u662F\u4E0D\u662F\u540C\u4E00\u4EF6\u4E8B\uFF0C\u786E\u5B9E\u76F8\u5173\u624D\u544A\u8BC9\u7528\u6237\uFF08\u89C1\u6280\u80FD\uFF09\uFF1B\u6CA1\u6709\u8FD9\u4E00\u6BB5\u5C31\u662F\u6CA1\u6BD4\u51FA\u6765\uFF0C\u6BD4\u5BF9\u51FA\u4E86\u95EE\u9898\u4E5F\u53EA\u662F\u6CA1\u6709\u8FD9\u4E00\u6BB5\uFF0C\u547D\u4EE4\u7167\u6837\u7B97\u6210\u529F\u3002",
|
|
339016
339688
|
flags: [
|
|
339017
339689
|
{ name: "type", desc: "\u6839\u4EA7\u7269\u7C7B\u578B", required: true },
|
|
339018
339690
|
{ name: "title", desc: "\u5DE5\u5355\u6807\u9898", required: true },
|
|
@@ -339408,7 +340080,7 @@ var COMMAND_DECLS = {
|
|
|
339408
340080
|
"todo add": {
|
|
339409
340081
|
group: "\u4E2A\u4EBA\u5F85\u529E",
|
|
339410
340082
|
usage: "oasis todo add [--to <\u4EBA>] --title <\u4E00\u53E5\u8BDD\uFF0C\u52A8\u8BCD\u5F00\u5934> [--note <\u8C01\u8981\u3001\u4E3A\u4EC0\u4E48\u3001\u539F\u8BDD\u8981\u70B9>] [--start YYYY-MM-DD [--start-time HH:mm]] --due YYYY-MM-DD [--time HH:mm]",
|
|
339411
|
-
description: "\u8BB0\u4E00\u6761\u5F85\u529E\u3002--due / --start \u53EA\u6536\u4E0D\u5E26\u65F6\u533A\u7684\u65E5\u671F\uFF08\u7EC4\u7EC7\u65F6\u533A\u91CC\u7684\u90A3\u4E00\u5929\uFF09\uFF0C\u975E\u6CD5\u65E5\u671F\u5F53\u573A\u62A5\u9519\uFF1B\u6CA1\u8BF4\u51E0\u70B9\u5C31\u522B\u7ED9 --time\uFF1B\u7528\u6237\u6CA1\u8BF4\u4EC0\u4E48\u65F6\u5019\u5F00\u59CB\u5C31\u522B\u7ED9 --start\uFF08\u4E0D\u8FFD\u95EE\u3001\u4E0D\u731C\uFF09\uFF0C\u5F00\u59CB\u4E0D\u80FD\u665A\u4E8E\u622A\u6B62\u3002\u6765\u6E90\u5BF9\u8BDD\u81EA\u52A8\u53D6 $OASIS_CHAT_SESSION_ID\uFF08\u63D0\u9192\u70B9\u5F00\u4F1A\u8DF3\u56DE\u8FD9\u91CC\uFF09\u3002\u7ED9\u81EA\u5DF1\u8BB0\uFF1A\u6210\u529F\u8F93\u51FA\u300C\u8BB0\u4E0B\u4E86\uFF1A<\u6807\u9898>\uFF0C\u622A\u6B62 X \u6708 X \u65E5\uFF08\u5468X\uFF09\u300D\u3002--to \u6D3E\u7ED9\u522B\u4EBA\uFF1A\u53EA\u5B58\u6210**\u8349\u6848**\uFF0C\u8F93\u51FA\u300C\u8349\u6848\uFF08\u8FD8\u6CA1\u53D1\u51FA\uFF09\uFF1A\u6D3E\u7ED9 X\uFF1A\u2026\u300D\uFF0C\u5BF9\u8BDD\u91CC\u51FA\u4E00\u5F20\u8349\u6848\u5361\uFF0C\u7528\u6237\u70B9\u300C\u53D1\u51FA\u300D\u624D\u751F\u6548\u3001\u5BF9\u65B9\u624D\u6536\u5230\u901A\u77E5\u2014\u2014\u4F60\u4E0D\u80FD\u66FF TA \u53D1\u51FA\u3002--to \u8BA4 actorId \u6216\u540D\u5B57\uFF0C\u5BF9\u4E0D\u4E0A\u6216\u5BF9\u4E0A\u4E0D\u6B62\u4E00\u4E2A\u76F4\u63A5\u62A5\u9519\uFF0C\u522B\u731C\uFF0C\u95EE\u7528\u6237\u662F\u54EA\u4F4D\u3002",
|
|
340083
|
+
description: "\u8BB0\u4E00\u6761\u5F85\u529E\u3002--due / --start \u53EA\u6536\u4E0D\u5E26\u65F6\u533A\u7684\u65E5\u671F\uFF08\u7EC4\u7EC7\u65F6\u533A\u91CC\u7684\u90A3\u4E00\u5929\uFF09\uFF0C\u975E\u6CD5\u65E5\u671F\u5F53\u573A\u62A5\u9519\uFF1B\u6CA1\u8BF4\u51E0\u70B9\u5C31\u522B\u7ED9 --time\uFF1B\u7528\u6237\u6CA1\u8BF4\u4EC0\u4E48\u65F6\u5019\u5F00\u59CB\u5C31\u522B\u7ED9 --start\uFF08\u4E0D\u8FFD\u95EE\u3001\u4E0D\u731C\uFF09\uFF0C\u5F00\u59CB\u4E0D\u80FD\u665A\u4E8E\u622A\u6B62\u3002\u6765\u6E90\u5BF9\u8BDD\u81EA\u52A8\u53D6 $OASIS_CHAT_SESSION_ID\uFF08\u63D0\u9192\u70B9\u5F00\u4F1A\u8DF3\u56DE\u8FD9\u91CC\uFF09\u3002\u7ED9\u81EA\u5DF1\u8BB0\uFF1A\u6210\u529F\u8F93\u51FA\u300C\u8BB0\u4E0B\u4E86\uFF1A<\u6807\u9898>\uFF0C\u622A\u6B62 X \u6708 X \u65E5\uFF08\u5468X\uFF09\u300D\u3002--to \u6D3E\u7ED9\u522B\u4EBA\uFF1A\u53EA\u5B58\u6210**\u8349\u6848**\uFF0C\u8F93\u51FA\u300C\u8349\u6848\uFF08\u8FD8\u6CA1\u53D1\u51FA\uFF09\uFF1A\u6D3E\u7ED9 X\uFF1A\u2026\u300D\uFF0C\u5BF9\u8BDD\u91CC\u51FA\u4E00\u5F20\u8349\u6848\u5361\uFF0C\u7528\u6237\u70B9\u300C\u53D1\u51FA\u300D\u624D\u751F\u6548\u3001\u5BF9\u65B9\u624D\u6536\u5230\u901A\u77E5\u2014\u2014\u4F60\u4E0D\u80FD\u66FF TA \u53D1\u51FA\u3002--to \u8BA4 actorId \u6216\u540D\u5B57\uFF0C\u5BF9\u4E0D\u4E0A\u6216\u5BF9\u4E0A\u4E0D\u6B62\u4E00\u4E2A\u76F4\u63A5\u62A5\u9519\uFF0C\u522B\u731C\uFF0C\u95EE\u7528\u6237\u662F\u54EA\u4F4D\u3002\u6210\u529F\u540E\u5982\u679C\u672C\u516C\u53F8\u6709\u4EBA\u5728\u505A\u6216\u505A\u8FC7\u76F8\u8FD1\u7684\u4E8B\uFF0C\u8F93\u51FA\u672B\u5C3E\u4F1A\u591A\u4E00\u6BB5\u300C\u76F8\u8FD1\u7684\u4E8B\u9879\uFF08\u7CFB\u7EDF\u7C97\u7B5B\uFF0C\u672A\u786E\u8BA4\uFF0C\u8BF7\u7528 id \u67E5\u8BE6\u60C5\u540E\u5224\u65AD\uFF09\u300D\uFF0C\u6BCF\u6761\u5E26 id\u2014\u2014\u9010\u6761\u67E5\u8BE6\u60C5\u518D\u5224\u65AD\u662F\u4E0D\u662F\u540C\u4E00\u4EF6\u4E8B\uFF0C\u786E\u5B9E\u76F8\u5173\u624D\u544A\u8BC9\u7528\u6237\uFF08\u89C1\u6280\u80FD\uFF09\uFF1B\u6CA1\u6709\u8FD9\u4E00\u6BB5\u5C31\u662F\u6CA1\u6BD4\u51FA\u6765\uFF0C\u6BD4\u5BF9\u51FA\u4E86\u95EE\u9898\u4E5F\u53EA\u662F\u6CA1\u6709\u8FD9\u4E00\u6BB5\uFF0C\u547D\u4EE4\u7167\u6837\u7B97\u6210\u529F\u3002",
|
|
339412
340084
|
flags: [
|
|
339413
340085
|
{ name: "to", desc: "\u6D3E\u7ED9\u8C01\uFF1A\u672C\u516C\u53F8\u771F\u4EBA\u7684 actorId \u6216\u540D\u5B57\uFF08\u4E0D\u7ED9 = \u7ED9\u81EA\u5DF1\u8BB0\uFF09", own: true },
|
|
339414
340086
|
{ name: "title", desc: "\u6807\u9898\uFF1A\u4E00\u53E5\u8BDD\u3001\u52A8\u8BCD\u5F00\u5934", required: true, own: true },
|
|
@@ -339439,13 +340111,13 @@ var COMMAND_DECLS = {
|
|
|
339439
340111
|
"todo show": {
|
|
339440
340112
|
group: "\u4E2A\u4EBA\u5F85\u529E",
|
|
339441
340113
|
usage: "oasis todo show <id>",
|
|
339442
|
-
description: "\u770B\u4E00\u6761\u5F85\u529E\u7684\u5168\u8C8C\uFF1A\u6807\u9898\u3001\u5F00\u59CB \u2192 \u622A\u6B62\u3001\u72B6\u6001\u3001\u53D1\u8D77\u4EBA\u3001\u627F\u63A5\u4EBA\uFF08\u6D3E\u7ED9\u522B\u4EBA\u7684\u8FD8\u6709\u53D1\u51FA\u65F6\u95F4\u3001\u627F\u63A5\u4EBA\u9996\u6B21\u67E5\u770B\u65F6\u95F4\uFF09\u3001\u5907\u6CE8\u5168\u6587\uFF0C\u4EE5\u53CA\u53D8\u66F4\u8BB0\u5F55\uFF08\u65F6\u95F4\u3001\u8C01\u6539\u7684 / \u7ECF\u624B agent\u3001\u5B57\u6BB5\u3001\u65E7\u503C \u2192 \u65B0\u503C\u3001\u539F\u56E0\uFF0C\u65B0\u7684\u5728\u524D\uFF09\u3002\u6539\u5907\u6CE8\u524D\u5148\u7528\u5B83\u8BFB\u51FA\u5F53\u524D\u5907\u6CE8\u5168\u6587\uFF1B\u7528\u6237\u95EE\u300C\u4E4B\u524D\u5199\u7684\u662F\u4EC0\u4E48\u300D\u4E5F\u67E5\u8FD9\u91CC\u3002\u672C\u516C\u53F8\u8C01\u7684\u5F85\u529E\u90FD\u80FD\u770B\uFF08\u522B\u4EBA\u7684\u8349\u6848\u9664\u5916\uFF09\uFF1B\u627F\u63A5\u4EBA\u7B2C\u4E00\u6B21\u770B\u4F1A\u88AB\u8BB0\u4E0B\u3002",
|
|
340114
|
+
description: "\u770B\u4E00\u6761\u5F85\u529E\u7684\u5168\u8C8C\uFF1A\u6807\u9898\u3001\u5F00\u59CB \u2192 \u622A\u6B62\u3001\u72B6\u6001\u3001\u53D1\u8D77\u4EBA\u3001\u627F\u63A5\u4EBA\uFF08\u6D3E\u7ED9\u522B\u4EBA\u7684\u8FD8\u6709\u53D1\u51FA\u65F6\u95F4\u3001\u627F\u63A5\u4EBA\u9996\u6B21\u67E5\u770B\u65F6\u95F4\uFF09\u3001\u7ED3\u679C\u5728\u54EA\uFF08\u5B8C\u6210\u65F6\u8BB0\u4E86\u7684\uFF09\u3001\u5907\u6CE8\u5168\u6587\uFF0C\u4EE5\u53CA\u53D8\u66F4\u8BB0\u5F55\uFF08\u65F6\u95F4\u3001\u8C01\u6539\u7684 / \u7ECF\u624B agent\u3001\u5B57\u6BB5\u3001\u65E7\u503C \u2192 \u65B0\u503C\u3001\u539F\u56E0\uFF0C\u65B0\u7684\u5728\u524D\uFF09\u3002\u6539\u5907\u6CE8\u524D\u5148\u7528\u5B83\u8BFB\u51FA\u5F53\u524D\u5907\u6CE8\u5168\u6587\uFF1B\u7528\u6237\u95EE\u300C\u4E4B\u524D\u5199\u7684\u662F\u4EC0\u4E48\u300D\u4E5F\u67E5\u8FD9\u91CC\u3002\u672C\u516C\u53F8\u8C01\u7684\u5F85\u529E\u90FD\u80FD\u770B\uFF08\u522B\u4EBA\u7684\u8349\u6848\u9664\u5916\uFF09\uFF1B\u627F\u63A5\u4EBA\u7B2C\u4E00\u6B21\u770B\u4F1A\u88AB\u8BB0\u4E0B\u3002",
|
|
339443
340115
|
positional: [{ name: "<id>", required: true, desc: "\u5F85\u529E id\uFF08oasis todo list \u7B2C\u4E00\u5217\uFF09" }],
|
|
339444
340116
|
examples: ["oasis todo show td_3f9a1c2b"]
|
|
339445
340117
|
},
|
|
339446
340118
|
"todo edit": {
|
|
339447
340119
|
group: "\u4E2A\u4EBA\u5F85\u529E",
|
|
339448
|
-
usage: "oasis todo edit <id> [--title \u2026] [--note \u2026] [--start YYYY-MM-DD|none] [--start-time HH:mm|none] [--due YYYY-MM-DD] [--time HH:mm|none] [--workorder <\u5DE5\u5355 id>|none] [--to <\u4EBA>] [--reason \u2026]",
|
|
340120
|
+
usage: "oasis todo edit <id> [--title \u2026] [--note \u2026] [--start YYYY-MM-DD|none] [--start-time HH:mm|none] [--due YYYY-MM-DD] [--time HH:mm|none] [--workorder <\u5DE5\u5355 id>|none] [--to <\u4EBA>] [--result <\u7ED3\u679C\u5728\u54EA>|none] [--reason \u2026]",
|
|
339449
340121
|
description: '\u6539\u4E00\u6761\u5F85\u529E\u7684\u5B57\u6BB5\uFF0C\u7ED9\u4E86\u54EA\u4E2A\u6539\u54EA\u4E2A\uFF1B\u6BCF\u6539\u4E00\u4E2A\u5B57\u6BB5\u90FD\u7559\u4E00\u6761\u8BB0\u5F55\uFF08\u65E7\u503C\u3001\u65B0\u503C\u3001\u539F\u56E0\uFF09\u3002\u53EA\u6709\u53D1\u8D77\u4EBA\u548C\u627F\u63A5\u4EBA\u80FD\u6539\uFF1B\u6D3E\u7ED9\u522B\u4EBA\u4E14\u5DF2\u53D1\u51FA\u7684\uFF0C\u6539\u4E86\u4F1A\u901A\u77E5\u53E6\u4E00\u65B9\u3002\u6539\u671F\u8981\u5199\u539F\u56E0\uFF1A\u7528\u6237\u6CA1\u8BF4\u5C31\u95EE\u4E00\u53E5\uFF1B**\u522B\u4EBA\u6D3E\u7ED9\u4F60\u7684\u6539\u622A\u6B62\u5FC5\u987B\u5E26 --reason**\uFF08\u4E0D\u5E26\u76F4\u63A5\u62A5\u9519\uFF09\uFF0C\u81EA\u5DF1\u8BB0\u7684\u7528\u6237\u8BF4\u4E0D\u7528\u5C31\u4E0D\u5199\uFF0C\u522B\u7F16\u3002--to \u53EA\u80FD\u5728\u8FD8\u6CA1\u53D1\u51FA\u7684\u8349\u6848\u4E0A\u6362\u627F\u63A5\u4EBA\u3002--start none\uFF08\u8FDE\u540C\u5F00\u59CB\u65F6\u523B\uFF09/ --start-time none / --time none / --workorder none \u6E05\u7A7A\uFF0C--note "" \u6E05\u7A7A\u5907\u6CE8\u3002',
|
|
339450
340122
|
positional: [{ name: "<id>", required: true, desc: "\u5F85\u529E id\uFF08oasis todo list \u7B2C\u4E00\u5217\uFF09" }],
|
|
339451
340123
|
flags: [
|
|
@@ -339457,16 +340129,21 @@ var COMMAND_DECLS = {
|
|
|
339457
340129
|
{ name: "time", desc: "\u65B0\u622A\u6B62\u65F6\u523B HH:mm\uFF1Bnone = \u6E05\u7A7A", own: true },
|
|
339458
340130
|
{ name: "workorder", desc: "\u5173\u8054\u7684\u5DE5\u5355 id\uFF08\u300C\u8FD9\u4EF6\u4F60\u5E2E\u6211\u505A\u4E86\u5427\u300D\u5EFA\u5355\u540E\u6302\u4E0A\uFF09\uFF1Bnone = \u6E05\u7A7A", own: true },
|
|
339459
340131
|
{ name: "to", desc: "\u6362\u627F\u63A5\u4EBA\uFF08\u53EA\u9650\u8FD8\u6CA1\u53D1\u51FA\u7684\u8349\u6848\uFF09", own: true },
|
|
340132
|
+
{ name: "result", desc: "\u7ED3\u679C\u5728\u54EA\uFF08\u6587\u4EF6 / \u94FE\u63A5 / \u5DE5\u5355 id\uFF09\uFF1A\u8865\u8BB0\u6216\u6539\u6B63\u5B8C\u6210\u65F6\u8BB0\u7684\u90A3\u53E5\uFF1Bnone = \u6E05\u7A7A", own: true },
|
|
339460
340133
|
{ name: "reason", desc: "\u4E3A\u4EC0\u4E48\u6539\uFF08\u6539\u671F\u65F6\u8981\u5199\uFF1B\u522B\u4EBA\u6D3E\u7ED9\u4F60\u7684\u6539\u622A\u6B62\u5FC5\u987B\u5199\uFF09", own: true }
|
|
339461
340134
|
],
|
|
339462
340135
|
examples: ['oasis todo edit td_3f9a1c2b --due 2026-10-12 --reason "\u5BA2\u6237\u5EF6\u671F\u4E00\u5468"']
|
|
339463
340136
|
},
|
|
339464
340137
|
"todo done": {
|
|
339465
340138
|
group: "\u4E2A\u4EBA\u5F85\u529E",
|
|
339466
|
-
usage: "oasis todo done <id> [--reason \u2026]",
|
|
339467
|
-
description: "\u6807\u8BB0\u5B8C\u6210\u3002\u5339\u914D\u5230\u591A\u6761\u65F6\u5148\u95EE\u7528\u6237\u662F\u54EA\u6761\uFF0C\u522B\u731C\u3002\u6D3E\u7ED9\u522B\u4EBA\u4E14\u5DF2\u53D1\u51FA\u7684\uFF0C\u5B8C\u6210\u540E\u901A\u77E5\u53E6\u4E00\u65B9\u3002",
|
|
340139
|
+
usage: "oasis todo done <id> [--result <\u6587\u4EF6 / \u94FE\u63A5 / \u5DE5\u5355 id>] [--reason \u2026]",
|
|
340140
|
+
description: "\u6807\u8BB0\u5B8C\u6210\u3002\u5339\u914D\u5230\u591A\u6761\u65F6\u5148\u95EE\u7528\u6237\u662F\u54EA\u6761\uFF0C\u522B\u731C\u3002\u6807\u4E4B\u524D\u987A\u53E3\u95EE\u4E00\u53E5\u300C\u7ED3\u679C\u5728\u54EA\uFF1F\u300D\uFF0C\u7528\u6237\u8BF4\u4E86\u5C31 --result \u8BB0\u4E0B\uFF08\u540C\u4E8B\u4EE5\u540E\u505A\u7C7B\u4F3C\u7684\u4E8B\uFF0C\u6BD4\u5BF9\u4F1A\u628A\u5B83\u5E26\u51FA\u6765\uFF09\uFF1B\u7528\u6237\u8BF4\u6CA1\u6709\u3001\u4E0D\u7528\u8BB0\u5C31\u4E0D\u7ED9 --result\uFF0C\u522B\u8FFD\u95EE\u3001\u522B\u7F16\u3002\u6D3E\u7ED9\u522B\u4EBA\u4E14\u5DF2\u53D1\u51FA\u7684\uFF0C\u5B8C\u6210\u540E\u901A\u77E5\u53E6\u4E00\u65B9\u3002",
|
|
339468
340141
|
positional: [{ name: "<id>", required: true, desc: "\u5F85\u529E id" }],
|
|
339469
|
-
flags: [
|
|
340142
|
+
flags: [
|
|
340143
|
+
{ name: "result", desc: "\u7ED3\u679C\u5728\u54EA\uFF1A\u6587\u4EF6\u8DEF\u5F84\u3001\u94FE\u63A5\u6216\u5DE5\u5355 id\uFF08\u53EF\u9009\uFF1B\u4E4B\u540E\u8981\u6539\u7528 todo edit --result\uFF09", own: true },
|
|
340144
|
+
{ name: "reason", desc: "\u5907\u6CE8\u4E00\u53E5\uFF08\u53EF\u9009\uFF09", own: true }
|
|
340145
|
+
],
|
|
340146
|
+
examples: ['oasis todo done td_3f9a1c2b --result "outputs/\u7ADE\u54C1\u62A5\u4EF7.xlsx"', "oasis todo done td_3f9a1c2b"]
|
|
339470
340147
|
},
|
|
339471
340148
|
"todo cancel": {
|
|
339472
340149
|
group: "\u4E2A\u4EBA\u5F85\u529E",
|
|
@@ -339677,13 +340354,13 @@ function ownFlagsFromDecl(command6) {
|
|
|
339677
340354
|
}
|
|
339678
340355
|
|
|
339679
340356
|
// ../cli/src/connector-effect-runner.ts
|
|
339680
|
-
var
|
|
340357
|
+
var import_node_crypto109 = require("node:crypto");
|
|
339681
340358
|
var import_node_child_process21 = require("node:child_process");
|
|
339682
340359
|
init_src3();
|
|
339683
340360
|
function stableKey(effect) {
|
|
339684
340361
|
const keyFields = Object.fromEntries(Object.entries(effect.keyFields).sort(([a5], [b6]) => a5.localeCompare(b6)));
|
|
339685
340362
|
const canonical2 = JSON.stringify({ kind: effect.kind, target: effect.target, keyFields });
|
|
339686
|
-
return `sha256:${(0,
|
|
340363
|
+
return `sha256:${(0, import_node_crypto109.createHash)("sha256").update(canonical2).digest("hex")}`;
|
|
339687
340364
|
}
|
|
339688
340365
|
async function runConnectorEffect(connector, toolArgs, deps) {
|
|
339689
340366
|
const effect = connector.describeExternalEffect?.(toolArgs) ?? null;
|
|
@@ -340169,6 +340846,8 @@ var ApiRequestError = class extends Error {
|
|
|
340169
340846
|
this.name = "ApiRequestError";
|
|
340170
340847
|
}
|
|
340171
340848
|
};
|
|
340849
|
+
var OVERLAP_TIMEOUT_MS = 5e3;
|
|
340850
|
+
var DELEGATION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
340172
340851
|
var CHAT_HISTORY_SPEAKER = { user: "\u7528\u6237", assistant: "\u52A9\u624B", system: "\u7CFB\u7EDF" };
|
|
340173
340852
|
function renderChatHistory(view, search2) {
|
|
340174
340853
|
const lines = [];
|
|
@@ -340252,7 +340931,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback2) {
|
|
|
340252
340931
|
const timeoutMs = resolveAuthWaitMs();
|
|
340253
340932
|
const controller = new AbortController();
|
|
340254
340933
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
340255
|
-
const waiterId = (0,
|
|
340934
|
+
const waiterId = (0, import_node_crypto110.randomUUID)();
|
|
340256
340935
|
process.stderr.write(
|
|
340257
340936
|
`\u7B49\u5F85\u4EBA\u5DE5\u6388\u6743\u4E2D\u2026\u2026\u6700\u591A ${Math.round(timeoutMs / 1e3)} \u79D2\uFF0C\u8D85\u65F6\u4F1A\u81EA\u52A8\u8F6C\u4E3A\u5F85\u5BA1\uFF1B\u8FD9\u4E0D\u662F\u9519\u8BEF\uFF0C\u8BF7\u52FF\u91CD\u8BD5\u540C\u4E00\u6761\u547D\u4EE4\u3002
|
|
340258
340937
|
`
|
|
@@ -340336,7 +341015,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback2) {
|
|
|
340336
341015
|
}
|
|
340337
341016
|
}
|
|
340338
341017
|
}
|
|
340339
|
-
var CLI_VERSION = "2.2.
|
|
341018
|
+
var CLI_VERSION = "2.2.123" ? "2.2.123" : "dev";
|
|
340340
341019
|
function apiHeaders(token2, company) {
|
|
340341
341020
|
const headers = {
|
|
340342
341021
|
authorization: `Bearer ${token2}`,
|
|
@@ -340380,11 +341059,12 @@ function makeClient(base, token2, opts = {}) {
|
|
|
340380
341059
|
if (!res.ok) await fail(res);
|
|
340381
341060
|
return (await res.json()).data;
|
|
340382
341061
|
},
|
|
340383
|
-
async request(method, path50, body2) {
|
|
341062
|
+
async request(method, path50, body2, opts2) {
|
|
340384
341063
|
const res = await fetch(`${base}${path50}`, {
|
|
340385
341064
|
method,
|
|
340386
341065
|
headers,
|
|
340387
|
-
...body2 !== void 0 ? { body: JSON.stringify(body2) } : {}
|
|
341066
|
+
...body2 !== void 0 ? { body: JSON.stringify(body2) } : {},
|
|
341067
|
+
...opts2?.timeoutMs ? { signal: AbortSignal.timeout(opts2.timeoutMs) } : {}
|
|
340388
341068
|
});
|
|
340389
341069
|
if (!res.ok) await fail(res);
|
|
340390
341070
|
if (res.status === 204) return void 0;
|
|
@@ -340426,7 +341106,7 @@ function fieldsFromFlags(flags, ownFlags) {
|
|
|
340426
341106
|
}
|
|
340427
341107
|
return Object.keys(fields).length > 0 ? fields : void 0;
|
|
340428
341108
|
}
|
|
340429
|
-
function buildStageOp(cmd, flags, positional,
|
|
341109
|
+
function buildStageOp(cmd, flags, positional, readFile16 = (file) => fs48.readFileSync(file, "utf8")) {
|
|
340430
341110
|
switch (cmd) {
|
|
340431
341111
|
case "link":
|
|
340432
341112
|
return {
|
|
@@ -340448,7 +341128,7 @@ function buildStageOp(cmd, flags, positional, readFile15 = (file) => fs48.readFi
|
|
|
340448
341128
|
...flags.get("title") !== void 0 ? { title: flags.get("title") } : {},
|
|
340449
341129
|
...(flags.get("brief") ?? flags.get("description")) !== void 0 ? { description: flags.get("brief") ?? flags.get("description") } : {},
|
|
340450
341130
|
...flags.get("input") !== void 0 ? { inputs: flags.get("input").split(",").map((to) => ({ to: to.trim() })) } : {},
|
|
340451
|
-
...partsFile !== void 0 ? { parts: JSON.parse(
|
|
341131
|
+
...partsFile !== void 0 ? { parts: JSON.parse(readFile16(partsFile)) } : {},
|
|
340452
341132
|
...fields !== void 0 ? { fields } : {}
|
|
340453
341133
|
};
|
|
340454
341134
|
}
|
|
@@ -340727,7 +341407,7 @@ async function runCli(argv, println = console.log, progressln = console.error) {
|
|
|
340727
341407
|
const store = createNodeTokenStore(path42.join(dir, "node-tokens.json"));
|
|
340728
341408
|
const sub = positional[0];
|
|
340729
341409
|
if (sub === "issue") {
|
|
340730
|
-
const id = flags.get("id") ?? `node-${(0,
|
|
341410
|
+
const id = flags.get("id") ?? `node-${(0, import_node_crypto110.randomUUID)()}`;
|
|
340731
341411
|
const token3 = store.issue(id);
|
|
340732
341412
|
println(token3);
|
|
340733
341413
|
process.stderr.write(
|
|
@@ -340966,6 +341646,21 @@ async function runCli(argv, println = console.log, progressln = console.error) {
|
|
|
340966
341646
|
if (!graph) return;
|
|
340967
341647
|
for (const line2 of renderGraphLines(graph)) println(line2);
|
|
340968
341648
|
};
|
|
341649
|
+
const printOverlap = async (action, text7, subjectId) => {
|
|
341650
|
+
if (!text7.trim()) return;
|
|
341651
|
+
try {
|
|
341652
|
+
const chatSessionId = process.env["OASIS_CHAT_SESSION_ID"];
|
|
341653
|
+
const r5 = await api.request("POST", "/api/overlap/candidates", {
|
|
341654
|
+
action,
|
|
341655
|
+
text: text7,
|
|
341656
|
+
...subjectId ? { subjectId } : {},
|
|
341657
|
+
...chatSessionId ? { chatSessionId } : {}
|
|
341658
|
+
}, { timeoutMs: OVERLAP_TIMEOUT_MS });
|
|
341659
|
+
if (!r5?.enabled) return;
|
|
341660
|
+
for (const line2 of formatOverlapLines(r5, r5.timeZone)) println(line2);
|
|
341661
|
+
} catch {
|
|
341662
|
+
}
|
|
341663
|
+
};
|
|
340969
341664
|
if (process.env["OASIS_STAGE"] === "1" && STAGE_COMMANDS.has(command6)) {
|
|
340970
341665
|
const op2 = buildStageOp(command6, flags, positional, readFileArg);
|
|
340971
341666
|
const editWs = flags.get("workspace") ?? process.env["OASIS_WORKSPACE"];
|
|
@@ -341043,7 +341738,32 @@ async function runCli(argv, println = console.log, progressln = console.error) {
|
|
|
341043
341738
|
const statusRef = flags.get("status");
|
|
341044
341739
|
if (statusRef !== void 0) {
|
|
341045
341740
|
if (statusRef === "true") throw new Error("--status \u8981\u8DDF\u4E00\u4E2A\u5F15\u7528\uFF1Alabel / \u4E13\u5BB6\u540D / delegationId \u524D\u7F00");
|
|
341046
|
-
|
|
341741
|
+
let target;
|
|
341742
|
+
try {
|
|
341743
|
+
target = await resolveRef2(statusRef);
|
|
341744
|
+
} catch (error3) {
|
|
341745
|
+
const ref2 = statusRef.trim();
|
|
341746
|
+
if (!DELEGATION_ID_RE.test(ref2)) throw error3;
|
|
341747
|
+
const summary = await api.request("GET", `/api/delegations/${encodeURIComponent(ref2)}/summary`);
|
|
341748
|
+
if (asJson2) {
|
|
341749
|
+
println(JSON.stringify(summary, null, 2));
|
|
341750
|
+
break;
|
|
341751
|
+
}
|
|
341752
|
+
println("\uFF08\u8FD9\u6761\u4E0D\u662F\u672C\u6BB5\u5BF9\u8BDD\u6D3E\u51FA\u7684\u59D4\u6D3E\u2014\u2014\u4EE5\u4E0B\u662F\u53EA\u8BFB\u6458\u8981\uFF0C\u4E0D\u542B\u5B50\u4F1A\u8BDD\u8FC7\u7A0B\uFF1B--follow-up \u53EA\u6709\u6D3E\u6D3B\u7684\u90A3\u6BB5\u5BF9\u8BDD\u80FD\u7528\u3002\uFF09");
|
|
341753
|
+
println(`${summary.label ?? "(\u65E0\u77ED\u540D)"} ${summary.expertName ?? summary.expertActorId} ${summary.state}${summary.failureKind ? `/${summary.failureKind}` : ""}`);
|
|
341754
|
+
println(`id=${summary.id} \u5B50\u4F1A\u8BDD=${summary.childSessionId} \u6D3E\u6D3B\u5BF9\u8BDD=${summary.parentSessionId} \u6D3E\u6D3B\u4EBA=${summary.delegatorName ?? summary.delegatorActorId ?? "\uFF08\u672A\u77E5\uFF09"}`);
|
|
341755
|
+
println(`\u6D3E\u51FA\uFF1A${summary.createdAt}${summary.settledAt ? ` \u4EA4\u56DE\uFF1A${summary.settledAt}` : ""}`);
|
|
341756
|
+
println(`\u4EFB\u52A1\u4E66${summary.taskTruncated ? "\uFF08\u53EA\u6709\u9996\u53E5\u6458\u8981\uFF09" : ""}\uFF1A`);
|
|
341757
|
+
println(summary.task || "\uFF08\u7A7A\uFF09");
|
|
341758
|
+
for (const round of summary.rounds) println(`
|
|
341759
|
+
\u7B2C ${round.round} \u8F6E\uFF08${round.at}\uFF09\uFF1A
|
|
341760
|
+
${round.text}`);
|
|
341761
|
+
if (summary.artifacts.length > 0) {
|
|
341762
|
+
println("\n\u4EA7\u51FA\uFF1A");
|
|
341763
|
+
for (const name of summary.artifacts) println(` ${name}`);
|
|
341764
|
+
}
|
|
341765
|
+
break;
|
|
341766
|
+
}
|
|
341047
341767
|
const detail = await api.request("GET", `/api/delegations/${encodeURIComponent(target.id)}`);
|
|
341048
341768
|
if (asJson2) {
|
|
341049
341769
|
println(JSON.stringify(detail, null, 2));
|
|
@@ -341075,17 +341795,17 @@ ${round.text}`);
|
|
|
341075
341795
|
println(JSON.stringify({ delegationId: target.id, label: target.label, files: fileArgs, ...outcome }, null, 2));
|
|
341076
341796
|
break;
|
|
341077
341797
|
}
|
|
341078
|
-
const
|
|
341798
|
+
const who2 = `${target.expertName ?? target.expertActorId}\uFF08${target.label ?? target.id.slice(0, 8)}\uFF09`;
|
|
341079
341799
|
if (outcome?.outcome === "inserted") {
|
|
341080
|
-
println(`\u5DF2\u63D2\u8FDB ${
|
|
341800
|
+
println(`\u5DF2\u63D2\u8FDB ${who2} \u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E\u2014\u2014\u5B83\u628A\u5F53\u524D\u8FD9\u4E00\u6B65\u7B54\u5B8C\u5C31\u4F1A\u770B\u5230\u3002`);
|
|
341081
341801
|
} else if (outcome?.outcome === "started-round") {
|
|
341082
|
-
println(`\u5DF2\u8F6C\u8FBE\u7ED9 ${
|
|
341802
|
+
println(`\u5DF2\u8F6C\u8FBE\u7ED9 ${who2}\uFF1A\u5B83\u4E0A\u4E00\u8F6E\u5DF2\u7ECF\u7ED3\u675F\uFF0C\u8FD9\u53E5\u8BDD\u5F53\u573A\u8D77\u4E86\u65B0\u7684\u4E00\u8F6E\u3002`);
|
|
341083
341803
|
} else if (outcome?.outcome === "queued") {
|
|
341084
|
-
println(`\u5DF2\u6536\u4E0B\uFF0C\u4F46${
|
|
341804
|
+
println(`\u5DF2\u6536\u4E0B\uFF0C\u4F46${who2}**\u73B0\u5728\u8FD8\u770B\u4E0D\u5230**\uFF1A${outcome.reason ?? "\u63D2\u4E0D\u8FDB\u6B63\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E"}\u3002`);
|
|
341085
341805
|
println(` \u8FD9\u53E5\u8BDD\u6392\u5728\u5F85\u8F6C\u8FBE\u961F\u5217\u91CC\uFF08\u8FD8\u6709 ${outcome.pendingInputs} \u53E5\u6CA1\u9001\u5230\uFF09\uFF0C\u672C\u8F6E\u8DD1\u5B8C\u4F1A\u4F5C\u4E3A\u4E0B\u4E00\u8F6E\u53D1\u51FA\u3002`);
|
|
341086
341806
|
println(" \u5B83\u8FD9\u4E00\u8F6E\u53EF\u80FD\u8FD8\u5728\u6309\u65E7\u65B9\u5411\u505A\u2014\u2014\u8981\u4E0D\u8981\u5728\u8FD9\u6761\u5BF9\u8BDD\u91CC\u5148\u8DDF\u7528\u6237\u8BF4\u660E\uFF0C\u4F60\u81EA\u5DF1\u5224\u65AD\u3002");
|
|
341087
341807
|
} else {
|
|
341088
|
-
println(`\u5DF2\u8F6C\u8FBE\u7ED9 ${
|
|
341808
|
+
println(`\u5DF2\u8F6C\u8FBE\u7ED9 ${who2}\u3002`);
|
|
341089
341809
|
}
|
|
341090
341810
|
if (fileArgs.length) println(` \u4E00\u8D77\u5E26\u8FC7\u53BB\u7684\u6587\u4EF6\uFF1A${fileArgs.join("\u3001")}`);
|
|
341091
341811
|
println("\u8FD9\u4E00\u8F6E\u5230\u6B64\u4E3A\u6B62\uFF1A\u7ED3\u679C\u4F1A\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\uFF0C\u4E0D\u8981\u5728\u8FD9\u91CC\u7B49\u3002");
|
|
@@ -341106,6 +341826,7 @@ ${round.text}`);
|
|
|
341106
341826
|
println(` delegationId\uFF1A${started.delegationId}`);
|
|
341107
341827
|
if (started.attachedFiles?.length) println(` \u5E26\u8FC7\u53BB\u7684\u6587\u4EF6\uFF1A${started.attachedFiles.join("\u3001")}`);
|
|
341108
341828
|
println("\u7ED3\u679C\u5E72\u5B8C\u4E86\u4F1A\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\u3002\u8FD9\u4E00\u8F6E\u5148\u6536\u5C3E\u2014\u2014\u53EF\u4EE5\u987A\u624B\u8DDF\u7528\u6237\u8BF4\u4E00\u53E5\u4F60\u628A\u8FD9\u4EF6\u4E8B\u6D3E\u51FA\u53BB\u4E86\u3002");
|
|
341829
|
+
await printOverlap("delegate", task, started.delegationId);
|
|
341109
341830
|
break;
|
|
341110
341831
|
}
|
|
341111
341832
|
case "kb": {
|
|
@@ -341420,6 +342141,8 @@ ${p4.ref} ${p4.name}`);
|
|
|
341420
342141
|
}
|
|
341421
342142
|
}
|
|
341422
342143
|
printGraph(graph);
|
|
342144
|
+
await printOverlap("run-playbook", `${title}
|
|
342145
|
+
${description}`, res.workspaceId);
|
|
341423
342146
|
break;
|
|
341424
342147
|
}
|
|
341425
342148
|
/* ---------- 自动化(Automations,ADR 0156):瘦客户端映射 /api/automations ---------- */
|
|
@@ -341654,6 +342377,11 @@ ${t.ref} ${t.name} [\u5267\u672C=${t.playbookRef}]`);
|
|
|
341654
342377
|
printGraph(detail.graph);
|
|
341655
342378
|
}
|
|
341656
342379
|
}
|
|
342380
|
+
await printOverlap(
|
|
342381
|
+
"create-workorder",
|
|
342382
|
+
[title, flags.get("goal"), flags.get("brief")].filter(Boolean).join("\n"),
|
|
342383
|
+
data?.workspace ?? /^planned (.+?): created/.exec(res.message)?.[1] ?? flags.get("workspace")
|
|
342384
|
+
);
|
|
341657
342385
|
break;
|
|
341658
342386
|
}
|
|
341659
342387
|
case "workorders": {
|
|
@@ -341879,7 +342607,7 @@ ${t.ref} ${t.name} [\u5267\u672C=${t.playbookRef}]`);
|
|
|
341879
342607
|
if (!name) throw new Error("\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
341880
342608
|
const goal = flags.get("goal")?.trim();
|
|
341881
342609
|
const slug5 = flags.get("slug");
|
|
341882
|
-
const id = slug5 !== void 0 ? projectSlug(slug5) : projectIdFromUuid((0,
|
|
342610
|
+
const id = slug5 !== void 0 ? projectSlug(slug5) : projectIdFromUuid((0, import_node_crypto110.randomUUID)());
|
|
341883
342611
|
const result = await api.request("POST", "/api/projects", {
|
|
341884
342612
|
...id ? { id } : {},
|
|
341885
342613
|
name,
|
|
@@ -342782,10 +343510,12 @@ ${res.warning}`);
|
|
|
342782
343510
|
println(`\u8349\u6848\uFF08\u8FD8\u6CA1\u53D1\u51FA\uFF09\uFF1A\u6D3E\u7ED9 ${nameIn(r5.names)(r5.todo.assigneeActorId)}\uFF1A${r5.todo.title}\uFF0C${due(r5.todo)}`);
|
|
342783
343511
|
println(`id\uFF1A${r5.todo.id}`);
|
|
342784
343512
|
println("\u5BF9\u8BDD\u91CC\u5DF2\u51FA\u8349\u6848\u5361\uFF1A\u8BF7\u7528\u6237\u6838\u5BF9\u540E\u70B9\u300C\u53D1\u51FA\u300D\u3002\u53D1\u51FA\u524D\u5BF9\u65B9\u770B\u4E0D\u5230\u3001\u4E5F\u6536\u4E0D\u5230\u901A\u77E5\uFF1B\u8981\u6539\u5C31 oasis todo edit \u8FD9\u6761\u8349\u6848\u3002");
|
|
343513
|
+
await printOverlap("todo-add", [title, note].filter(Boolean).join("\n"), r5.todo.id);
|
|
342785
343514
|
break;
|
|
342786
343515
|
}
|
|
342787
343516
|
println(`\u8BB0\u4E0B\u4E86\uFF1A${r5.todo.title}\uFF0C${due(r5.todo)}`);
|
|
342788
343517
|
println(`id\uFF1A${r5.todo.id}`);
|
|
343518
|
+
await printOverlap("todo-add", [title, note].filter(Boolean).join("\n"), r5.todo.id);
|
|
342789
343519
|
break;
|
|
342790
343520
|
}
|
|
342791
343521
|
if (sub === "list") {
|
|
@@ -342843,6 +343573,7 @@ ${res.warning}`);
|
|
|
342843
343573
|
println(`\u627F\u63A5\u4EBA\u9996\u6B21\u67E5\u770B\uFF1A${t.firstViewedAt ? fmtAt(t.firstViewedAt) : "\uFF08\u8FD8\u6CA1\u770B\u8FC7\uFF09"}`);
|
|
342844
343574
|
}
|
|
342845
343575
|
if (t.linkedWorkorderId) println(`\u5DE5\u5355\uFF1A${t.linkedWorkorderId}`);
|
|
343576
|
+
if (t.result) println(`\u7ED3\u679C\u5728\u54EA\uFF1A${t.result}`);
|
|
342846
343577
|
println("\u5907\u6CE8\uFF1A");
|
|
342847
343578
|
println(t.note ? t.note : "\uFF08\u65E0\uFF09");
|
|
342848
343579
|
const FIELD = {
|
|
@@ -342855,16 +343586,17 @@ ${res.warning}`);
|
|
|
342855
343586
|
dueDate: "\u622A\u6B62\u65E5",
|
|
342856
343587
|
dueTime: "\u622A\u6B62\u65F6\u523B",
|
|
342857
343588
|
linkedWorkorderId: "\u5DE5\u5355",
|
|
342858
|
-
assignee: "\u627F\u63A5\u4EBA"
|
|
343589
|
+
assignee: "\u627F\u63A5\u4EBA",
|
|
343590
|
+
result: "\u7ED3\u679C\u5728\u54EA"
|
|
342859
343591
|
};
|
|
342860
343592
|
const STATUS = { draft: "\u8349\u6848", open: "\u672A\u5B8C\u6210", done: "\u5DF2\u5B8C\u6210", cancelled: "\u5DF2\u53D6\u6D88" };
|
|
342861
343593
|
const val = (field, v2) => v2 === void 0 || v2 === "" ? "\uFF08\u7A7A\uFF09" : field === "status" ? STATUS[v2] ?? v2 : field === "assignee" ? nm(v2) : v2;
|
|
342862
343594
|
const changes = [...one2.changes].sort((a5, b6) => b6.at.localeCompare(a5.at));
|
|
342863
343595
|
println(`\u53D8\u66F4\u8BB0\u5F55\uFF08${changes.length} \u6761\uFF0C\u65B0\u7684\u5728\u524D\uFF09\uFF1A`);
|
|
342864
343596
|
for (const c5 of changes) {
|
|
342865
|
-
const
|
|
343597
|
+
const who2 = c5.handActorId ? `${nm(c5.actorId)}\uFF08\u7ECF\u624B ${c5.handActorId}\uFF09` : nm(c5.actorId);
|
|
342866
343598
|
const what = c5.field === "created" ? `\u8BB0\u4E0B\uFF1A${c5.newValue ?? ""}` : c5.field === "sent" ? `\u53D1\u51FA\uFF1A\u6D3E\u7ED9 ${nm(c5.newValue ?? "")}` : `${FIELD[c5.field] ?? c5.field}\uFF1A${val(c5.field, c5.oldValue)} \u2192 ${val(c5.field, c5.newValue)}`;
|
|
342867
|
-
println(`- ${fmtAt(c5.at)} ${
|
|
343599
|
+
println(`- ${fmtAt(c5.at)} ${who2} ${what}${c5.reason ? ` \u539F\u56E0\uFF1A${c5.reason}` : ""}`);
|
|
342868
343600
|
}
|
|
342869
343601
|
break;
|
|
342870
343602
|
}
|
|
@@ -342879,7 +343611,8 @@ ${res.warning}`);
|
|
|
342879
343611
|
if (flags.has("start-time")) body2["startTime"] = flags.get("start-time") === "none" ? null : checkTime(flags.get("start-time"), "start-time");
|
|
342880
343612
|
if (flags.has("workorder")) body2["linkedWorkorderId"] = flags.get("workorder") === "none" ? null : flags.get("workorder");
|
|
342881
343613
|
if (flags.has("to")) body2["assignee"] = flags.get("to");
|
|
342882
|
-
if (
|
|
343614
|
+
if (flags.has("result")) body2["result"] = flags.get("result") === "none" ? null : flags.get("result");
|
|
343615
|
+
if (Object.keys(body2).length === 0) throw new Error("\u6CA1\u6709\u8981\u6539\u7684\u5B57\u6BB5\uFF1A\u7ED9 --title / --note / --start / --start-time / --due / --time / --workorder / --to / --result \u91CC\u7684\u81F3\u5C11\u4E00\u4E2A");
|
|
342883
343616
|
if (flags.get("reason")) body2["reason"] = flags.get("reason");
|
|
342884
343617
|
const r5 = await call("PATCH", todoPath(id), body2);
|
|
342885
343618
|
println(r5.todayLine);
|
|
@@ -342889,9 +343622,13 @@ ${res.warning}`);
|
|
|
342889
343622
|
if (sub === "done" || sub === "cancel" || sub === "reopen") {
|
|
342890
343623
|
const id = idOf();
|
|
342891
343624
|
const reason = flags.get("reason");
|
|
342892
|
-
const
|
|
343625
|
+
const result = flags.get("result");
|
|
343626
|
+
if (result !== void 0 && sub !== "done") throw new Error("--result \u53EA\u914D oasis todo done\uFF1B\u8981\u6539\u7ED3\u679C\u5728\u54EA\u7528 oasis todo edit <id> --result \u2026");
|
|
343627
|
+
if (result !== void 0 && !result.trim()) throw new Error("--result \u8981\u5199\u7ED3\u679C\u5728\u54EA\uFF08\u6587\u4EF6 / \u94FE\u63A5 / \u5DE5\u5355 id\uFF09\uFF1B\u7528\u6237\u8BF4\u4E0D\u7528\u8BB0\u5C31\u522B\u7ED9 --result");
|
|
343628
|
+
const r5 = await call("POST", todoPath(id, `/${sub}`), { ...reason ? { reason } : {}, ...result ? { result } : {} });
|
|
342893
343629
|
println(r5.todayLine);
|
|
342894
343630
|
println(`${sub === "done" ? "\u5DF2\u5B8C\u6210" : sub === "cancel" ? "\u5DF2\u53D6\u6D88" : "\u5DF2\u91CD\u65B0\u6253\u5F00"}\uFF1A${r5.todo.title}\uFF0C${due(r5.todo)}`);
|
|
343631
|
+
if (sub === "done" && r5.todo.result) println(`\u7ED3\u679C\u5728\u54EA\uFF1A${r5.todo.result}`);
|
|
342895
343632
|
break;
|
|
342896
343633
|
}
|
|
342897
343634
|
throw new Error("\u7528\u6CD5: oasis todo <add|list|show|edit|done|cancel|reopen> \u2026\uFF08oasis todo --help \u770B\u8BE6\u60C5\uFF09");
|
|
@@ -344365,7 +345102,14 @@ function syncRuntimeAssets(candidateRoots, binDir) {
|
|
|
344365
345102
|
}
|
|
344366
345103
|
function runtimeAssetSourceRoots(input) {
|
|
344367
345104
|
const roots = [];
|
|
344368
|
-
if (input.executingBundle)
|
|
345105
|
+
if (input.executingBundle) {
|
|
345106
|
+
let bundle = input.executingBundle;
|
|
345107
|
+
try {
|
|
345108
|
+
bundle = fs53.realpathSync(bundle);
|
|
345109
|
+
} catch {
|
|
345110
|
+
}
|
|
345111
|
+
roots.push(path47.dirname(bundle));
|
|
345112
|
+
}
|
|
344369
345113
|
try {
|
|
344370
345114
|
roots.push(fs53.realpathSync(input.currentLink));
|
|
344371
345115
|
} catch {
|
|
@@ -344440,13 +345184,13 @@ async function exchangeEnrollToken(o3) {
|
|
|
344440
345184
|
}
|
|
344441
345185
|
|
|
344442
345186
|
// src/install.ts
|
|
344443
|
-
var
|
|
345187
|
+
var import_node_crypto111 = require("node:crypto");
|
|
344444
345188
|
var fs54 = __toESM(require("node:fs"));
|
|
344445
345189
|
var path48 = __toESM(require("node:path"));
|
|
344446
345190
|
function versionLabel(sourceFile, pkgVersion, npmPrefixDir, pkgName = LEGACY_PKG_NAME) {
|
|
344447
345191
|
const tag = pkgName === LEGACY_PKG_NAME ? "" : `+pkg.${pkgName.replace(/[^A-Za-z0-9-]/g, "-")}`;
|
|
344448
345192
|
if (isFromNpmPrefix(sourceFile, npmPrefixDir)) return `${pkgVersion}${tag}`;
|
|
344449
|
-
const digest3 = (0,
|
|
345193
|
+
const digest3 = (0, import_node_crypto111.createHash)("sha256").update(fs54.readFileSync(sourceFile)).digest("hex").slice(0, 8);
|
|
344450
345194
|
return tag ? `${pkgVersion}${tag}.local.${digest3}` : `${pkgVersion}+local.${digest3}`;
|
|
344451
345195
|
}
|
|
344452
345196
|
function isFromNpmPrefix(sourceFile, npmPrefixDir) {
|
|
@@ -344569,7 +345313,7 @@ function shimScript() {
|
|
|
344569
345313
|
}
|
|
344570
345314
|
|
|
344571
345315
|
// src/index.ts
|
|
344572
|
-
var PKG_VERSION = true ? "2.2.
|
|
345316
|
+
var PKG_VERSION = true ? "2.2.123" : "dev";
|
|
344573
345317
|
var LOCAL_BIN = localBin();
|
|
344574
345318
|
var NPM_PREFIX = npmPrefix();
|
|
344575
345319
|
var INSTANCE = DEFAULT_INSTANCE;
|
|
@@ -344877,7 +345621,7 @@ function newInstanceName() {
|
|
|
344877
345621
|
const existing = new Set(listInstances());
|
|
344878
345622
|
if (!existing.has(DEFAULT_INSTANCE)) return DEFAULT_INSTANCE;
|
|
344879
345623
|
for (; ; ) {
|
|
344880
|
-
const n3 = `inst-${(0,
|
|
345624
|
+
const n3 = `inst-${(0, import_node_crypto112.randomBytes)(3).toString("hex")}`;
|
|
344881
345625
|
if (!existing.has(n3)) return n3;
|
|
344882
345626
|
}
|
|
344883
345627
|
}
|