oasis_test_v2 2.2.92 → 2.2.94
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 +725 -268
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -913,7 +913,7 @@ var init_runtime = __esm({
|
|
|
913
913
|
});
|
|
914
914
|
|
|
915
915
|
// ../contract/src/runtime-allocation.ts
|
|
916
|
-
var RUNTIME_FAULT_RECOVERY, RUNTIME_FAULT_PROBE_INITIAL_MS, RUNTIME_FAULT_PROBE_MAX_INTERVAL_MS, RUNTIME_FAULT_PROBE_MAX_TOTAL_MS, RUNTIME_QUOTA_DERATE_THRESHOLD_PERCENT, RUNTIME_ALLOCATION_MAX_ATTEMPTS;
|
|
916
|
+
var RUNTIME_FAULT_RECOVERY, RUNTIME_FAULT_SCOPE, RUNTIME_FAULT_PROBE_INITIAL_MS, RUNTIME_FAULT_PROBE_MAX_INTERVAL_MS, RUNTIME_FAULT_PROBE_MAX_TOTAL_MS, RUNTIME_QUOTA_DERATE_THRESHOLD_PERCENT, RUNTIME_ALLOCATION_MAX_ATTEMPTS;
|
|
917
917
|
var init_runtime_allocation = __esm({
|
|
918
918
|
"../contract/src/runtime-allocation.ts"() {
|
|
919
919
|
"use strict";
|
|
@@ -928,6 +928,16 @@ var init_runtime_allocation = __esm({
|
|
|
928
928
|
timeout: "half-open",
|
|
929
929
|
"node-error": "half-open"
|
|
930
930
|
};
|
|
931
|
+
RUNTIME_FAULT_SCOPE = {
|
|
932
|
+
"quota-exhausted": "runtime",
|
|
933
|
+
unauthenticated: "runtime",
|
|
934
|
+
"node-offline": "node",
|
|
935
|
+
"runtime-missing": "runtime",
|
|
936
|
+
"startup-failed": "runtime",
|
|
937
|
+
crashed: "runtime",
|
|
938
|
+
timeout: "runtime",
|
|
939
|
+
"node-error": "node"
|
|
940
|
+
};
|
|
931
941
|
RUNTIME_FAULT_PROBE_INITIAL_MS = 6e4;
|
|
932
942
|
RUNTIME_FAULT_PROBE_MAX_INTERVAL_MS = 30 * 6e4;
|
|
933
943
|
RUNTIME_FAULT_PROBE_MAX_TOTAL_MS = 6 * 60 * 6e4;
|
|
@@ -11295,7 +11305,7 @@ async function resolveSessionRuntimeTarget(input) {
|
|
|
11295
11305
|
if (!kinds.includes(override.runtimeKind)) {
|
|
11296
11306
|
throw new SessionRuntimeOverrideError(
|
|
11297
11307
|
"CHAT_SESSION_RUNTIME_UNAVAILABLE",
|
|
11298
|
-
`\
|
|
11308
|
+
`\u673A\u5668\u300C${nodeName}\u300D\u4E0A\u6CA1\u6709\u53EF\u7528\u7684\u8FD0\u884C\u65F6 ${override.runtimeKind}\uFF08\u53EF\u80FD\u5DF2\u5378\u8F7D\u3001\u8FD8\u6CA1\u88C5\u597D\uFF0C\u6216\u8FD8\u6CA1\u68C0\u6D4B\u5230\uFF09\u3002\u8BF7\u5728\u90A3\u53F0\u673A\u5668\u4E0A\u88C5\u597D\u540E\u518D\u53D1\uFF1B\u6216${CLEAR_SESSION_RUNTIME_HINT}`
|
|
11299
11309
|
);
|
|
11300
11310
|
}
|
|
11301
11311
|
if (!probe.binding) {
|
|
@@ -29203,8 +29213,8 @@ var require_axios = __commonJS({
|
|
|
29203
29213
|
};
|
|
29204
29214
|
var DEFAULT_CHUNK_SIZE = 64 * 1024;
|
|
29205
29215
|
var { isFunction } = utils$1;
|
|
29206
|
-
var globalFetchAPI = (({ Request, Response: Response2 }) => ({
|
|
29207
|
-
Request,
|
|
29216
|
+
var globalFetchAPI = (({ Request: Request2, Response: Response2 }) => ({
|
|
29217
|
+
Request: Request2,
|
|
29208
29218
|
Response: Response2
|
|
29209
29219
|
}))(utils$1.global);
|
|
29210
29220
|
var { ReadableStream: ReadableStream$1, TextEncoder: TextEncoder$1 } = utils$1.global;
|
|
@@ -29223,18 +29233,18 @@ var require_axios = __commonJS({
|
|
|
29223
29233
|
globalFetchAPI,
|
|
29224
29234
|
env
|
|
29225
29235
|
);
|
|
29226
|
-
const { fetch: envFetch, Request, Response: Response2 } = env;
|
|
29236
|
+
const { fetch: envFetch, Request: Request2, Response: Response2 } = env;
|
|
29227
29237
|
const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === "function";
|
|
29228
|
-
const isRequestSupported = isFunction(
|
|
29238
|
+
const isRequestSupported = isFunction(Request2);
|
|
29229
29239
|
const isResponseSupported = isFunction(Response2);
|
|
29230
29240
|
if (!isFetchSupported) {
|
|
29231
29241
|
return false;
|
|
29232
29242
|
}
|
|
29233
29243
|
const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1);
|
|
29234
|
-
const encodeText = isFetchSupported && (typeof TextEncoder$1 === "function" ? /* @__PURE__ */ ((encoder) => (str5) => encoder.encode(str5))(new TextEncoder$1()) : async (str5) => new Uint8Array(await new
|
|
29244
|
+
const encodeText = isFetchSupported && (typeof TextEncoder$1 === "function" ? /* @__PURE__ */ ((encoder) => (str5) => encoder.encode(str5))(new TextEncoder$1()) : async (str5) => new Uint8Array(await new Request2(str5).arrayBuffer()));
|
|
29235
29245
|
const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {
|
|
29236
29246
|
let duplexAccessed = false;
|
|
29237
|
-
const hasContentType = new
|
|
29247
|
+
const hasContentType = new Request2(platform2.origin, {
|
|
29238
29248
|
body: new ReadableStream$1(),
|
|
29239
29249
|
method: "POST",
|
|
29240
29250
|
get duplex() {
|
|
@@ -29271,7 +29281,7 @@ var require_axios = __commonJS({
|
|
|
29271
29281
|
return body2.size;
|
|
29272
29282
|
}
|
|
29273
29283
|
if (utils$1.isSpecCompliantForm(body2)) {
|
|
29274
|
-
const _request = new
|
|
29284
|
+
const _request = new Request2(platform2.origin, {
|
|
29275
29285
|
method: "POST",
|
|
29276
29286
|
body: body2
|
|
29277
29287
|
});
|
|
@@ -29319,7 +29329,7 @@ var require_axios = __commonJS({
|
|
|
29319
29329
|
let requestContentLength;
|
|
29320
29330
|
try {
|
|
29321
29331
|
if (onUploadProgress && supportsRequestStream && method !== "get" && method !== "head" && (requestContentLength = await resolveBodyLength(headers, data)) !== 0) {
|
|
29322
|
-
let _request = new
|
|
29332
|
+
let _request = new Request2(url2, {
|
|
29323
29333
|
method: "POST",
|
|
29324
29334
|
body: data,
|
|
29325
29335
|
duplex: "half"
|
|
@@ -29339,7 +29349,7 @@ var require_axios = __commonJS({
|
|
|
29339
29349
|
if (!utils$1.isString(withCredentials)) {
|
|
29340
29350
|
withCredentials = withCredentials ? "include" : "omit";
|
|
29341
29351
|
}
|
|
29342
|
-
const isCredentialsSupported = isRequestSupported && "credentials" in
|
|
29352
|
+
const isCredentialsSupported = isRequestSupported && "credentials" in Request2.prototype;
|
|
29343
29353
|
const resolvedOptions = {
|
|
29344
29354
|
...fetchOptions,
|
|
29345
29355
|
signal: composedSignal,
|
|
@@ -29349,7 +29359,7 @@ var require_axios = __commonJS({
|
|
|
29349
29359
|
duplex: "half",
|
|
29350
29360
|
credentials: isCredentialsSupported ? withCredentials : void 0
|
|
29351
29361
|
};
|
|
29352
|
-
request2 = isRequestSupported && new
|
|
29362
|
+
request2 = isRequestSupported && new Request2(url2, resolvedOptions);
|
|
29353
29363
|
let response = await (isRequestSupported ? _fetch(request2, fetchOptions) : _fetch(url2, resolvedOptions));
|
|
29354
29364
|
const isStreamResponse = supportsResponseStream && (responseType === "stream" || responseType === "response");
|
|
29355
29365
|
if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) {
|
|
@@ -29409,8 +29419,8 @@ var require_axios = __commonJS({
|
|
|
29409
29419
|
var seedCache = /* @__PURE__ */ new Map();
|
|
29410
29420
|
var getFetch = (config2) => {
|
|
29411
29421
|
let env = config2 && config2.env || {};
|
|
29412
|
-
const { fetch: fetch2, Request, Response: Response2 } = env;
|
|
29413
|
-
const seeds = [
|
|
29422
|
+
const { fetch: fetch2, Request: Request2, Response: Response2 } = env;
|
|
29423
|
+
const seeds = [Request2, Response2, fetch2];
|
|
29414
29424
|
let len = seeds.length, i = len, seed, target, map = seedCache;
|
|
29415
29425
|
while (i--) {
|
|
29416
29426
|
seed = seeds[i];
|
|
@@ -133376,9 +133386,9 @@ var require_client = __commonJS({
|
|
|
133376
133386
|
user: params.user,
|
|
133377
133387
|
database: params.database
|
|
133378
133388
|
};
|
|
133379
|
-
const
|
|
133380
|
-
if (
|
|
133381
|
-
data.application_name =
|
|
133389
|
+
const appName2 = params.application_name || params.fallback_application_name;
|
|
133390
|
+
if (appName2) {
|
|
133391
|
+
data.application_name = appName2;
|
|
133382
133392
|
}
|
|
133383
133393
|
if (params.replication) {
|
|
133384
133394
|
data.replication = "" + params.replication;
|
|
@@ -146147,12 +146157,12 @@ var init_kernel_bridge = __esm({
|
|
|
146147
146157
|
typeName: a.type
|
|
146148
146158
|
};
|
|
146149
146159
|
}
|
|
146150
|
-
const
|
|
146160
|
+
const shape2 = predicted.map((r) => ({
|
|
146151
146161
|
actor: r.reviewerActorId,
|
|
146152
146162
|
source: r.source,
|
|
146153
146163
|
reviewGroup: r.reviewGroup
|
|
146154
146164
|
}));
|
|
146155
|
-
return { ...reviewerPreviewOfRows(
|
|
146165
|
+
return { ...reviewerPreviewOfRows(shape2), predicted: true, typeName: a.type };
|
|
146156
146166
|
}
|
|
146157
146167
|
/**
|
|
146158
146168
|
* 草案节点的审核人预览:按**这台内核**的类型配置与花名册(roleIndex,含 registry-only 注入的机械投票者),
|
|
@@ -150947,9 +150957,9 @@ var init_types2 = __esm({
|
|
|
150947
150957
|
_getCached() {
|
|
150948
150958
|
if (this._cached !== null)
|
|
150949
150959
|
return this._cached;
|
|
150950
|
-
const
|
|
150951
|
-
const keys = util.objectKeys(
|
|
150952
|
-
this._cached = { shape, keys };
|
|
150960
|
+
const shape2 = this._def.shape();
|
|
150961
|
+
const keys = util.objectKeys(shape2);
|
|
150962
|
+
this._cached = { shape: shape2, keys };
|
|
150953
150963
|
return this._cached;
|
|
150954
150964
|
}
|
|
150955
150965
|
_parse(input) {
|
|
@@ -150964,7 +150974,7 @@ var init_types2 = __esm({
|
|
|
150964
150974
|
return INVALID;
|
|
150965
150975
|
}
|
|
150966
150976
|
const { status, ctx } = this._processInputParams(input);
|
|
150967
|
-
const { shape, keys: shapeKeys } = this._getCached();
|
|
150977
|
+
const { shape: shape2, keys: shapeKeys } = this._getCached();
|
|
150968
150978
|
const extraKeys = [];
|
|
150969
150979
|
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
|
|
150970
150980
|
for (const key2 in ctx.data) {
|
|
@@ -150975,7 +150985,7 @@ var init_types2 = __esm({
|
|
|
150975
150985
|
}
|
|
150976
150986
|
const pairs = [];
|
|
150977
150987
|
for (const key2 of shapeKeys) {
|
|
150978
|
-
const keyValidator =
|
|
150988
|
+
const keyValidator = shape2[key2];
|
|
150979
150989
|
const value2 = ctx.data[key2];
|
|
150980
150990
|
pairs.push({
|
|
150981
150991
|
key: { status: "valid", value: key2 },
|
|
@@ -151181,27 +151191,27 @@ var init_types2 = __esm({
|
|
|
151181
151191
|
});
|
|
151182
151192
|
}
|
|
151183
151193
|
pick(mask2) {
|
|
151184
|
-
const
|
|
151194
|
+
const shape2 = {};
|
|
151185
151195
|
for (const key2 of util.objectKeys(mask2)) {
|
|
151186
151196
|
if (mask2[key2] && this.shape[key2]) {
|
|
151187
|
-
|
|
151197
|
+
shape2[key2] = this.shape[key2];
|
|
151188
151198
|
}
|
|
151189
151199
|
}
|
|
151190
151200
|
return new _ZodObject({
|
|
151191
151201
|
...this._def,
|
|
151192
|
-
shape: () =>
|
|
151202
|
+
shape: () => shape2
|
|
151193
151203
|
});
|
|
151194
151204
|
}
|
|
151195
151205
|
omit(mask2) {
|
|
151196
|
-
const
|
|
151206
|
+
const shape2 = {};
|
|
151197
151207
|
for (const key2 of util.objectKeys(this.shape)) {
|
|
151198
151208
|
if (!mask2[key2]) {
|
|
151199
|
-
|
|
151209
|
+
shape2[key2] = this.shape[key2];
|
|
151200
151210
|
}
|
|
151201
151211
|
}
|
|
151202
151212
|
return new _ZodObject({
|
|
151203
151213
|
...this._def,
|
|
151204
|
-
shape: () =>
|
|
151214
|
+
shape: () => shape2
|
|
151205
151215
|
});
|
|
151206
151216
|
}
|
|
151207
151217
|
/**
|
|
@@ -151248,27 +151258,27 @@ var init_types2 = __esm({
|
|
|
151248
151258
|
return createZodEnum(util.objectKeys(this.shape));
|
|
151249
151259
|
}
|
|
151250
151260
|
};
|
|
151251
|
-
ZodObject.create = (
|
|
151261
|
+
ZodObject.create = (shape2, params) => {
|
|
151252
151262
|
return new ZodObject({
|
|
151253
|
-
shape: () =>
|
|
151263
|
+
shape: () => shape2,
|
|
151254
151264
|
unknownKeys: "strip",
|
|
151255
151265
|
catchall: ZodNever.create(),
|
|
151256
151266
|
typeName: ZodFirstPartyTypeKind.ZodObject,
|
|
151257
151267
|
...processCreateParams(params)
|
|
151258
151268
|
});
|
|
151259
151269
|
};
|
|
151260
|
-
ZodObject.strictCreate = (
|
|
151270
|
+
ZodObject.strictCreate = (shape2, params) => {
|
|
151261
151271
|
return new ZodObject({
|
|
151262
|
-
shape: () =>
|
|
151272
|
+
shape: () => shape2,
|
|
151263
151273
|
unknownKeys: "strict",
|
|
151264
151274
|
catchall: ZodNever.create(),
|
|
151265
151275
|
typeName: ZodFirstPartyTypeKind.ZodObject,
|
|
151266
151276
|
...processCreateParams(params)
|
|
151267
151277
|
});
|
|
151268
151278
|
};
|
|
151269
|
-
ZodObject.lazycreate = (
|
|
151279
|
+
ZodObject.lazycreate = (shape2, params) => {
|
|
151270
151280
|
return new ZodObject({
|
|
151271
|
-
shape,
|
|
151281
|
+
shape: shape2,
|
|
151272
151282
|
unknownKeys: "strip",
|
|
151273
151283
|
catchall: ZodNever.create(),
|
|
151274
151284
|
typeName: ZodFirstPartyTypeKind.ZodObject,
|
|
@@ -152980,9 +152990,9 @@ function stringifyPrimitive(value2) {
|
|
|
152980
152990
|
return `"${value2}"`;
|
|
152981
152991
|
return `${value2}`;
|
|
152982
152992
|
}
|
|
152983
|
-
function optionalKeys(
|
|
152984
|
-
return Object.keys(
|
|
152985
|
-
return
|
|
152993
|
+
function optionalKeys(shape2) {
|
|
152994
|
+
return Object.keys(shape2).filter((k2) => {
|
|
152995
|
+
return shape2[k2]._zod.optin === "optional" && shape2[k2]._zod.optout === "optional";
|
|
152986
152996
|
});
|
|
152987
152997
|
}
|
|
152988
152998
|
function pick2(schema, mask2) {
|
|
@@ -153019,14 +153029,14 @@ function omit(schema, mask2) {
|
|
|
153019
153029
|
checks: []
|
|
153020
153030
|
});
|
|
153021
153031
|
}
|
|
153022
|
-
function extend(schema,
|
|
153023
|
-
if (!isPlainObject(
|
|
153032
|
+
function extend(schema, shape2) {
|
|
153033
|
+
if (!isPlainObject(shape2)) {
|
|
153024
153034
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
153025
153035
|
}
|
|
153026
153036
|
const def = {
|
|
153027
153037
|
...schema._zod.def,
|
|
153028
153038
|
get shape() {
|
|
153029
|
-
const _shape = { ...schema._zod.def.shape, ...
|
|
153039
|
+
const _shape = { ...schema._zod.def.shape, ...shape2 };
|
|
153030
153040
|
assignProp(this, "shape", _shape);
|
|
153031
153041
|
return _shape;
|
|
153032
153042
|
},
|
|
@@ -153050,7 +153060,7 @@ function merge(a, b2) {
|
|
|
153050
153060
|
}
|
|
153051
153061
|
function partial(Class2, schema, mask2) {
|
|
153052
153062
|
const oldShape = schema._zod.def.shape;
|
|
153053
|
-
const
|
|
153063
|
+
const shape2 = { ...oldShape };
|
|
153054
153064
|
if (mask2) {
|
|
153055
153065
|
for (const key2 in mask2) {
|
|
153056
153066
|
if (!(key2 in oldShape)) {
|
|
@@ -153058,14 +153068,14 @@ function partial(Class2, schema, mask2) {
|
|
|
153058
153068
|
}
|
|
153059
153069
|
if (!mask2[key2])
|
|
153060
153070
|
continue;
|
|
153061
|
-
|
|
153071
|
+
shape2[key2] = Class2 ? new Class2({
|
|
153062
153072
|
type: "optional",
|
|
153063
153073
|
innerType: oldShape[key2]
|
|
153064
153074
|
}) : oldShape[key2];
|
|
153065
153075
|
}
|
|
153066
153076
|
} else {
|
|
153067
153077
|
for (const key2 in oldShape) {
|
|
153068
|
-
|
|
153078
|
+
shape2[key2] = Class2 ? new Class2({
|
|
153069
153079
|
type: "optional",
|
|
153070
153080
|
innerType: oldShape[key2]
|
|
153071
153081
|
}) : oldShape[key2];
|
|
@@ -153073,28 +153083,28 @@ function partial(Class2, schema, mask2) {
|
|
|
153073
153083
|
}
|
|
153074
153084
|
return clone(schema, {
|
|
153075
153085
|
...schema._zod.def,
|
|
153076
|
-
shape,
|
|
153086
|
+
shape: shape2,
|
|
153077
153087
|
checks: []
|
|
153078
153088
|
});
|
|
153079
153089
|
}
|
|
153080
153090
|
function required(Class2, schema, mask2) {
|
|
153081
153091
|
const oldShape = schema._zod.def.shape;
|
|
153082
|
-
const
|
|
153092
|
+
const shape2 = { ...oldShape };
|
|
153083
153093
|
if (mask2) {
|
|
153084
153094
|
for (const key2 in mask2) {
|
|
153085
|
-
if (!(key2 in
|
|
153095
|
+
if (!(key2 in shape2)) {
|
|
153086
153096
|
throw new Error(`Unrecognized key: "${key2}"`);
|
|
153087
153097
|
}
|
|
153088
153098
|
if (!mask2[key2])
|
|
153089
153099
|
continue;
|
|
153090
|
-
|
|
153100
|
+
shape2[key2] = new Class2({
|
|
153091
153101
|
type: "nonoptional",
|
|
153092
153102
|
innerType: oldShape[key2]
|
|
153093
153103
|
});
|
|
153094
153104
|
}
|
|
153095
153105
|
} else {
|
|
153096
153106
|
for (const key2 in oldShape) {
|
|
153097
|
-
|
|
153107
|
+
shape2[key2] = new Class2({
|
|
153098
153108
|
type: "nonoptional",
|
|
153099
153109
|
innerType: oldShape[key2]
|
|
153100
153110
|
});
|
|
@@ -153102,7 +153112,7 @@ function required(Class2, schema, mask2) {
|
|
|
153102
153112
|
}
|
|
153103
153113
|
return clone(schema, {
|
|
153104
153114
|
...schema._zod.def,
|
|
153105
|
-
shape,
|
|
153115
|
+
shape: shape2,
|
|
153106
153116
|
// optional: [],
|
|
153107
153117
|
checks: []
|
|
153108
153118
|
});
|
|
@@ -154579,10 +154589,10 @@ var init_schemas = __esm({
|
|
|
154579
154589
|
};
|
|
154580
154590
|
});
|
|
154581
154591
|
defineLazy(inst._zod, "propValues", () => {
|
|
154582
|
-
const
|
|
154592
|
+
const shape2 = def.shape;
|
|
154583
154593
|
const propValues = {};
|
|
154584
|
-
for (const key2 in
|
|
154585
|
-
const field =
|
|
154594
|
+
for (const key2 in shape2) {
|
|
154595
|
+
const field = shape2[key2]._zod;
|
|
154586
154596
|
if (field.values) {
|
|
154587
154597
|
propValues[key2] ?? (propValues[key2] = /* @__PURE__ */ new Set());
|
|
154588
154598
|
for (const v2 of field.values)
|
|
@@ -154591,7 +154601,7 @@ var init_schemas = __esm({
|
|
|
154591
154601
|
}
|
|
154592
154602
|
return propValues;
|
|
154593
154603
|
});
|
|
154594
|
-
const generateFastpass = (
|
|
154604
|
+
const generateFastpass = (shape2) => {
|
|
154595
154605
|
const doc = new Doc(["shape", "payload", "ctx"]);
|
|
154596
154606
|
const normalized4 = _normalized.value;
|
|
154597
154607
|
const parseStr = (key2) => {
|
|
@@ -154644,7 +154654,7 @@ var init_schemas = __esm({
|
|
|
154644
154654
|
doc.write(`payload.value = newResult;`);
|
|
154645
154655
|
doc.write(`return payload;`);
|
|
154646
154656
|
const fn = doc.compile();
|
|
154647
|
-
return (payload2, ctx) => fn(
|
|
154657
|
+
return (payload2, ctx) => fn(shape2, payload2, ctx);
|
|
154648
154658
|
};
|
|
154649
154659
|
let fastpass;
|
|
154650
154660
|
const isObject2 = isObject;
|
|
@@ -154672,9 +154682,9 @@ var init_schemas = __esm({
|
|
|
154672
154682
|
payload2 = fastpass(payload2, ctx);
|
|
154673
154683
|
} else {
|
|
154674
154684
|
payload2.value = {};
|
|
154675
|
-
const
|
|
154685
|
+
const shape2 = value2.shape;
|
|
154676
154686
|
for (const key2 of value2.keys) {
|
|
154677
|
-
const el =
|
|
154687
|
+
const el = shape2[key2];
|
|
154678
154688
|
const r = el._zod.run({ value: input[key2], issues: [] }, ctx);
|
|
154679
154689
|
const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
|
|
154680
154690
|
if (r instanceof Promise) {
|
|
@@ -155961,22 +155971,22 @@ function never(params) {
|
|
|
155961
155971
|
function array(element, params) {
|
|
155962
155972
|
return _array(ZodArray2, element, params);
|
|
155963
155973
|
}
|
|
155964
|
-
function object(
|
|
155974
|
+
function object(shape2, params) {
|
|
155965
155975
|
const def = {
|
|
155966
155976
|
type: "object",
|
|
155967
155977
|
get shape() {
|
|
155968
|
-
util_exports.assignProp(this, "shape", { ...
|
|
155978
|
+
util_exports.assignProp(this, "shape", { ...shape2 });
|
|
155969
155979
|
return this.shape;
|
|
155970
155980
|
},
|
|
155971
155981
|
...util_exports.normalizeParams(params)
|
|
155972
155982
|
};
|
|
155973
155983
|
return new ZodObject2(def);
|
|
155974
155984
|
}
|
|
155975
|
-
function looseObject(
|
|
155985
|
+
function looseObject(shape2, params) {
|
|
155976
155986
|
return new ZodObject2({
|
|
155977
155987
|
type: "object",
|
|
155978
155988
|
get shape() {
|
|
155979
|
-
util_exports.assignProp(this, "shape", { ...
|
|
155989
|
+
util_exports.assignProp(this, "shape", { ...shape2 });
|
|
155980
155990
|
return this.shape;
|
|
155981
155991
|
},
|
|
155982
155992
|
catchall: unknown(),
|
|
@@ -170153,7 +170163,7 @@ function escalationKindOf(issueId, authorActorId, source) {
|
|
|
170153
170163
|
if (issueId.startsWith(REVIEW_EXHAUSTED_ESC_PREFIX2)) return "review_exhausted";
|
|
170154
170164
|
if (typeof source === "string") {
|
|
170155
170165
|
if (source.startsWith(SLA_STALL_ESC_SOURCE_PREFIX)) {
|
|
170156
|
-
return STALL_KIND_BY_SOURCE[source.slice(SLA_STALL_ESC_SOURCE_PREFIX.length)] ?? "stall_idle_unexplained";
|
|
170166
|
+
return STALL_KIND_BY_SOURCE[source.slice(SLA_STALL_ESC_SOURCE_PREFIX.length).split(":")[0]] ?? "stall_idle_unexplained";
|
|
170157
170167
|
}
|
|
170158
170168
|
if (source === LEGACY_REVIEW_STALL_ESC_SOURCE) return "stall_idle_unexplained";
|
|
170159
170169
|
if (source === SLA_BREAKER_ESC_SOURCE) return "sla_breaker";
|
|
@@ -172200,10 +172210,10 @@ var init_run_store = __esm({
|
|
|
172200
172210
|
return result;
|
|
172201
172211
|
}
|
|
172202
172212
|
async persist(runs) {
|
|
172203
|
-
const
|
|
172213
|
+
const shape2 = { version: 1, runs };
|
|
172204
172214
|
const temp = `${this.file}.${process.pid}.${(0, import_node_crypto28.randomUUID)()}.tmp`;
|
|
172205
172215
|
try {
|
|
172206
|
-
await (0, import_promises3.writeFile)(temp, `${JSON.stringify(
|
|
172216
|
+
await (0, import_promises3.writeFile)(temp, `${JSON.stringify(shape2, null, 2)}
|
|
172207
172217
|
`, { mode: 384 });
|
|
172208
172218
|
await (0, import_promises3.rename)(temp, this.file);
|
|
172209
172219
|
} finally {
|
|
@@ -202288,23 +202298,23 @@ var init_governance_store = __esm({
|
|
|
202288
202298
|
this.mutationChain = result.then(() => void 0, () => void 0);
|
|
202289
202299
|
return result;
|
|
202290
202300
|
}
|
|
202291
|
-
async persist(
|
|
202301
|
+
async persist(shape2) {
|
|
202292
202302
|
const temp = `${this.file}.${process.pid}.${(0, import_node_crypto35.randomUUID)()}.tmp`;
|
|
202293
202303
|
try {
|
|
202294
|
-
await (0, import_promises4.writeFile)(temp, `${JSON.stringify(this.sealSnapshots(
|
|
202304
|
+
await (0, import_promises4.writeFile)(temp, `${JSON.stringify(this.sealSnapshots(shape2), null, 2)}
|
|
202295
202305
|
`, { mode: 384 });
|
|
202296
202306
|
await (0, import_promises4.rename)(temp, this.file);
|
|
202297
202307
|
} finally {
|
|
202298
202308
|
await (0, import_promises4.unlink)(temp).catch(() => void 0);
|
|
202299
202309
|
}
|
|
202300
202310
|
}
|
|
202301
|
-
sealSnapshots(
|
|
202302
|
-
const next = clone3(
|
|
202311
|
+
sealSnapshots(shape2) {
|
|
202312
|
+
const next = clone3(shape2);
|
|
202303
202313
|
next.records.snapshot = (next.records.snapshot ?? []).map((record9) => sealKnowledgeSnapshot(record9, this.snapshotKey));
|
|
202304
202314
|
return next;
|
|
202305
202315
|
}
|
|
202306
|
-
static openSnapshots(
|
|
202307
|
-
const next = clone3(
|
|
202316
|
+
static openSnapshots(shape2, key2) {
|
|
202317
|
+
const next = clone3(shape2);
|
|
202308
202318
|
next.records.snapshot = (next.records.snapshot ?? []).map((record9) => openKnowledgeSnapshot(record9, key2));
|
|
202309
202319
|
return next;
|
|
202310
202320
|
}
|
|
@@ -209571,21 +209581,24 @@ var init_open_design2 = __esm({
|
|
|
209571
209581
|
async function adoptGithubApp(store, args, deps = {}) {
|
|
209572
209582
|
const scope2 = args.actorId ? { scope: "personal", actorId: args.actorId } : { scope: "global" };
|
|
209573
209583
|
const put3 = (key2, value2, encrypted) => store.putVariable({ key: key2, value: value2, ...scope2, connectorId: "github", encrypted });
|
|
209584
|
+
const minting = args.actorId ? mintInstallationToken(
|
|
209585
|
+
{ appId: args.appId, privateKeyPem: args.privateKeyPem, installationId: args.installationId },
|
|
209586
|
+
deps
|
|
209587
|
+
) : null;
|
|
209588
|
+
minting?.catch(() => {
|
|
209589
|
+
});
|
|
209574
209590
|
await put3("GITHUB_APP_ID", args.appId, false);
|
|
209575
209591
|
await put3("GITHUB_APP_PRIVATE_KEY", args.privateKeyPem, true);
|
|
209576
209592
|
await put3("GITHUB_APP_INSTALLATION_ID", args.installationId, false);
|
|
209577
209593
|
if (args.slug) await put3("GITHUB_APP_SLUG", args.slug, false);
|
|
209578
|
-
if (!
|
|
209594
|
+
if (!minting) {
|
|
209579
209595
|
return { account: args.slug ? `${args.slug}[bot]` : args.appId };
|
|
209580
209596
|
}
|
|
209581
|
-
const minted = await
|
|
209582
|
-
{ appId: args.appId, privateKeyPem: args.privateKeyPem, installationId: args.installationId },
|
|
209583
|
-
deps
|
|
209584
|
-
);
|
|
209597
|
+
const minted = await minting;
|
|
209585
209598
|
await put3("GITHUB_APP_TOKEN", minted.token, true);
|
|
209586
209599
|
await put3("GITHUB_APP_TOKEN_EXPIRES_AT", String(minted.expiresAtMs), false);
|
|
209587
209600
|
if (args.slug) {
|
|
209588
|
-
const bot = await fetchAppBotIdentity(args.slug, { token: minted.token }, deps);
|
|
209601
|
+
const bot = args.knownBot ?? await fetchAppBotIdentity(args.slug, { token: minted.token }, deps);
|
|
209589
209602
|
await put3("GITHUB_APP_BOT_EMAIL", bot?.email ?? "", false);
|
|
209590
209603
|
await put3("GITHUB_APP_BOT_NAME", bot?.login ?? `${args.slug}[bot]`, false);
|
|
209591
209604
|
}
|
|
@@ -209606,13 +209619,40 @@ function randomAppNameSuffix() {
|
|
|
209606
209619
|
const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
|
|
209607
209620
|
return Array.from((0, import_node_crypto42.randomBytes)(4), (b2) => alphabet[b2 % alphabet.length]).join("");
|
|
209608
209621
|
}
|
|
209622
|
+
async function githubAppNameTaken(name, fetchImpl = fetch, timeoutMs = 3e3) {
|
|
209623
|
+
const probe = async (url, headers = {}) => {
|
|
209624
|
+
const res = await fetchImpl(url, { method: "GET", redirect: "manual", headers, signal: AbortSignal.timeout(timeoutMs) });
|
|
209625
|
+
if (res.status === 404) return false;
|
|
209626
|
+
if (res.status === 200) return true;
|
|
209627
|
+
throw new Error(`unexpected ${res.status}`);
|
|
209628
|
+
};
|
|
209629
|
+
const n = encodeURIComponent(name);
|
|
209630
|
+
try {
|
|
209631
|
+
const [app, user] = await Promise.all([
|
|
209632
|
+
probe(`https://github.com/apps/${n}`),
|
|
209633
|
+
probe(`https://api.github.com/users/${n}`, { accept: "application/vnd.github+json", "user-agent": "oasis" })
|
|
209634
|
+
]);
|
|
209635
|
+
return app || user;
|
|
209636
|
+
} catch {
|
|
209637
|
+
return true;
|
|
209638
|
+
}
|
|
209639
|
+
}
|
|
209640
|
+
async function chooseAppNameSuffix(args, isTaken) {
|
|
209641
|
+
const nameWith = (suffix2) => appName({ ...args, suffix: suffix2 });
|
|
209642
|
+
if (!await isTaken(nameWith(""))) return "";
|
|
209643
|
+
let suffix = randomAppNameSuffix();
|
|
209644
|
+
for (let i = 0; i < 4 && await isTaken(nameWith(suffix)); i++) suffix = randomAppNameSuffix();
|
|
209645
|
+
return suffix;
|
|
209646
|
+
}
|
|
209647
|
+
function appName(args) {
|
|
209648
|
+
const room = GITHUB_APP_NAME_MAX - args.namePrefix.length - 1 - (args.suffix ? args.suffix.length + 1 : 0);
|
|
209649
|
+
const middle = args.employeeSlug.slice(0, Math.max(0, room)).replace(/-+$/, "");
|
|
209650
|
+
return [args.namePrefix, middle, args.suffix].filter(Boolean).join("-");
|
|
209651
|
+
}
|
|
209609
209652
|
function buildAppManifest(args) {
|
|
209610
209653
|
const base = args.baseUrl.replace(/\/+$/, "");
|
|
209611
|
-
const suffix = args.nameSuffix ?? randomAppNameSuffix();
|
|
209612
|
-
const room = GITHUB_APP_NAME_MAX - args.namePrefix.length - suffix.length - 2;
|
|
209613
|
-
const middle = args.employeeSlug.slice(0, Math.max(0, room)).replace(/-+$/, "");
|
|
209614
209654
|
return {
|
|
209615
|
-
name:
|
|
209655
|
+
name: appName({ employeeSlug: args.employeeSlug, namePrefix: args.namePrefix, suffix: args.nameSuffix ?? "" }),
|
|
209616
209656
|
url: base,
|
|
209617
209657
|
redirect_url: `${base}${args.redirectPath}`,
|
|
209618
209658
|
public: false,
|
|
@@ -210506,6 +210546,50 @@ var init_github_app_inventory = __esm({
|
|
|
210506
210546
|
}
|
|
210507
210547
|
});
|
|
210508
210548
|
|
|
210549
|
+
// ../server/src/github-app-timing.ts
|
|
210550
|
+
function startGithubAppTiming(res) {
|
|
210551
|
+
const t0 = performance.now();
|
|
210552
|
+
const entries = [];
|
|
210553
|
+
let n = 0;
|
|
210554
|
+
const record9 = async (name, desc, run) => {
|
|
210555
|
+
const s2 = performance.now();
|
|
210556
|
+
try {
|
|
210557
|
+
return await run();
|
|
210558
|
+
} finally {
|
|
210559
|
+
entries.push({ name: `${name}${++n}`, desc, startMs: s2 - t0, durMs: performance.now() - s2 });
|
|
210560
|
+
}
|
|
210561
|
+
};
|
|
210562
|
+
const writeHead = res.writeHead.bind(res);
|
|
210563
|
+
res.writeHead = (...args) => {
|
|
210564
|
+
const header = [
|
|
210565
|
+
...entries.map((e) => `${e.name};desc="${e.desc} @${Math.round(e.startMs)}";dur=${e.durMs.toFixed(0)}`),
|
|
210566
|
+
`total;dur=${(performance.now() - t0).toFixed(0)}`
|
|
210567
|
+
].join(", ");
|
|
210568
|
+
res.setHeader("server-timing", header);
|
|
210569
|
+
return writeHead(...args);
|
|
210570
|
+
};
|
|
210571
|
+
return {
|
|
210572
|
+
fetch: (input, init) => record9("gh", `${init?.method ?? "GET"} ${shape(String(input instanceof Request ? input.url : input))}`, () => globalThis.fetch(input, init)),
|
|
210573
|
+
step: record9
|
|
210574
|
+
};
|
|
210575
|
+
}
|
|
210576
|
+
function timedAdoptionStore(store, timing) {
|
|
210577
|
+
return { putVariable: (v2) => timing.step("db", `put ${v2.key}`, () => store.putVariable(v2)) };
|
|
210578
|
+
}
|
|
210579
|
+
var shape;
|
|
210580
|
+
var init_github_app_timing = __esm({
|
|
210581
|
+
"../server/src/github-app-timing.ts"() {
|
|
210582
|
+
"use strict";
|
|
210583
|
+
shape = (url) => {
|
|
210584
|
+
try {
|
|
210585
|
+
return new URL(url).pathname.replace(/\/\d+(?=\/|$)/g, "/:id").replace(/\/[^/]+%5Bbot%5D|\/[^/]+\[bot\]/g, "/:bot");
|
|
210586
|
+
} catch {
|
|
210587
|
+
return "?";
|
|
210588
|
+
}
|
|
210589
|
+
};
|
|
210590
|
+
}
|
|
210591
|
+
});
|
|
210592
|
+
|
|
210509
210593
|
// ../server/src/server.ts
|
|
210510
210594
|
function isBundleFrozen(err) {
|
|
210511
210595
|
return typeof err === "object" && err !== null && err.code === "TENANT_BUNDLE_FROZEN";
|
|
@@ -216024,9 +216108,14 @@ ${composed}`;
|
|
|
216024
216108
|
const { randomUUID: randomUUID48 } = await import("node:crypto");
|
|
216025
216109
|
const state = randomUUID48();
|
|
216026
216110
|
const nameSlug = (actorName || actorId?.split(":").pop() || owner?.login || "bot").toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "").slice(0, 24) || "bot";
|
|
216111
|
+
const nameSuffix = await chooseAppNameSuffix(
|
|
216112
|
+
{ employeeSlug: nameSlug, namePrefix: "oasis" },
|
|
216113
|
+
(name) => (opts.githubAppNameTaken ?? githubAppNameTaken)(name)
|
|
216114
|
+
);
|
|
216027
216115
|
const manifest = buildAppManifest({
|
|
216028
216116
|
employeeSlug: nameSlug,
|
|
216029
216117
|
namePrefix: "oasis",
|
|
216118
|
+
nameSuffix,
|
|
216030
216119
|
baseUrl: base,
|
|
216031
216120
|
redirectPath: "/api/connectors/github/app/manifest-callback",
|
|
216032
216121
|
setupPath: "/api/connectors/github/app/setup-callback"
|
|
@@ -216182,9 +216271,10 @@ ${composed}`;
|
|
|
216182
216271
|
res.writeHead(400, { "content-type": "application/json" }).end(JSON.stringify({ error: "\u7F3A\u5C11 appId" }));
|
|
216183
216272
|
return;
|
|
216184
216273
|
}
|
|
216274
|
+
const timing = startGithubAppTiming(res);
|
|
216185
216275
|
const svc = await connectorActorsService();
|
|
216186
216276
|
if (!svc) throw new Error("actors service unavailable");
|
|
216187
|
-
const rows = await svc.listVariables();
|
|
216277
|
+
const rows = await timing.step("db", "list variables", () => svc.listVariables());
|
|
216188
216278
|
const owners = rows.filter((r) => r.key === "GITHUB_APP_ID" && !r.encrypted && r.maskedValue === appId);
|
|
216189
216279
|
const src = owners.find((r) => !r.actorId) ?? owners[0];
|
|
216190
216280
|
if (!src) {
|
|
@@ -216192,27 +216282,30 @@ ${composed}`;
|
|
|
216192
216282
|
return;
|
|
216193
216283
|
}
|
|
216194
216284
|
const srcActor = src.actorId;
|
|
216195
|
-
const pem = await svc.revealVariable("GITHUB_APP_PRIVATE_KEY", srcActor);
|
|
216285
|
+
const pem = await timing.step("db", "reveal key", () => svc.revealVariable("GITHUB_APP_PRIVATE_KEY", srcActor));
|
|
216196
216286
|
if (!pem) {
|
|
216197
216287
|
res.writeHead(409, { "content-type": "application/json" }).end(JSON.stringify({ error: "\u8FD9\u4E2A App \u7684\u79C1\u94A5\u4E0D\u5728\u5E93\u91CC\uFF0C\u65E0\u6CD5\u7ED1\u5B9A" }));
|
|
216198
216288
|
return;
|
|
216199
216289
|
}
|
|
216200
216290
|
const pick3 = (key2) => rows.find((r) => r.key === key2 && r.actorId === srcActor && !r.encrypted)?.maskedValue ?? "";
|
|
216201
216291
|
const storedInstallationId = pick3("GITHUB_APP_INSTALLATION_ID");
|
|
216202
|
-
const live = await listAppInstallations({ appId, privateKeyPem: pem }).catch(() => null);
|
|
216292
|
+
const live = await listAppInstallations({ appId, privateKeyPem: pem }, { fetch: timing.fetch }).catch(() => null);
|
|
216203
216293
|
const installationId = live ? (live.find((i) => i.installationId === storedInstallationId) ?? live[0])?.installationId ?? "" : storedInstallationId;
|
|
216204
216294
|
if (!installationId) {
|
|
216205
216295
|
res.writeHead(409, { "content-type": "application/json" }).end(JSON.stringify({ error: "\u8FD9\u4E2A App \u8FD8\u6CA1\u88C5\u5230\u4EFB\u4F55\u8D26\u53F7\u2014\u2014\u5148\u5728 GitHub \u4E0A\u5B89\u88C5\u5B83\uFF0C\u88C5\u597D\u540E\u518D\u70B9\u8FDE\u63A5", notInstalled: true }));
|
|
216206
216296
|
return;
|
|
216207
216297
|
}
|
|
216208
216298
|
const slug6 = pick3("GITHUB_APP_SLUG");
|
|
216209
|
-
const
|
|
216299
|
+
const botEmail = pick3("GITHUB_APP_BOT_EMAIL");
|
|
216300
|
+
const botLogin = pick3("GITHUB_APP_BOT_NAME");
|
|
216301
|
+
const result = await adoptGithubApp(timedAdoptionStore(svc, timing), {
|
|
216210
216302
|
...actorId ? { actorId } : {},
|
|
216211
216303
|
appId,
|
|
216212
216304
|
privateKeyPem: pem,
|
|
216213
216305
|
installationId,
|
|
216214
|
-
...slug6 ? { slug: slug6 } : {}
|
|
216215
|
-
|
|
216306
|
+
...slug6 ? { slug: slug6 } : {},
|
|
216307
|
+
...botEmail && botLogin ? { knownBot: { email: botEmail, login: botLogin } } : {}
|
|
216308
|
+
}, { fetch: timing.fetch });
|
|
216216
216309
|
res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({ ok: true, account: result.account }));
|
|
216217
216310
|
} catch (e) {
|
|
216218
216311
|
res.writeHead(500, { "content-type": "application/json" }).end(JSON.stringify({ error: String(e) }));
|
|
@@ -216231,11 +216324,15 @@ ${composed}`;
|
|
|
216231
216324
|
bad(400, "\u8FD9\u4E0D\u50CF\u4E00\u4E2A\u79C1\u94A5\u6587\u4EF6\u2014\u2014\u8BF7\u4E0A\u4F20 GitHub \u4E0B\u8F7D\u7684 .pem\uFF08\u5185\u5BB9\u4EE5 -----BEGIN ... PRIVATE KEY----- \u5F00\u5934\uFF09");
|
|
216232
216325
|
return;
|
|
216233
216326
|
}
|
|
216327
|
+
const timing = startGithubAppTiming(res);
|
|
216234
216328
|
const svc = await connectorActorsService();
|
|
216235
216329
|
if (!svc) throw new Error("actors service unavailable");
|
|
216330
|
+
const listing = listAppInstallations({ appId, privateKeyPem }, { fetch: timing.fetch });
|
|
216331
|
+
listing.catch(() => {
|
|
216332
|
+
});
|
|
216236
216333
|
let meta;
|
|
216237
216334
|
try {
|
|
216238
|
-
meta = await fetchAppSelfMetadata({ appId, privateKeyPem });
|
|
216335
|
+
meta = await fetchAppSelfMetadata({ appId, privateKeyPem }, { fetch: timing.fetch });
|
|
216239
216336
|
} catch (e) {
|
|
216240
216337
|
const msg = String(e);
|
|
216241
216338
|
bad(
|
|
@@ -216253,7 +216350,7 @@ ${composed}`;
|
|
|
216253
216350
|
);
|
|
216254
216351
|
return;
|
|
216255
216352
|
}
|
|
216256
|
-
const installs = await
|
|
216353
|
+
const installs = await listing;
|
|
216257
216354
|
if (installs.length === 0) {
|
|
216258
216355
|
bad(409, "\u8FD9\u4E2A App \u8FD8\u6CA1\u6709\u88AB\u5B89\u88C5\u5230\u4EFB\u4F55\u8D26\u53F7\u2014\u2014\u5148\u5728 GitHub \u4E0A\u628A\u5B83\u88C5\u5230\u76EE\u6807\u4ED3\u5E93");
|
|
216259
216356
|
return;
|
|
@@ -216267,14 +216364,14 @@ ${composed}`;
|
|
|
216267
216364
|
}));
|
|
216268
216365
|
return;
|
|
216269
216366
|
}
|
|
216270
|
-
const result = await adoptGithubApp(svc, {
|
|
216367
|
+
const result = await adoptGithubApp(timedAdoptionStore(svc, timing), {
|
|
216271
216368
|
...actorId ? { actorId } : {},
|
|
216272
216369
|
appId,
|
|
216273
216370
|
privateKeyPem,
|
|
216274
216371
|
installationId: chosen.installationId,
|
|
216275
216372
|
...meta.slug ? { slug: meta.slug } : {}
|
|
216276
|
-
});
|
|
216277
|
-
const effective =
|
|
216373
|
+
}, { fetch: timing.fetch });
|
|
216374
|
+
const effective = Object.keys(chosen.permissions).length > 0 ? chosen.permissions : meta.permissions;
|
|
216278
216375
|
res.writeHead(200, { "content-type": "application/json" }).end(JSON.stringify({
|
|
216279
216376
|
ok: true,
|
|
216280
216377
|
account: result.account,
|
|
@@ -216985,6 +217082,7 @@ var init_server3 = __esm({
|
|
|
216985
217082
|
init_registry_audit_sink();
|
|
216986
217083
|
init_src8();
|
|
216987
217084
|
init_github_app_inventory();
|
|
217085
|
+
init_github_app_timing();
|
|
216988
217086
|
init_continuation3();
|
|
216989
217087
|
CONNECTOR_AUTH_SNAPSHOT_TTL_MS = 30 * 60 * 1e3;
|
|
216990
217088
|
defaultResolveActor = (token) => token.startsWith("token:") ? token.slice("token:".length) : null;
|
|
@@ -237744,11 +237842,12 @@ function reviewLabel(r) {
|
|
|
237744
237842
|
if (state === "retry") return "\u6B63\u5728\u91CD\u8BD5\u5BA1\u6838";
|
|
237745
237843
|
return r.reviewerActorId.startsWith("actor:human:") ? "\u5F85\u5BA1\u6838" : "\u6B63\u5728\u5BA1\u6838";
|
|
237746
237844
|
}
|
|
237747
|
-
function reviewSummary(snap, reviews, events) {
|
|
237845
|
+
function reviewSummary(snap, reviews, events, versionNo) {
|
|
237748
237846
|
const first = reviews[0];
|
|
237749
237847
|
const work = snap.works.find((w2) => w2.id === first.targetWorkId);
|
|
237750
237848
|
const node2 = snap.nodes.find((n) => n.id === first.nodeId);
|
|
237751
237849
|
const name = node2?.title ?? first.nodeId;
|
|
237850
|
+
const ver = versionNo !== void 0 ? `\u7B2C ${versionNo} \u7248` : "";
|
|
237752
237851
|
const latest = latestActivityReviews(reviews, events);
|
|
237753
237852
|
const requirements = snap.requirements.filter((r) => r.nodeId === first.nodeId && r.reviewerActorId === first.reviewerActorId);
|
|
237754
237853
|
for (const requirement of requirements) {
|
|
@@ -237760,21 +237859,21 @@ function reviewSummary(snap, reviews, events) {
|
|
|
237760
237859
|
const judgement = judgeWork({ requirements: requirements.length ? requirements : latest, reviews: latest });
|
|
237761
237860
|
const pending = latest.filter((r) => !r.cancelledAt && !r.verdict && reviewState(r) === "running");
|
|
237762
237861
|
if (work?.acceptanceState === "accepted" || work?.acceptedAt || work?.acceptanceState !== "rejected" && judgement === "passed") {
|
|
237763
|
-
return { phase: "done", status: `\u300A${name}\u300B\u5BA1\u6838\u901A\u8FC7\u3002`, latest, pending: [] };
|
|
237862
|
+
return { phase: "done", status: `\u300A${name}\u300B${ver}\u5BA1\u6838\u901A\u8FC7\u3002`, latest, pending: [] };
|
|
237764
237863
|
}
|
|
237765
237864
|
if (work?.acceptanceState === "rejected" || judgement === "rejected") {
|
|
237766
|
-
return { phase: "done", status: `\u300A${name}\u300B\u5BA1\u6838\u4E0D\u901A\u8FC7\u3002`, latest, pending: [] };
|
|
237865
|
+
return { phase: "done", status: `\u300A${name}\u300B${ver}\u5BA1\u6838\u4E0D\u901A\u8FC7\u3002`, latest, pending: [] };
|
|
237767
237866
|
}
|
|
237768
237867
|
const endedWork = !!(work?.cancelledAt || work?.deadAt);
|
|
237769
237868
|
if (endedWork && latest.every((r) => !!r.cancelledAt && reviewState(r) !== "retry")) {
|
|
237770
237869
|
return { phase: "done", status: `\u300A${name}\u300B\u7684\u672C\u6B21\u5BA1\u6838\u5DF2\u53D6\u6D88\u3002`, latest, pending: [] };
|
|
237771
237870
|
}
|
|
237772
237871
|
const interrupted = latest.some((r) => ["failed", "dead"].includes(reviewState(r)));
|
|
237773
|
-
if (interrupted) return { phase: "stuck", status: latest.length === 1 ? reviewState(latest[0]) === "dead" ? events.some((r) => r.event.kind === "review.kill" && r.event.reviewId === latest[0].id) ? `\u300A${name}\u300B\u7684\
|
|
237872
|
+
if (interrupted) return { phase: "stuck", status: latest.length === 1 ? reviewState(latest[0]) === "dead" ? events.some((r) => r.event.kind === "review.kill" && r.event.reviewId === latest[0].id) ? `\u300A${name}\u300B\u7684\u5BA1\u6838\u8FDE\u7EED\u51E0\u6B21\u6CA1\u8DD1\u6210\uFF0C\u5DF2\u505C\u6B62\u3002` : `\u300A${name}\u300B\u7684\u5BA1\u6838\u5DF2\u505C\u6B62\u3002` : `\u300A${name}\u300B\u7684\u5BA1\u6838\u672A\u5728\u65F6\u9650\u5185\u5B8C\u6210\u3002` : `\u300A${name}\u300B\u6709\u5BA1\u6838\u4EBA\u7684\u5BA1\u6838\u4E2D\u65AD\u4E86\uFF0C\u5BA1\u6838\u8FD8\u6CA1\u5168\u90E8\u5B8C\u6210\u3002`, latest, pending };
|
|
237774
237873
|
if (latest.some((r) => r.reviewerActorId.startsWith("actor:agent:") && ["running", "retry"].includes(reviewState(r)))) {
|
|
237775
|
-
return { phase: "running", status: `\u6B63\u5728\u5BA1\u6838
|
|
237874
|
+
return { phase: "running", status: `\u6B63\u5728\u5BA1\u6838\u300A${name}\u300B${ver}\u3002`, latest, pending };
|
|
237776
237875
|
}
|
|
237777
|
-
return { phase: "not_started", status: `\u8BF7\u786E\u8BA4\u300A${name}\u300B\u662F\u5426\u5BA1\u6838\u901A\u8FC7\u3002`, latest, pending };
|
|
237876
|
+
return { phase: "not_started", status: `\u8BF7\u786E\u8BA4\u300A${name}\u300B${ver}\u662F\u5426\u5BA1\u6838\u901A\u8FC7\u3002`, latest, pending };
|
|
237778
237877
|
}
|
|
237779
237878
|
var REVIEW_CARD_PREFIX, REVIEW_TRACE_EVENT_KINDS;
|
|
237780
237879
|
var init_review_activity = __esm({
|
|
@@ -237800,13 +237899,13 @@ function reviewRequirementActivity(snap, events, ref2) {
|
|
|
237800
237899
|
const label2 = (r) => `${ref2(r.reviewerActorId).name || "\u672A\u547D\u540D\u5BA1\u6838\u4EBA"}${r.source === "closure" ? "\uFF08\u7ED3\u6848\u5BA1\u6838\uFF09" : ""}`;
|
|
237801
237900
|
const names = (rows) => [...new Set(rows.map(label2))].join("\u3001");
|
|
237802
237901
|
const submitter = (id) => ref2(id).name?.trim() || "\u672A\u547D\u540D\u6210\u5458";
|
|
237803
|
-
const sentence = (id, nodeTitle, rows) => rows.length ? `${submitter(id)} \
|
|
237902
|
+
const sentence = (id, nodeTitle, rows) => rows.length ? `${submitter(id)} \u628A\u300A${nodeTitle}\u300B\u7684\u5BA1\u6838\u4EBA\u6539\u4E3A ${names(rows)}\u3002` : `${submitter(id)} \u53D6\u6D88\u4E86\u300A${nodeTitle}\u300B\u7684\u5BA1\u6838\u4EBA\u3002`;
|
|
237804
237903
|
for (const rec2 of [...events].sort((a, b2) => a.seq - b2.seq)) {
|
|
237805
237904
|
if (rec2.status === "pending" || rec2.status === "failed") continue;
|
|
237806
237905
|
const e = rec2.event;
|
|
237807
237906
|
if (e.kind !== "plan.update_review_requirements") continue;
|
|
237808
237907
|
if (!isAuthoredChange(rec2)) continue;
|
|
237809
|
-
const nodeTitle = titles.get(e.nodeId) || "\u5DF2\u79FB\u9664\u7684\
|
|
237908
|
+
const nodeTitle = titles.get(e.nodeId) || "\u5DF2\u79FB\u9664\u7684\u6B65\u9AA4";
|
|
237810
237909
|
cards.push({
|
|
237811
237910
|
id: `wo:${rec2.seq}`,
|
|
237812
237911
|
seq: rec2.seq,
|
|
@@ -237834,6 +237933,186 @@ var init_review_requirement_activity = __esm({
|
|
|
237834
237933
|
}
|
|
237835
237934
|
});
|
|
237836
237935
|
|
|
237936
|
+
// ../server/src/domains/collab/activity-version.ts
|
|
237937
|
+
function countsAsVersion(w2) {
|
|
237938
|
+
if (w2.lane === "reply") return false;
|
|
237939
|
+
return !!w2.conclusion || w2.acceptanceState === "accepted";
|
|
237940
|
+
}
|
|
237941
|
+
function outputVersionNumbers(snap) {
|
|
237942
|
+
const byNode = /* @__PURE__ */ new Map();
|
|
237943
|
+
for (const w2 of snap.works) {
|
|
237944
|
+
if (!countsAsVersion(w2)) continue;
|
|
237945
|
+
const list2 = byNode.get(w2.nodeId) ?? [];
|
|
237946
|
+
list2.push(w2);
|
|
237947
|
+
byNode.set(w2.nodeId, list2);
|
|
237948
|
+
}
|
|
237949
|
+
const out = /* @__PURE__ */ new Map();
|
|
237950
|
+
for (const list2 of byNode.values()) {
|
|
237951
|
+
list2.sort((a, b2) => a.createdAt.localeCompare(b2.createdAt) || a.id.localeCompare(b2.id));
|
|
237952
|
+
list2.forEach((w2, i) => out.set(w2.id, i + 1));
|
|
237953
|
+
}
|
|
237954
|
+
return out;
|
|
237955
|
+
}
|
|
237956
|
+
function latestVersionAt(snap, versions, nodeId, at2) {
|
|
237957
|
+
let best;
|
|
237958
|
+
for (const w2 of snap.works) {
|
|
237959
|
+
if (w2.nodeId !== nodeId || w2.createdAt > at2) continue;
|
|
237960
|
+
const v2 = versions.get(w2.id);
|
|
237961
|
+
if (v2 !== void 0 && (best === void 0 || v2 > best)) best = v2;
|
|
237962
|
+
}
|
|
237963
|
+
return best;
|
|
237964
|
+
}
|
|
237965
|
+
function versionPhrase(n) {
|
|
237966
|
+
return n !== void 0 ? `\u7B2C ${n} \u7248` : "";
|
|
237967
|
+
}
|
|
237968
|
+
var init_activity_version = __esm({
|
|
237969
|
+
"../server/src/domains/collab/activity-version.ts"() {
|
|
237970
|
+
"use strict";
|
|
237971
|
+
}
|
|
237972
|
+
});
|
|
237973
|
+
|
|
237974
|
+
// ../server/src/domains/collab/stall-copy.ts
|
|
237975
|
+
function isNotDoneCode(code2) {
|
|
237976
|
+
return !!code2 && NOT_DONE_CODES.has(code2);
|
|
237977
|
+
}
|
|
237978
|
+
function notDoneCopy(code2, facts = {}) {
|
|
237979
|
+
switch (code2) {
|
|
237980
|
+
case "no-output":
|
|
237981
|
+
return { reason: "\u8FD9\u4E00\u8F6E\u6CA1\u6709\u4EA4\u51FA\u4EFB\u4F55\u6210\u679C", fix: "\u91CD\u65B0\u8FD0\u884C\uFF0C\u6216\u6539\u7528\u4E0A\u4E00\u7248\u6210\u679C" };
|
|
237982
|
+
case "work-dead":
|
|
237983
|
+
return { reason: facts.deadReason ? `\u8FD9\u4E00\u8F6E\u5DF2\u7ECF\u88AB\u505C\u6389\uFF08${facts.deadReason}\uFF09` : "\u8FD9\u4E00\u8F6E\u5DF2\u7ECF\u88AB\u505C\u6389", fix: "\u91CD\u65B0\u8FD0\u884C" };
|
|
237984
|
+
case "work-in-flight":
|
|
237985
|
+
return { reason: "\u8FD9\u4E00\u8F6E\u8FD8\u5728\u8FD0\u884C\uFF0C\u8FD8\u6CA1\u6709\u4EA4\u51FA\u6210\u679C", fix: "\u7B49\u5B83\u505A\u5B8C\uFF0C\u6216\u5148\u505C\u6389\u518D\u91CD\u65B0\u8FD0\u884C" };
|
|
237986
|
+
case "not-latest-work":
|
|
237987
|
+
return facts.selectedVersion !== void 0 && facts.latestVersion !== void 0 ? { reason: `\u9009\u4E2D\u7684\u662F\u7B2C ${facts.selectedVersion} \u7248\uFF0C\u6700\u65B0\u7684\u662F\u7B2C ${facts.latestVersion} \u7248`, fix: `\u6539\u7528\u7B2C ${facts.latestVersion} \u7248` } : { reason: "\u9009\u4E2D\u7684\u4E0D\u662F\u6700\u65B0\u7684\u4E00\u7248", fix: "\u6539\u7528\u6700\u65B0\u7684\u4E00\u7248" };
|
|
237988
|
+
case "handoff-undeclared":
|
|
237989
|
+
return { reason: "\u6267\u884C\u4EBA\u8BF4\u660E\u8FD9\u4E00\u8F6E\u6CA1\u6709\u505A\u5B8C", fix: "\u91CD\u65B0\u8FD0\u884C" };
|
|
237990
|
+
case "work-not-success":
|
|
237991
|
+
return { reason: "\u8FD9\u4E00\u7248\u662F\u8FD0\u884C\u5931\u8D25\u65F6\u7559\u4E0B\u7684", fix: "\u786E\u8BA4\u5185\u5BB9\u53EF\u7528\u5C31\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\uFF0C\u5426\u5219\u91CD\u65B0\u8FD0\u884C" };
|
|
237992
|
+
case "no-conclude":
|
|
237993
|
+
return { reason: "\u6267\u884C\u4EBA\u53EA\u63D0\u4EA4\u4E86\u9636\u6BB5\u6210\u679C\uFF0C\u6CA1\u6709\u8BF4\u660E\u5DF2\u7ECF\u505A\u5B8C\uFF0C\u6240\u4EE5\u6CA1\u6709\u8FDB\u5165\u5BA1\u6838", fix: "\u91CD\u65B0\u8FD0\u884C\u8BA9\u5B83\u505A\u5B8C\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210" };
|
|
237994
|
+
case "no-reviewers":
|
|
237995
|
+
return { reason: "\u8FD9\u4E00\u6B65\u6CA1\u6709\u914D\u5230\u5BA1\u6838\u4EBA", fix: "\u7ED9\u8FD9\u4E00\u6B65\u6307\u5B9A\u5BA1\u6838\u4EBA" };
|
|
237996
|
+
case "already-accepted":
|
|
237997
|
+
return { reason: "\u8FD9\u4E00\u7248\u5DF2\u7ECF\u7B97\u5B8C\u6210\u4E86", fix: "\u4E0D\u7528\u518D\u5904\u7406" };
|
|
237998
|
+
case "work-missing":
|
|
237999
|
+
case "node-missing":
|
|
238000
|
+
return { reason: "\u7CFB\u7EDF\u627E\u4E0D\u5230\u8FD9\u4E00\u8F6E\u7684\u8BB0\u5F55", fix: "\u91CD\u65B0\u8FD0\u884C" };
|
|
238001
|
+
case "not-converged":
|
|
238002
|
+
return void 0;
|
|
238003
|
+
}
|
|
238004
|
+
}
|
|
238005
|
+
function stallCodeOfSource(source) {
|
|
238006
|
+
if (!source?.startsWith(STALL_PREFIX)) return void 0;
|
|
238007
|
+
const code2 = source.slice(STALL_PREFIX.length).split(":")[1];
|
|
238008
|
+
return code2 || void 0;
|
|
238009
|
+
}
|
|
238010
|
+
function legacyNotDoneCodeOf(body2) {
|
|
238011
|
+
const t = body2.replace(/\*\*/g, "");
|
|
238012
|
+
if (/这一版已结束但没有任何产出/.test(t)) return "no-output";
|
|
238013
|
+
if (/这一版已作废(/.test(t)) return "work-dead";
|
|
238014
|
+
if (/这一版还在跑、且还没有任何产出/.test(t)) return "work-in-flight";
|
|
238015
|
+
if (/不是本节点最新版(/.test(t)) return "not-latest-work";
|
|
238016
|
+
if (/执行人明确声明本轮未交付/.test(t)) return "handoff-undeclared";
|
|
238017
|
+
if (/这一版不是有效产出(/.test(t)) return "work-not-success";
|
|
238018
|
+
if (/已是验收态(/.test(t)) return "already-accepted";
|
|
238019
|
+
if (/^work 不在册:/m.test(t)) return "work-missing";
|
|
238020
|
+
if (/^节点不在册:/m.test(t)) return "node-missing";
|
|
238021
|
+
if (/已经交了稿,但没有收口/.test(t)) return "no-conclude";
|
|
238022
|
+
if (/没有配到任何评审人/.test(t)) return "no-reviewers";
|
|
238023
|
+
return void 0;
|
|
238024
|
+
}
|
|
238025
|
+
function parseStallBody(body2) {
|
|
238026
|
+
const t = body2.replace(/\*\*/g, "");
|
|
238027
|
+
const num5 = (...res) => {
|
|
238028
|
+
for (const re of res) {
|
|
238029
|
+
const m2 = re.exec(t)?.[1];
|
|
238030
|
+
if (m2 !== void 0) return Number(m2);
|
|
238031
|
+
}
|
|
238032
|
+
return void 0;
|
|
238033
|
+
};
|
|
238034
|
+
const rounds = num5(
|
|
238035
|
+
/连续被评审打回\s*(\d+)\s*轮/,
|
|
238036
|
+
/连续\s*(\d+)\s*次审核不通过/,
|
|
238037
|
+
// 打回到上限:旧 / 新
|
|
238038
|
+
/连续\s*(\d+)\s*轮没有新增交付内容/,
|
|
238039
|
+
/连续\s*(\d+)\s*轮提交的内容都没有变化/,
|
|
238040
|
+
// 无进展上限:旧 / 新
|
|
238041
|
+
/派出去\s*(\d+)\s*次都没等到票/,
|
|
238042
|
+
/审核发起了\s*(\d+)\s*次都没有等到结果/
|
|
238043
|
+
// 审核等不到结果:旧 / 新
|
|
238044
|
+
);
|
|
238045
|
+
const reviewer = /当前是\s*([^))\s]+)/.exec(t)?.[1];
|
|
238046
|
+
const dead = /已作废([^:)]*:([^)\n]+))/.exec(t)?.[1] ?? /已经被停掉(([^\n]+))/.exec(t)?.[1];
|
|
238047
|
+
const latestProposed = /最新有效产出:([^);\s]+)/.exec(t)?.[1];
|
|
238048
|
+
return {
|
|
238049
|
+
...rounds !== void 0 ? { rounds } : {},
|
|
238050
|
+
...reviewer ? { reviewerActorId: reviewer } : {},
|
|
238051
|
+
...dead?.trim() ? { deadReason: dead.trim() } : {},
|
|
238052
|
+
...latestProposed && latestProposed !== "\u65E0" ? { latestProposedWorkId: latestProposed } : {}
|
|
238053
|
+
};
|
|
238054
|
+
}
|
|
238055
|
+
function stallCardCopy(kind, source, body2, ctx) {
|
|
238056
|
+
const facts = parseStallBody(body2);
|
|
238057
|
+
const x2 = ctx.node;
|
|
238058
|
+
const notDone = (code2) => {
|
|
238059
|
+
const copy = code2 ? notDoneCopy(code2, {
|
|
238060
|
+
...facts.deadReason ? { deadReason: facts.deadReason } : {},
|
|
238061
|
+
...ctx.selectedVersion !== void 0 ? { selectedVersion: ctx.selectedVersion } : {},
|
|
238062
|
+
.../* @__PURE__ */ ((v2) => v2 !== void 0 ? { latestVersion: v2 } : {})(
|
|
238063
|
+
facts.latestProposedWorkId ? ctx.versionOfWork?.(facts.latestProposedWorkId) : void 0
|
|
238064
|
+
)
|
|
238065
|
+
}) : void 0;
|
|
238066
|
+
return copy ? { headline: `\u300A${x2}\u300B\u8FD9\u4E00\u8F6E\u7ED3\u675F\u4E86\uFF0C\u4F46\u8FD8\u4E0D\u80FD\u7B97\u5B8C\u6210\uFF1A${copy.reason}\u3002`, action: `${copy.fix}\u3002` } : { headline: `\u300A${x2}\u300B\u8FD9\u4E00\u8F6E\u7ED3\u675F\u4E86\uFF0C\u4F46\u8FD8\u4E0D\u80FD\u7B97\u5B8C\u6210\u3002`, action: "\u91CD\u65B0\u8FD0\u884C\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002" };
|
|
238067
|
+
};
|
|
238068
|
+
const sourceCode = stallCodeOfSource(source);
|
|
238069
|
+
switch (kind) {
|
|
238070
|
+
case "stall_gate_rejections_exhausted":
|
|
238071
|
+
return {
|
|
238072
|
+
headline: ctx.latestVersion !== void 0 && facts.rounds !== void 0 ? `\u300A${x2}\u300B\u5DF2\u4EA4\u5230\u7B2C ${ctx.latestVersion} \u7248\uFF0C\u8FDE\u7EED ${facts.rounds} \u6B21\u5BA1\u6838\u4E0D\u901A\u8FC7\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u8FD4\u5DE5\u3002` : facts.rounds !== void 0 ? `\u300A${x2}\u300B\u8FDE\u7EED ${facts.rounds} \u6B21\u5BA1\u6838\u4E0D\u901A\u8FC7\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u8FD4\u5DE5\u3002` : `\u300A${x2}\u300B\u8FDE\u7EED\u591A\u6B21\u5BA1\u6838\u4E0D\u901A\u8FC7\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u8FD4\u5DE5\u3002`,
|
|
238073
|
+
action: "\u5148\u770B\u5BA1\u6838\u610F\u89C1\u548C\u6267\u884C\u4EBA\u6BCF\u6B21\u4EA4\u7684\u5185\u5BB9\uFF08\u591A\u534A\u662F\u5185\u5BB9\u6CA1\u6709\u5B9E\u8D28\u53D8\u5316\uFF09\uFF0C\u518D\u9009\u62E9\uFF1A\u91CD\u65B0\u8FD0\u884C\u3001\u6362\u6267\u884C\u4EBA\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002"
|
|
238074
|
+
};
|
|
238075
|
+
case "stall_checkpoints_exhausted":
|
|
238076
|
+
return {
|
|
238077
|
+
headline: facts.rounds !== void 0 ? `\u300A${x2}\u300B\u8FDE\u7EED ${facts.rounds} \u8F6E\u63D0\u4EA4\u7684\u5185\u5BB9\u90FD\u6CA1\u6709\u53D8\u5316\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u7EE7\u7EED\u6267\u884C\u3002` : `\u300A${x2}\u300B\u8FDE\u7EED\u51E0\u8F6E\u63D0\u4EA4\u7684\u5185\u5BB9\u90FD\u6CA1\u6709\u53D8\u5316\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u7EE7\u7EED\u6267\u884C\u3002`,
|
|
238078
|
+
action: "\u5148\u770B\u6700\u8FD1\u63D0\u4EA4\u7684\u5185\u5BB9\u548C\u8FD8\u5269\u54EA\u4E9B\u6CA1\u505A\uFF0C\u8865\u5145\u8BF4\u660E\u540E\u91CD\u65B0\u8FD0\u884C\uFF1B\u5982\u679C\u5176\u5B9E\u5DF2\u7ECF\u505A\u5B8C\uFF0C\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002"
|
|
238079
|
+
};
|
|
238080
|
+
case "stall_review_exhausted":
|
|
238081
|
+
return {
|
|
238082
|
+
headline: facts.rounds !== void 0 ? `\u300A${x2}\u300B\u7684\u5BA1\u6838\u53D1\u8D77\u4E86 ${facts.rounds} \u6B21\u90FD\u6CA1\u6709\u7B49\u5230\u7ED3\u679C\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u91CD\u65B0\u53D1\u8D77\u3002` : `\u300A${x2}\u300B\u7684\u5BA1\u6838\u53D1\u8D77\u4E86\u51E0\u6B21\u90FD\u6CA1\u6709\u7B49\u5230\u7ED3\u679C\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u91CD\u65B0\u53D1\u8D77\u3002`,
|
|
238083
|
+
action: facts.reviewerActorId ? `\u91CD\u65B0\u53D1\u8D77\u8FD9\u4E00\u8F6E\u5BA1\u6838\u3001\u6362\u4E00\u4E2A\u5BA1\u6838\u4EBA\uFF08\u5F53\u524D\u662F ${ctx.nameOf(facts.reviewerActorId)}\uFF09\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002` : "\u91CD\u65B0\u53D1\u8D77\u8FD9\u4E00\u8F6E\u5BA1\u6838\u3001\u6362\u4E00\u4E2A\u5BA1\u6838\u4EBA\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002"
|
|
238084
|
+
};
|
|
238085
|
+
case "stall_accept_blocked":
|
|
238086
|
+
return notDone(isNotDoneCode(sourceCode) ? sourceCode : legacyNotDoneCodeOf(body2));
|
|
238087
|
+
case "stall_idle_unexplained": {
|
|
238088
|
+
const code2 = isNotDoneCode(sourceCode) ? sourceCode : legacyNotDoneCodeOf(body2);
|
|
238089
|
+
if (code2 === "no-conclude" || code2 === "no-reviewers") return notDone(code2);
|
|
238090
|
+
return { headline: `\u300A${x2}\u300B\u505A\u5B8C\u4E4B\u540E\u957F\u65F6\u95F4\u6CA1\u6709\u52A8\u9759\uFF0C\u7CFB\u7EDF\u627E\u4E0D\u5230\u539F\u56E0\u3002`, action: "\u9700\u8981\u4F60\u770B\u4E00\u4E0B\u5B83\u5361\u5728\u54EA\u91CC\u3002" };
|
|
238091
|
+
}
|
|
238092
|
+
}
|
|
238093
|
+
}
|
|
238094
|
+
var NOT_DONE_CODES, STALL_PREFIX;
|
|
238095
|
+
var init_stall_copy = __esm({
|
|
238096
|
+
"../server/src/domains/collab/stall-copy.ts"() {
|
|
238097
|
+
"use strict";
|
|
238098
|
+
NOT_DONE_CODES = /* @__PURE__ */ new Set([
|
|
238099
|
+
"work-missing",
|
|
238100
|
+
"node-missing",
|
|
238101
|
+
"work-dead",
|
|
238102
|
+
"already-accepted",
|
|
238103
|
+
"work-in-flight",
|
|
238104
|
+
"no-output",
|
|
238105
|
+
"not-latest-work",
|
|
238106
|
+
"work-not-success",
|
|
238107
|
+
"handoff-undeclared",
|
|
238108
|
+
"not-converged",
|
|
238109
|
+
"no-conclude",
|
|
238110
|
+
"no-reviewers"
|
|
238111
|
+
]);
|
|
238112
|
+
STALL_PREFIX = "sla:stall:";
|
|
238113
|
+
}
|
|
238114
|
+
});
|
|
238115
|
+
|
|
237837
238116
|
// ../server/src/domains/collab/activity.ts
|
|
237838
238117
|
function coordinatorCardGapId(cardId) {
|
|
237839
238118
|
return cardId.startsWith(COORDINATOR_CARD_PREFIX) ? cardId.slice(COORDINATOR_CARD_PREFIX.length) : void 0;
|
|
@@ -237848,13 +238127,6 @@ function gapEvalsOf(body2) {
|
|
|
237848
238127
|
const n = /评估了\s*(\d+)\s*次/.exec(body2)?.[1];
|
|
237849
238128
|
return n !== void 0 ? Number(n) : void 0;
|
|
237850
238129
|
}
|
|
237851
|
-
function stallCardCopyOf(body2) {
|
|
237852
|
-
const paras = body2.split(/\n{2,}/).map((p2) => p2.replace(/\*\*/g, "").trim()).filter(Boolean);
|
|
237853
|
-
const headline = paras[0] && !paras[0].startsWith("\u9700\u8981\u4F60") ? paras[0] : void 0;
|
|
237854
|
-
const actionPara = paras.slice(1).reverse().find((p2) => p2.startsWith("\u9700\u8981\u4F60"));
|
|
237855
|
-
const action = actionPara?.replace(/^需要你处理[::]\s*/, "");
|
|
237856
|
-
return { ...headline ? { headline } : {}, ...action ? { action } : {} };
|
|
237857
|
-
}
|
|
237858
238130
|
function parseStopLossFacts(kind, body2) {
|
|
237859
238131
|
if (kind === "retry_exhausted") {
|
|
237860
238132
|
const n2 = /连续\s*(\d+)\s*次执行失败/.exec(body2)?.[1];
|
|
@@ -237901,6 +238173,8 @@ function buildWorkorderActivity(input) {
|
|
|
237901
238173
|
const nodeById = new Map(snap.nodes.map((n) => [n.id, n]));
|
|
237902
238174
|
const workById = new Map(snap.works.map((w2) => [w2.id, w2]));
|
|
237903
238175
|
const issueById = new Map(snap.issues.map((i) => [i.id, i]));
|
|
238176
|
+
const versionOf2 = outputVersionNumbers(snap);
|
|
238177
|
+
const versionOfWork = (workId) => workId ? versionOf2.get(workId) : void 0;
|
|
237904
238178
|
const nodesWithInEdges = new Set(snap.edges.map((e) => e.toNodeId));
|
|
237905
238179
|
const rootBriefNodeIds = new Set(
|
|
237906
238180
|
snap.nodes.filter((n) => n.type === "brief" && !nodesWithInEdges.has(n.id)).map((n) => n.id)
|
|
@@ -238366,15 +238640,15 @@ function buildWorkorderActivity(input) {
|
|
|
238366
238640
|
} else {
|
|
238367
238641
|
const finalReviewers = node2?.isFinalOutput ? expectedReviewers(nodeId) : [];
|
|
238368
238642
|
if (node2?.isFinalOutput && finalReviewers.length > 0) {
|
|
238369
|
-
card2.status = ACTIVITY_COPY.finalDelivered(nameOf2(finalReviewers[0]));
|
|
238643
|
+
card2.status = ACTIVITY_COPY.finalDelivered(nameOf2(finalReviewers[0]), versionOfWork(w2.id));
|
|
238370
238644
|
} else {
|
|
238371
238645
|
const awaits = snap.reviews.some((r) => r.targetWorkId === w2.id) || nodesWithRequirement.has(nodeId);
|
|
238372
|
-
card2.status = awaits ? ACTIVITY_COPY.doneAwaitingReview(name) : ACTIVITY_COPY.done(name);
|
|
238646
|
+
card2.status = awaits ? ACTIVITY_COPY.doneAwaitingReview(name, versionOfWork(w2.id)) : ACTIVITY_COPY.done(name, versionOfWork(w2.id));
|
|
238373
238647
|
}
|
|
238374
238648
|
}
|
|
238375
238649
|
const bpRaisers = backpressureRaisersOf(w2.id);
|
|
238376
|
-
if (bpRaisers && (card2.status === ACTIVITY_COPY.done(name) || card2.status === ACTIVITY_COPY.goalConfirmed || card2.status === ACTIVITY_COPY.goalRevised)) {
|
|
238377
|
-
card2.status = ACTIVITY_COPY.backpressureAddressed(bpRaisers, backpressureTargetName(nodeId));
|
|
238650
|
+
if (bpRaisers && (card2.status === ACTIVITY_COPY.done(name, versionOfWork(w2.id)) || card2.status === ACTIVITY_COPY.goalConfirmed || card2.status === ACTIVITY_COPY.goalRevised)) {
|
|
238651
|
+
card2.status = ACTIVITY_COPY.backpressureAddressed(bpRaisers, backpressureTargetName(nodeId), versionOfWork(w2.id));
|
|
238378
238652
|
}
|
|
238379
238653
|
} else if (interrupt) {
|
|
238380
238654
|
card2.phase = "stuck";
|
|
@@ -238400,7 +238674,7 @@ function buildWorkorderActivity(input) {
|
|
|
238400
238674
|
card2.phase = "stuck";
|
|
238401
238675
|
card2.segmentOpen = false;
|
|
238402
238676
|
const editor = openerOfWork.get(supersededBy.workId);
|
|
238403
|
-
card2.status = rootBriefNodeIds.has(supersededBy.upstreamNodeId) && editor && !isSystemActorId(editor) ? ACTIVITY_COPY.interruptedBySpecChange(nameOf2(editor), name) : ACTIVITY_COPY.interruptedByUpstreamVersion(nodeName(supersededBy.upstreamNodeId), name);
|
|
238677
|
+
card2.status = rootBriefNodeIds.has(supersededBy.upstreamNodeId) && editor && !isSystemActorId(editor) ? ACTIVITY_COPY.interruptedBySpecChange(nameOf2(editor), name) : ACTIVITY_COPY.interruptedByUpstreamVersion(nodeName(supersededBy.upstreamNodeId), name, versionOfWork(supersededBy.workId));
|
|
238404
238678
|
} else if (removedHere || killedByPlan) {
|
|
238405
238679
|
card2.phase = "stuck";
|
|
238406
238680
|
card2.segmentOpen = false;
|
|
@@ -238419,7 +238693,7 @@ function buildWorkorderActivity(input) {
|
|
|
238419
238693
|
fold2 = foldableFailure ? card2 : null;
|
|
238420
238694
|
} else if (ackedRound) {
|
|
238421
238695
|
card2.phase = "done";
|
|
238422
|
-
card2.status = ACTIVITY_COPY.upstreamAcked(name);
|
|
238696
|
+
card2.status = ACTIVITY_COPY.upstreamAcked(name, versionOfWork(w2.upstreamAck?.acceptedWorkId));
|
|
238423
238697
|
} else if (batchEnd) {
|
|
238424
238698
|
card2.phase = "done";
|
|
238425
238699
|
card2.segmentOpen = false;
|
|
@@ -238499,7 +238773,7 @@ function buildWorkorderActivity(input) {
|
|
|
238499
238773
|
d.phase = "done";
|
|
238500
238774
|
d.actions = [];
|
|
238501
238775
|
d.executorId = subjectId;
|
|
238502
|
-
d.status = addressed ? ACTIVITY_COPY.commentAddressed(nameOf2(subjectId), nameOf2(authorId), nodeName(d.nodeId)) : ACTIVITY_COPY.commentResolved(nameOf2(subjectId), nodeName(d.nodeId));
|
|
238776
|
+
d.status = addressed ? ACTIVITY_COPY.commentAddressed(nameOf2(subjectId), nameOf2(authorId), nodeName(d.nodeId), versionOfWork(drivenWork.id)) : ACTIVITY_COPY.commentResolved(nameOf2(subjectId), nodeName(d.nodeId));
|
|
238503
238777
|
};
|
|
238504
238778
|
for (const rec2 of events) {
|
|
238505
238779
|
const ev = rec2.event;
|
|
@@ -238626,7 +238900,7 @@ function buildWorkorderActivity(input) {
|
|
|
238626
238900
|
const bypassed = reviewers.length > 0 && isSystemAccept(by) && !voted;
|
|
238627
238901
|
if (isSystemAccept(by) && !bypassed) break;
|
|
238628
238902
|
const existing = acceptCards.get(workId);
|
|
238629
|
-
const status = bypassed ? node2?.isFinalOutput ? ACTIVITY_COPY.autoAccepted(nameOf2(reviewers[0])) : ACTIVITY_COPY.autoAcceptedNode(nodeName(nodeId), nameOf2(reviewers[0])) : node2?.isFinalOutput ? ACTIVITY_COPY.accepted : ACTIVITY_COPY.acceptedNode(nodeName(nodeId));
|
|
238903
|
+
const status = bypassed ? node2?.isFinalOutput ? ACTIVITY_COPY.autoAccepted(nameOf2(reviewers[0])) : ACTIVITY_COPY.autoAcceptedNode(nodeName(nodeId), nameOf2(reviewers[0])) : node2?.isFinalOutput ? ACTIVITY_COPY.accepted(versionOfWork(workId)) : ACTIVITY_COPY.acceptedNode(nodeName(nodeId), versionOfWork(workId));
|
|
238630
238904
|
if (existing) {
|
|
238631
238905
|
touch(existing, rec2);
|
|
238632
238906
|
existing.executorId = bypassed ? reviewers[0] : by;
|
|
@@ -238877,11 +239151,17 @@ function buildWorkorderActivity(input) {
|
|
|
238877
239151
|
const ids2 = comments.map((c) => c.id);
|
|
238878
239152
|
const closures = ids2.map(closureOf);
|
|
238879
239153
|
const works = [...new Set(ids2.flatMap((id) => worksOfComment.get(id) ?? []))];
|
|
239154
|
+
let updatedVersion;
|
|
238880
239155
|
const outcomeOf = (id, cl) => {
|
|
238881
239156
|
if (!cl.wontfix) {
|
|
238882
239157
|
const driven = cl.viaWorkId ? workById.get(cl.viaWorkId) : void 0;
|
|
238883
239158
|
const drivers = driven ? [driven] : [...(worksOfComment.get(id) ?? []).filter((w2) => w2.createdAt <= cl.at), ...closingRoundsOf(first.nodeId, cl)];
|
|
238884
|
-
if (drivers.some(deliveredNewVersion))
|
|
239159
|
+
if (drivers.some(deliveredNewVersion)) {
|
|
239160
|
+
for (const v2 of drivers.map((w2) => versionOfWork(w2.id))) {
|
|
239161
|
+
if (v2 !== void 0 && (updatedVersion === void 0 || v2 > updatedVersion)) updatedVersion = v2;
|
|
239162
|
+
}
|
|
239163
|
+
return 5;
|
|
239164
|
+
}
|
|
238885
239165
|
}
|
|
238886
239166
|
if (cl.by && cl.by === first.authorId && cl.by !== executorId) return 1;
|
|
238887
239167
|
if (!cl.by) return 2;
|
|
@@ -238893,7 +239173,7 @@ function buildWorkorderActivity(input) {
|
|
|
238893
239173
|
phase = "done";
|
|
238894
239174
|
const best = Math.max(...ids2.map((id, i) => outcomeOf(id, closures[i])));
|
|
238895
239175
|
const nodeRemoved = !!(first.nodeId && nodeById.get(first.nodeId)?.cancelledAt);
|
|
238896
|
-
status = best === 5 ? ACTIVITY_COPY.commentUpdated(author, node2) : best === 4 ? ACTIVITY_COPY.commentReplied(author) : best === 3 ? ACTIVITY_COPY.commentViewed(author) : best === 1 ? ACTIVITY_COPY.commentWithdrawn(author) : input.workorderTerminal ? ACTIVITY_COPY.closedNoAction(input.workorderTerminal) : nodeRemoved ? ACTIVITY_COPY.commentNodeRemoved(node2) : ACTIVITY_COPY.commentViewed(author);
|
|
239176
|
+
status = best === 5 ? ACTIVITY_COPY.commentUpdated(author, node2, updatedVersion) : best === 4 ? ACTIVITY_COPY.commentReplied(author) : best === 3 ? ACTIVITY_COPY.commentViewed(author) : best === 1 ? ACTIVITY_COPY.commentWithdrawn(author) : input.workorderTerminal ? ACTIVITY_COPY.closedNoAction(input.workorderTerminal) : nodeRemoved ? ACTIVITY_COPY.commentNodeRemoved(node2) : ACTIVITY_COPY.commentViewed(author);
|
|
238897
239177
|
} else if (works.some((w2) => workRunning(w2) && ids2.some((id, i) => !closures[i] && worksOfComment.get(id)?.includes(w2)))) {
|
|
238898
239178
|
phase = "running";
|
|
238899
239179
|
status = ACTIVITY_COPY.commentInProgress(author);
|
|
@@ -238929,7 +239209,17 @@ function buildWorkorderActivity(input) {
|
|
|
238929
239209
|
return escalationKindOf(x2.id, row?.authorActorId ?? x2.authorId, row?.source ?? x2.source ?? null);
|
|
238930
239210
|
};
|
|
238931
239211
|
const kind = kindOf3(e);
|
|
238932
|
-
const stallCopy = isStallEscalation(kind)
|
|
239212
|
+
const stallCopy = isStallEscalation(kind) && e.nodeId ? (() => {
|
|
239213
|
+
const row = issueById.get(e.id);
|
|
239214
|
+
const selected = [...allRoundsOfNode.get(e.nodeId) ?? []].filter((w2) => w2.createdAt <= e.at).at(-1);
|
|
239215
|
+
return stallCardCopy(kind, row?.source ?? e.source, row?.body ?? "", {
|
|
239216
|
+
node: nodeName(e.nodeId),
|
|
239217
|
+
.../* @__PURE__ */ ((v2) => v2 !== void 0 ? { latestVersion: v2 } : {})(latestVersionAt(snap, versionOf2, e.nodeId, e.at)),
|
|
239218
|
+
.../* @__PURE__ */ ((v2) => v2 !== void 0 ? { selectedVersion: v2 } : {})(versionOfWork(selected?.id)),
|
|
239219
|
+
versionOfWork: (id) => versionOf2.get(id),
|
|
239220
|
+
nameOf: (id) => nameOf2(id)
|
|
239221
|
+
});
|
|
239222
|
+
})() : void 0;
|
|
238933
239223
|
const resolvedAt = (id) => issueById.get(id)?.resolvedAt ?? null;
|
|
238934
239224
|
const closedAt = resolvedAt(e.id);
|
|
238935
239225
|
const open3 = !closedAt;
|
|
@@ -238945,8 +239235,8 @@ function buildWorkorderActivity(input) {
|
|
|
238945
239235
|
const gapId = issueById.get(id)?.gapId;
|
|
238946
239236
|
return typeof gapId === "string" && !!issueById.get(gapId);
|
|
238947
239237
|
};
|
|
238948
|
-
const head = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHeadRetryExhausted(nodeName(e.nodeId)) : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHeadReviewExhausted(nodeName(e.nodeId)) : kind === "output_stall" ? ACTIVITY_COPY.escalationHeadOutputStall(nodeName(e.nodeId)) :
|
|
238949
|
-
const howTo = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHowToRetryExhausted : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHowToReviewExhausted : kind === "output_stall" ? ACTIVITY_COPY.escalationHowToOutputStall :
|
|
239238
|
+
const head = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHeadRetryExhausted(nodeName(e.nodeId)) : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHeadReviewExhausted(nodeName(e.nodeId)) : kind === "output_stall" ? ACTIVITY_COPY.escalationHeadOutputStall(nodeName(e.nodeId)) : isStallEscalation(kind) ? stallCopy?.headline ?? ACTIVITY_COPY.escalationHeadStall(nodeName(e.nodeId)) : kind === "sla_breaker" ? ACTIVITY_COPY.escalationHeadSlaBreaker(nodeName(e.nodeId)) : kind === "quota_starvation" ? ACTIVITY_COPY.escalationHeadQuotaStarvation(nodeName(e.nodeId)) : kind === "reviewer_unavailable" ? ACTIVITY_COPY.escalationHeadReviewerUnavailable(nodeName(e.nodeId)) : kind === "gap_evals_exhausted" ? ACTIVITY_COPY.escalationHeadGapEvalsExhausted(nodeName(e.nodeId), gapEvalsOf(issueById.get(e.id)?.body ?? "")) : kind === "dispatch_missing_node" ? ACTIVITY_COPY.escalationHeadDispatchMissingNode(nodeName(e.nodeId)) : gapBehind(e.id) ? ACTIVITY_COPY.escalationHeadGapEscalated(nameOf2(e.authorId), nodeName(e.nodeId)) : ACTIVITY_COPY.escalationHeadManual(nameOf2(stuckActor));
|
|
239239
|
+
const howTo = kind === "retry_exhausted" ? ACTIVITY_COPY.escalationHowToRetryExhausted : kind === "review_exhausted" ? ACTIVITY_COPY.escalationHowToReviewExhausted : kind === "output_stall" ? ACTIVITY_COPY.escalationHowToOutputStall : isStallEscalation(kind) ? stallCopy?.action : kind === "sla_breaker" ? ACTIVITY_COPY.escalationHowToSlaBreaker : kind === "quota_starvation" ? ACTIVITY_COPY.escalationHowToQuotaStarvation : kind === "reviewer_unavailable" ? ACTIVITY_COPY.escalationHowToReviewerUnavailable : kind === "gap_evals_exhausted" ? ACTIVITY_COPY.escalationHowToGapEvalsExhausted : kind === "dispatch_missing_node" ? ACTIVITY_COPY.escalationHowToDispatchMissingNode : void 0;
|
|
238950
239240
|
const closing = issueById.get(e.id);
|
|
238951
239241
|
const closeEvent = plainResolveEvents.get(e.id);
|
|
238952
239242
|
const closedBy = text5(closing?.resolvedBy) ?? closeEvent?.by ?? target;
|
|
@@ -239021,7 +239311,7 @@ function buildWorkorderActivity(input) {
|
|
|
239021
239311
|
const pending = f2.decision === "pending" && !f2.acceptedAt && !removed;
|
|
239022
239312
|
const paused = f2.decision === "denied" && !f2.releasedAt && !f2.acceptedAt && !removed;
|
|
239023
239313
|
const open3 = pending || paused;
|
|
239024
|
-
const status = f2.acceptedAt ? ACTIVITY_COPY.continuationOutputAccepted(nameOf2(signer), name) : f2.resumedAt ? ACTIVITY_COPY.continuationResumed(nameOf2(signer), f2.resumeRounds ?? f2.rounds) : f2.decision === "approved" ? ACTIVITY_COPY.continuationApproved(nameOf2(signer), f2.rounds) : removed ? ACTIVITY_COPY.continuationNodeRemoved : f2.decision === "completed" ? ACTIVITY_COPY.continuationSettled(name) : paused ? ACTIVITY_COPY.continuationDenied(nameOf2(signer), f2.reason) : ACTIVITY_COPY.continuationPending(name, f2.batchRounds, nameOf2(signer));
|
|
239314
|
+
const status = f2.acceptedAt ? ACTIVITY_COPY.continuationOutputAccepted(nameOf2(signer), name, versionOfWork(f2.acceptedWorkId)) : f2.resumedAt ? ACTIVITY_COPY.continuationResumed(nameOf2(signer), f2.resumeRounds ?? f2.rounds) : f2.decision === "approved" ? ACTIVITY_COPY.continuationApproved(nameOf2(signer), f2.rounds) : removed ? ACTIVITY_COPY.continuationNodeRemoved(name) : f2.decision === "completed" ? ACTIVITY_COPY.continuationSettled(name) : paused ? ACTIVITY_COPY.continuationDenied(nameOf2(signer), f2.reason) : ACTIVITY_COPY.continuationPending(name, f2.batchRounds, nameOf2(signer));
|
|
239025
239315
|
continuationCards.push({
|
|
239026
239316
|
id: f2.id,
|
|
239027
239317
|
seq: f2.seq,
|
|
@@ -239036,7 +239326,7 @@ function buildWorkorderActivity(input) {
|
|
|
239036
239326
|
status,
|
|
239037
239327
|
detail: ACTIVITY_COPY.continuationRounds(f2.usedRounds, f2.authorizedRounds, f2.rounds),
|
|
239038
239328
|
artifacts: batchOutputOf.get(f2.id) ?? [],
|
|
239039
|
-
actions: !viewerMayDecide ? [] : pending ? [decide2(f2, "approve", "\u540C\u610F\u7EE7\u7EED", "primary"), decide2(f2, "accept_output", "\u63A5\u53D7\u5F53\u524D\u6210\u679C", "secondary"), decide2(f2, "pause", "\u5148\
|
|
239329
|
+
actions: !viewerMayDecide ? [] : pending ? [decide2(f2, "approve", "\u540C\u610F\u7EE7\u7EED", "primary"), decide2(f2, "accept_output", "\u63A5\u53D7\u5F53\u524D\u6210\u679C", "secondary"), decide2(f2, "pause", "\u5148\u4E0D\u7EE7\u7EED", "quiet")] : paused ? [decide2(f2, "resume", "\u7EE7\u7EED\u6267\u884C", "primary"), decide2(f2, "accept_output", "\u63A5\u53D7\u5F53\u524D\u6210\u679C", "secondary")] : []
|
|
239040
239330
|
});
|
|
239041
239331
|
}
|
|
239042
239332
|
}
|
|
@@ -239050,7 +239340,7 @@ function buildWorkorderActivity(input) {
|
|
|
239050
239340
|
const name = nodeName(nodeId);
|
|
239051
239341
|
const resolvedAt = gap.resolvedAt ?? null;
|
|
239052
239342
|
const inWindow2 = (at2) => !!at2 && at2 >= gap.createdAt && (!resolvedAt || at2 <= resolvedAt);
|
|
239053
|
-
const escalated = snap.issues.find((i) => i.kind === "escalation" && escalationKindOf(i.id, i.authorActorId, i.source)
|
|
239343
|
+
const escalated = snap.issues.find((i) => i.kind === "escalation" && /* @__PURE__ */ ((k2) => k2 === "manual" || k2 === "gap_evals_exhausted")(escalationKindOf(i.id, i.authorActorId, i.source)) && (i.gapId === gapId || (i.aboutNodeId ?? i.raisedByNodeId) === nodeId && inWindow2(i.createdAt)));
|
|
239054
239344
|
const run = coordinatorRunOfGap(
|
|
239055
239345
|
{ createdAt: gap.createdAt, resolvedAt },
|
|
239056
239346
|
(input.coordinatorRuns ?? []).filter((r) => !!r.id && r.nodeId === nodeId)
|
|
@@ -239147,7 +239437,7 @@ function buildWorkorderActivity(input) {
|
|
|
239147
239437
|
nodeId: w2.nodeId,
|
|
239148
239438
|
executorId: acceptor,
|
|
239149
239439
|
phase: "not_started",
|
|
239150
|
-
status: ACTIVITY_COPY.acceptPending,
|
|
239440
|
+
status: ACTIVITY_COPY.acceptPending(versionOfWork(w2.id)),
|
|
239151
239441
|
artifacts: artifactsByWork.get(w2.id) ?? [],
|
|
239152
239442
|
actions: [
|
|
239153
239443
|
{ kind: "accept", label: BUTTON.acceptPass, target: node2.id, revisionId: w2.id, verdict: "approve" },
|
|
@@ -239169,7 +239459,7 @@ function buildWorkorderActivity(input) {
|
|
|
239169
239459
|
reviewCards.set(cardId, group);
|
|
239170
239460
|
}
|
|
239171
239461
|
for (const [cardId, { workId, reviewerId, reviews }] of reviewCards) {
|
|
239172
|
-
const summary = reviewSummary(snap, reviews, events);
|
|
239462
|
+
const summary = reviewSummary(snap, reviews, events, versionOfWork(workId));
|
|
239173
239463
|
const first = reviews[0];
|
|
239174
239464
|
const ids2 = new Set(reviews.map((r) => r.id));
|
|
239175
239465
|
const created = events.filter((r) => r.event.kind === "review.create" && ids2.has(r.event.reviewId));
|
|
@@ -239184,7 +239474,7 @@ function buildWorkorderActivity(input) {
|
|
|
239184
239474
|
return [{
|
|
239185
239475
|
id: r.id,
|
|
239186
239476
|
// 同一个人担多个评审组时才标组号——单组标了纯属噪声(卡上本来就只有这一个人)。
|
|
239187
|
-
label: groups.length > 1 ? `\
|
|
239477
|
+
label: groups.length > 1 ? `\u5BA1\u6838\u7EC4 ${groups.indexOf(r.reviewGroup) + 1} \xB7 ${label2}` : label2,
|
|
239188
239478
|
text: text7,
|
|
239189
239479
|
tone: rejected ? "reject" : "note"
|
|
239190
239480
|
}];
|
|
@@ -239207,15 +239497,17 @@ function buildWorkorderActivity(input) {
|
|
|
239207
239497
|
/* 同一人担多个责任组时,展开区留一份**逐组结论**(只有判定词、没有意见正文)——小状态只有
|
|
239208
239498
|
一句总判定,说不清哪个组过了哪个组没过。意见正文一律走下面的意见条。 */
|
|
239209
239499
|
...summary.latest.length > 1 ? {
|
|
239210
|
-
detail: summary.latest.map((r) => `${nameOf2(r.reviewerActorId)}\uFF08\
|
|
239500
|
+
detail: summary.latest.map((r) => `${nameOf2(r.reviewerActorId)}\uFF08\u5BA1\u6838\u7EC4 ${groups.indexOf(r.reviewGroup) + 1}\uFF09\uFF1A${reviewLabel(r)}`).join("\n")
|
|
239211
239501
|
} : {},
|
|
239212
239502
|
...reviewNotes.length ? { reviewNotes } : {},
|
|
239213
239503
|
...reviewLine ? { reviewThreadSessionId: reviewLine } : {},
|
|
239214
239504
|
artifacts: artifactsByWork.get(workId) ?? [],
|
|
239505
|
+
/* 有审核线(有意见条)且没在等表态 ⇒ 给一颗「查看沟通」进审核线(奕璇 2026-09-29 审定清单第一节):
|
|
239506
|
+
意见条改成卡内「展开 / 收起」之后,去审核沟通页的入口从意见条右下角的「展开 ›」挪到这颗按钮上,落点不变。 */
|
|
239215
239507
|
actions: pending.length ? [
|
|
239216
239508
|
{ kind: "review", label: BUTTON.approve, target: first.nodeId, revisionId: workId, verdict: "approve" },
|
|
239217
239509
|
{ kind: "review", label: BUTTON.reject, target: first.nodeId, revisionId: workId, verdict: "request_changes" }
|
|
239218
|
-
] : []
|
|
239510
|
+
] : reviewLine ? [{ kind: "open_thread", label: BUTTON.view, target: reviewLine, variant: "quiet" }] : []
|
|
239219
239511
|
});
|
|
239220
239512
|
}
|
|
239221
239513
|
const openedSeq = events.find((rec2) => rec2.event.kind === "work.create")?.seq;
|
|
@@ -239337,6 +239629,8 @@ var init_activity2 = __esm({
|
|
|
239337
239629
|
init_review_requirement_activity();
|
|
239338
239630
|
init_workorder_manager();
|
|
239339
239631
|
init_escalation_recipient();
|
|
239632
|
+
init_activity_version();
|
|
239633
|
+
init_stall_copy();
|
|
239340
239634
|
ACTIVITY_EVENT_KINDS = [
|
|
239341
239635
|
"plan.changed",
|
|
239342
239636
|
"plan.update_review_requirements",
|
|
@@ -239382,9 +239676,9 @@ var init_activity2 = __esm({
|
|
|
239382
239676
|
* 别复用 `goalChanged`(「{X} 修改了任务目标。」)——那句锚在 `workorder.meta_changed` 上,
|
|
239383
239677
|
* 说的是「改了工单 meta 上的 goal 字段」,跟「brief 正文重新收口」不是同一动作。
|
|
239384
239678
|
*/
|
|
239385
|
-
goalRevised: "\u5DF2\u4FEE\u8BA2\
|
|
239679
|
+
goalRevised: "\u76EE\u6807\u5DF2\u4FEE\u8BA2\uFF0C\u4EFB\u52A1\u6309\u65B0\u76EE\u6807\u5F00\u59CB\u6267\u884C\u3002",
|
|
239386
239680
|
working: (node2) => `\u6B63\u5728\u5904\u7406\u300A${node2}\u300B\u3002`,
|
|
239387
|
-
reworking: (node2) => `\u6B63\u5728\u6839\u636E\u5BA1\u6838\
|
|
239681
|
+
reworking: (node2) => `\u6B63\u5728\u6839\u636E\u5BA1\u6838\u610F\u89C1\u4FEE\u6539\u300A${node2}\u300B\u3002`,
|
|
239388
239682
|
specChanged: (node2) => `\u6B63\u5728\u6839\u636E\u4EFB\u52A1\u8BF4\u660E\u7684\u66F4\u65B0\u8C03\u6574\u300A${node2}\u300B\u3002`,
|
|
239389
239683
|
issueDriven: (node2) => `\u6B63\u5728\u6839\u636E\u53CD\u9988\u8C03\u6574\u300A${node2}\u300B\u3002`,
|
|
239390
239684
|
/* `gapReworked`(「缺口已解决,{执行人} 带着答复重新开工《X》。」)**2026-09-21 删掉**:
|
|
@@ -239406,7 +239700,7 @@ var init_activity2 = __esm({
|
|
|
239406
239700
|
也是引擎做的(`activate.ts` 的 `tryToRun`)——管理者根本不知道这两件事,此前却写成
|
|
239407
239701
|
「{管理者}已主动介入」「{管理者}正在重试」,把系统干的事指名道姓按到人头上。
|
|
239408
239702
|
「后来谁介入了」由 `plan.node_retry` 那张卡说,那里的主语是**真按下重试的人**,说的是事实。 */
|
|
239409
|
-
timedOut: (executor) => `${executor} \u8FD0\u884C\
|
|
239703
|
+
timedOut: (executor) => `${executor} \u8FD0\u884C\u8D85\u65F6\u3002`,
|
|
239410
239704
|
failed: (executor) => `${executor} \u6267\u884C\u5931\u8D25\u3002`,
|
|
239411
239705
|
/**
|
|
239412
239706
|
* **零产出轮**:会话正常退出,一件东西都没交(引擎判卷不是 success)。与 {@link failed} 分开说——
|
|
@@ -239414,8 +239708,8 @@ var init_activity2 = __esm({
|
|
|
239414
239708
|
*/
|
|
239415
239709
|
endedWithoutOutput: (executor, node2) => `${executor} \u672C\u8F6E\u7ED3\u675F\uFF0C\u6CA1\u6709\u4EA4\u51FA\u300A${node2}\u300B\u7684\u4EFB\u4F55\u6210\u679C\u3002`,
|
|
239416
239710
|
/** 人点了重试——只在 `plan.node_retry` 用,`by` 是真按下重试的那个人。 */
|
|
239417
|
-
retriedAfterTimeout: (executor, by) => `${executor} \u8FD0\u884C\
|
|
239418
|
-
retriedAfterFailure: (executor, by) => `${executor} \u6267\u884C\u5931\u8D25\uFF0C${by}\u5DF2\
|
|
239711
|
+
retriedAfterTimeout: (executor, by) => `${executor} \u8FD0\u884C\u8D85\u65F6\uFF0C${by} \u5DF2\u91CD\u65B0\u8FD0\u884C\u3002`,
|
|
239712
|
+
retriedAfterFailure: (executor, by) => `${executor} \u6267\u884C\u5931\u8D25\uFF0C${by} \u5DF2\u91CD\u65B0\u8FD0\u884C\u3002`,
|
|
239419
239713
|
resumed: (executor, node2) => `${executor} \u5DF2\u6062\u590D\uFF0C\u7EE7\u7EED\u5904\u7406\u300A${node2}\u300B\u3002`,
|
|
239420
239714
|
killed: (node2) => `\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\u5DF2\u7EC8\u6B62\u3002`,
|
|
239421
239715
|
/**
|
|
@@ -239445,7 +239739,7 @@ var init_activity2 = __esm({
|
|
|
239445
239739
|
/* `foldedFailuresRetried`(「{执行人} 连续 N 次没跑成《X》,{谁}已介入重试。」)**2026-09-22 删掉**
|
|
239446
239740
|
(Bug 0209 / 用例 T-117):人介入现在是折叠的**断点**,断点前那张卡就此定稿,不该再被一句
|
|
239447
239741
|
「已介入重试」回填;「又跑了」由断点之后另起的那张卡说,「谁重新运行了这一步」由升级卡说。 */
|
|
239448
|
-
interruptedByIssue: (node2) => `\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\
|
|
239742
|
+
interruptedByIssue: (node2) => `\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\u9047\u5230\u95EE\u9898\uFF0C\u5DF2\u4E2D\u65AD\u3002`,
|
|
239449
239743
|
/**
|
|
239450
239744
|
* 同上,但这一轮是**被自己报的缺口**打断的:把「接下来等谁」并进结局句(F4,缺口卡删掉之后
|
|
239451
239745
|
* 「该找谁」只剩这一个出口)。红卡三问里的「等谁」由这半句回答。
|
|
@@ -239455,7 +239749,7 @@ var init_activity2 = __esm({
|
|
|
239455
239749
|
* 卡上。此前这里写过「已由 {协调者} 补齐缺口」——缺口也可能补不上、最后升级给人,那就是一句
|
|
239456
239750
|
* 卡面兑现不了的断言(同「未经 X 确认」那一族)。
|
|
239457
239751
|
*/
|
|
239458
|
-
interruptedByGap: (node2, helper) => `\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\
|
|
239752
|
+
interruptedByGap: (node2, helper) => `\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\u7F3A\u5C11\u5FC5\u8981\u4FE1\u606F\uFF0C\u5DF2\u53D1\u8D77\u6C42\u52A9\uFF0C\u7B49 ${helper} \u5904\u7406\u3002`,
|
|
239459
239753
|
/* ── 两种系统止损,文案分开写(F6,奕璇 2026-09-21 拍板)──────────────────────────────
|
|
239460
239754
|
改完之后两种止损的**执行者是一样的**(执行卡挂执行人、升级卡挂等处理的那个人),
|
|
239461
239755
|
能不能分辨全落在这几句话上。投影侧怎么判是哪一种见 {@link escalationKindOf}。
|
|
@@ -239464,14 +239758,14 @@ var init_activity2 = __esm({
|
|
|
239464
239758
|
上报正文是唯一事实源(奕璇 2026-09-22 定)。两头的口径都已经是**轮**:引擎那条本来就数
|
|
239465
239759
|
work,保险丝那条 Bug 0211 起把同一轮里的协议续唤 run 折回去再数(老正文不回填,见
|
|
239466
239760
|
{@link parseStopLossFacts})。 */
|
|
239467
|
-
retryExhausted: (executor, node2, n, lastReason) => `${executor} \u8FDE\u7EED ${n} \u6B21\u6CA1\u8DD1\u6210\u300A${node2}\u300B\uFF0C\u91CD\u8BD5\u5DF2\u7528\
|
|
239468
|
-
outputStalled: (executor, node2, n, cost) => `${executor} \u8FDE\u7EED ${n} \u6B21\u6CA1\u4EA4\u51FA\u300A${node2}\u300B\u7684\u4EFB\u4F55\u6210\u679C${cost ? `\uFF08\u7EA6 ${cost}\uFF09` : ""}\uFF0C\u7CFB\u7EDF\u5DF2\
|
|
239761
|
+
retryExhausted: (executor, node2, n, lastReason) => `${executor} \u8FDE\u7EED ${n} \u6B21\u6CA1\u8DD1\u6210\u300A${node2}\u300B\uFF0C\u81EA\u52A8\u91CD\u8BD5\u6B21\u6570\u5DF2\u7528\u5B8C${lastReason ? `\uFF08\u6700\u540E\u4E00\u6B21\u62A5\u9519\uFF1A${lastReason}\uFF09` : ""}\u3002`,
|
|
239762
|
+
outputStalled: (executor, node2, n, cost) => `${executor} \u8FDE\u7EED ${n} \u6B21\u6CA1\u4EA4\u51FA\u300A${node2}\u300B\u7684\u4EFB\u4F55\u6210\u679C${cost ? `\uFF08\u7EA6 ${cost}\uFF09` : ""}\uFF0C\u7CFB\u7EDF\u5DF2\u6682\u505C\u8FD9\u4E00\u6B65\u3002`,
|
|
239469
239763
|
/* ── 升级卡(上报)的整句 ───────────────────────────────────────────────────────────
|
|
239470
239764
|
卡面只有一处小状态,所以「谁卡住了 / 等谁 / 你要做什么」三问连写成一句。
|
|
239471
239765
|
开头那半句(`escalationHead*`)三族各一份,收口时也复用它——同一条上报前后两拍说的是
|
|
239472
239766
|
同一件事,只换后半句(「等 @X 处理」→「X 已处理:…」)。 */
|
|
239473
|
-
escalationHeadRetryExhausted: (node2) => `\u300A${node2}\u300B\u91CD\u8BD5\u5DF2\u7528\
|
|
239474
|
-
escalationHeadOutputStall: (node2) => `\
|
|
239767
|
+
escalationHeadRetryExhausted: (node2) => `\u300A${node2}\u300B\u81EA\u52A8\u91CD\u8BD5\u6B21\u6570\u5DF2\u7528\u5B8C\uFF0C`,
|
|
239768
|
+
escalationHeadOutputStall: (node2) => `\u300A${node2}\u300B\u8FDE\u7EED\u591A\u6B21\u6CA1\u6709\u4EA4\u51FA\u6210\u679C\uFF0C\u7CFB\u7EDF\u5DF2\u6682\u505C\u8FD9\u4E00\u6B65\uFF0C`,
|
|
239475
239769
|
/**
|
|
239476
239770
|
* 评审连败熔断(Bug 0212):卡住的是**这一轮评审**,不是那一版活——话不能写成「执行异常」。
|
|
239477
239771
|
*
|
|
@@ -239481,26 +239775,26 @@ var init_activity2 = __esm({
|
|
|
239481
239775
|
* 这批行根本取不到。硬拼一句取不到值的模板只会永远不出现,不如不写。
|
|
239482
239776
|
* 要补这半句,得先让评审派发把 `work_order_id` / `node_id` 记进 `agent_runs`(另开单)。
|
|
239483
239777
|
*/
|
|
239484
|
-
escalationHeadReviewExhausted: (node2) => `\u300A${node2}\u300B\u7684\
|
|
239778
|
+
escalationHeadReviewExhausted: (node2) => `\u300A${node2}\u300B\u7684\u5BA1\u6838\u8FDE\u7EED\u51E0\u6B21\u6CA1\u8DD1\u6210\uFF0C\u8FD9\u4E00\u8F6E\u5BA1\u6838\u5B8C\u6210\u4E0D\u4E86\uFF0C`,
|
|
239485
239779
|
/** 人工上报里**关联着缺口**的那一档:协调者接了缺口、补不了,于是升级给人(四种停法的第二种)。 */
|
|
239486
|
-
escalationHeadGapEscalated: (coordinator, node2) => `${coordinator} \
|
|
239780
|
+
escalationHeadGapEscalated: (coordinator, node2) => `${coordinator} \u89E3\u51B3\u4E0D\u4E86\u300A${node2}\u300B\u7684\u6C42\u52A9\uFF0C`,
|
|
239487
239781
|
/* ── 系统巡检那几路(Bug 0274):以前全被当成零产出保险丝、套「系统止损…空烧」那两句。
|
|
239488
|
-
|
|
239489
|
-
escalationHeadStall: (node2) => `\
|
|
239782
|
+
巡检卡的标题与处理说明按类型现拼(`stall-copy.ts` 的 `stallCardCopy`),下面这句只在卡不挂节点时兜底。 */
|
|
239783
|
+
escalationHeadStall: (node2) => `\u7CFB\u7EDF\u53D1\u73B0\u300A${node2}\u300B\u505C\u4F4F\u4E86\uFF0C`,
|
|
239490
239784
|
/** SLA 熔断:自动处理(或收尾审核)反复失败,系统已冻住派发(`escalateHold`)。 */
|
|
239491
|
-
escalationHeadSlaBreaker: (node2) => `\u300A${node2}\u300B\
|
|
239785
|
+
escalationHeadSlaBreaker: (node2) => `\u300A${node2}\u300B\u53CD\u590D\u8FD0\u884C\u5931\u8D25\uFF0C\u7CFB\u7EDF\u5DF2\u6682\u505C\u8FD9\u4E00\u6B65\uFF0C`,
|
|
239492
239786
|
/** 配额饥饿:运行时额度长期被限流,系统已冻住派发。 */
|
|
239493
|
-
escalationHeadQuotaStarvation: (node2) => `\u300A${node2}\u300B\u56E0\u4E3A\u989D\u5EA6\u4E0D\u591F\
|
|
239787
|
+
escalationHeadQuotaStarvation: (node2) => `\u300A${node2}\u300B\u56E0\u4E3A\u989D\u5EA6\u4E0D\u591F\u4E00\u76F4\u8DD1\u4E0D\u8D77\u6765\uFF0C\u7CFB\u7EDF\u5DF2\u6682\u505C\u8FD9\u4E00\u6B65\uFF0C`,
|
|
239494
239788
|
/* ── Bug 0275 的三路系统上报。🚨 都**不写「这一步会自动重试」**:关上报只会复活 latest_work 已死的节点
|
|
239495
239789
|
(engine `issue.resolve` → `markNodeForRetry`),这三种停法里活多半没死,那句话兑现不了。 */
|
|
239496
239790
|
/** 锁定审核人不可用(熔断 / 离岗 / 被移出角色):评审派不出去,要人改派。 */
|
|
239497
|
-
escalationHeadReviewerUnavailable: (node2) => `\u300A${node2}\u300B\
|
|
239791
|
+
escalationHeadReviewerUnavailable: (node2) => `\u300A${node2}\u300B\u6307\u5B9A\u7684\u5BA1\u6838\u4EBA\u73B0\u5728\u65E0\u6CD5\u5BA1\u6838\uFF0C`,
|
|
239498
239792
|
/** 协调者对缺口评估到上限仍推进不了(系统兜底)。`n` 取正文里的评估次数,取不到就不说数。 */
|
|
239499
|
-
escalationHeadGapEvalsExhausted: (node2, n) =>
|
|
239793
|
+
escalationHeadGapEvalsExhausted: (node2, n) => n !== void 0 ? `\u7CFB\u7EDF\u5C1D\u8BD5\u4E86 ${n} \u6B21\u4ECD\u89E3\u51B3\u4E0D\u4E86\u300A${node2}\u300B\u7684\u6C42\u52A9\uFF0C` : `\u7CFB\u7EDF\u591A\u6B21\u5C1D\u8BD5\u4ECD\u89E3\u51B3\u4E0D\u4E86\u300A${node2}\u300B\u7684\u6C42\u52A9\uFF0C`,
|
|
239500
239794
|
/** 执行人的运行时绑定指向已删除 / 未注册的节点:这一步根本没开跑。 */
|
|
239501
|
-
escalationHeadDispatchMissingNode: (node2) => `\u300A${node2}\u300B\u8FD8\u6CA1\u6709\
|
|
239795
|
+
escalationHeadDispatchMissingNode: (node2) => `\u300A${node2}\u300B\u8FD8\u6CA1\u6709\u5F00\u59CB\uFF1A\u6267\u884C\u4EBA\u7ED1\u5B9A\u7684\u673A\u5668\u4E0D\u5B58\u5728\uFF0C`,
|
|
239502
239796
|
/** 其余人工上报:主语是卡住的那个执行人(异常是它的,不是上报作者的)。 */
|
|
239503
|
-
escalationHeadManual: (stuckActor) => `${stuckActor} \u7684\
|
|
239797
|
+
escalationHeadManual: (stuckActor) => `${stuckActor} \u9047\u5230\u7684\u95EE\u9898\u4E00\u76F4\u6CA1\u6709\u89E3\u51B3\uFF0C`,
|
|
239504
239798
|
/** 同一节点反复跳闸**并进同一张卡计数**,不每次新开一张(F6)。`n` ≥ 2 才拼这半句。 */
|
|
239505
239799
|
stopLossAgain: (sentence, n) => `${sentence.replace(/。$/, "")}\uFF08\u7B2C ${n} \u6B21\uFF09\u3002`,
|
|
239506
239800
|
/* 升级卡的整句 = 标题行 + 小状态(卡面只有一处小状态可用,两句连写)。
|
|
@@ -239510,15 +239804,15 @@ var init_activity2 = __esm({
|
|
|
239510
239804
|
「已暂停」只有一个来源——整张工单被人点了暂停任务。两种止损都只停掉当前那一轮。 */
|
|
239511
239805
|
escalationPendingWith: (head, target, howTo) => `${head}\u7B49 @${target} \u5904\u7406\u3002${howTo ?? ""}`,
|
|
239512
239806
|
/** 「你要做什么」那半句——两种系统止损各一份(F6 的立论就在这里:执行者一样,只有话不一样)。 */
|
|
239513
|
-
escalationHowToRetryExhausted: "\
|
|
239514
|
-
escalationHowToOutputStall: "\u5904\u7406\
|
|
239807
|
+
escalationHowToRetryExhausted: "\u591A\u534A\u662F\u989D\u5EA6\u4E0D\u591F\u3001\u767B\u5F55\u8FC7\u671F\u8FD9\u7C7B\u73AF\u5883\u95EE\u9898\uFF0C\u5148\u67E5\u770B\u6267\u884C\u8FC7\u7A0B\u786E\u8BA4\u539F\u56E0\u3002\u5904\u7406\u5B8C\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u6B65\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002",
|
|
239808
|
+
escalationHowToOutputStall: "\u5148\u70B9\u300C\u53BB\u5904\u7406\u300D\u67E5\u6E05\u539F\u56E0\uFF0C\u5426\u5219\u91CD\u8BD5\u8FD8\u662F\u4EA4\u4E0D\u51FA\u6210\u679C\u3002\u5904\u7406\u5B8C\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u6B65\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002",
|
|
239515
239809
|
/** 评审熔断那一份:关掉之后重开的是**评审**,不是这一步的活(活已经交了,等的是审)。 */
|
|
239516
|
-
escalationHowToReviewExhausted: "\
|
|
239517
|
-
escalationHowToSlaBreaker: "\
|
|
239518
|
-
escalationHowToQuotaStarvation: "\
|
|
239519
|
-
escalationHowToReviewerUnavailable: "\u9700\u8981\u4F60\u5B9A\
|
|
239520
|
-
escalationHowToGapEvalsExhausted: "\u9700\u8981\u4F60\
|
|
239521
|
-
escalationHowToDispatchMissingNode: "\u6062\u590D\u90A3\u53F0\
|
|
239810
|
+
escalationHowToReviewExhausted: "\u591A\u534A\u662F\u5BA1\u6838\u4EBA\u7684\u8FD0\u884C\u73AF\u5883\u51FA\u4E86\u95EE\u9898\uFF08\u989D\u5EA6\u4E0D\u591F\u3001\u767B\u5F55\u8FC7\u671F\uFF09\uFF0C\u5148\u67E5\u770B\u6267\u884C\u8FC7\u7A0B\u786E\u8BA4\u539F\u56E0\u3002\u5904\u7406\u5B8C\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u8F6E\u5BA1\u6838\u4F1A\u81EA\u52A8\u91CD\u65B0\u5F00\u59CB\u3002",
|
|
239811
|
+
escalationHowToSlaBreaker: "\u591A\u534A\u662F\u6267\u884C\u7684\u673A\u5668\u8FDE\u4E0D\u4E0A\u3001\u5361\u4F4F\u6216\u7F3A\u5C11\u914D\u7F6E\uFF0C\u5148\u70B9\u300C\u53BB\u5904\u7406\u300D\u770B\u6E05\u539F\u56E0\u3002\u5904\u7406\u5B8C\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u6B65\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002",
|
|
239812
|
+
escalationHowToQuotaStarvation: "\u5148\u52A0\u989D\u5EA6\u3001\u6362\u8D26\u53F7\uFF0C\u6216\u51CF\u5C11\u540C\u65F6\u5728\u8DD1\u7684\u4EFB\u52A1\uFF0C\u5426\u5219\u91CD\u8BD5\u8FD8\u662F\u8DD1\u4E0D\u8D77\u6765\u3002\u5904\u7406\u5B8C\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u6B65\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002",
|
|
239813
|
+
escalationHowToReviewerUnavailable: "\u9700\u8981\u4F60\u51B3\u5B9A\uFF1A\u6362\u4E00\u4E2A\u5BA1\u6838\u4EBA\uFF0C\u8FD8\u662F\u7B49\u539F\u5BA1\u6838\u4EBA\u6062\u590D\u3002\u5904\u7406\u5B8C\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u6B65\u624D\u4F1A\u7EE7\u7EED\u3002",
|
|
239814
|
+
escalationHowToGapEvalsExhausted: "\u9700\u8981\u4F60\u51B3\u5B9A\uFF1A\u8865\u4E0A\u7F3A\u5C11\u7684\u4FE1\u606F\uFF0C\u6216\u4FEE\u6539\u8FD9\u4E00\u6B65\u7684\u8BF4\u660E\u3002\u6C42\u52A9\u89E3\u51B3\u540E\u8FD9\u6761\u5F85\u529E\u4F1A\u81EA\u52A8\u5173\u95ED\uFF0C\u8FD9\u4E00\u6B65\u63A5\u7740\u505A\u3002",
|
|
239815
|
+
escalationHowToDispatchMissingNode: "\u6062\u590D\u90A3\u53F0\u673A\u5668\uFF0C\u6216\u7ED9\u6267\u884C\u4EBA\u6362\u4E00\u53F0\u5728\u7EBF\u7684\u673A\u5668\u3002\u4FEE\u597D\u540E\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF0C\u8FD9\u4E00\u6B65\u624D\u4F1A\u5F00\u59CB\u3002",
|
|
239522
239816
|
/** 关掉了:接着开头那半句说「谁处理的、怎么处理的」。没写处置说明就只说「已处理」。
|
|
239523
239817
|
* 处置说明常常是人自己写的一整段、末尾自带句号——**别再补一个**,否则卡面收在「。。」上。 */
|
|
239524
239818
|
escalationHandled: (head, by, note) => `${head}${by} \u5DF2\u5904\u7406${note ? `\uFF1A${note}` : ""}${note && /[。!?.!?]$/.test(note) ? "" : "\u3002"}`,
|
|
@@ -239526,14 +239820,14 @@ var init_activity2 = __esm({
|
|
|
239526
239820
|
* 从升级卡上点「重新运行」关掉的那一档(F7):这一步当场重开,所以不说「已处理:{说明}」
|
|
239527
239821
|
* ——人并没有写说明,说明是这颗按钮替他写的。次数是**这个节点上第几次这么重试**。
|
|
239528
239822
|
*/
|
|
239529
|
-
escalationRerun: (by, n) => `${by} \u91CD\u65B0\u8FD0\u884C\u4E86\u8FD9\u4E00\u6B65\uFF08\u7B2C ${n} \u6B21\
|
|
239823
|
+
escalationRerun: (by, n) => `${by} \u91CD\u65B0\u8FD0\u884C\u4E86\u8FD9\u4E00\u6B65\uFF08\u7B2C ${n} \u6B21\uFF09\u3002`,
|
|
239530
239824
|
/* ── 协调者卡(F2)──────────────────────────────────────────────────────────────────
|
|
239531
239825
|
「协调者处理**某条缺口**的那一段」。三句话对应缺口的三种去向(已补齐 / 补不了升级给人 /
|
|
239532
239826
|
还开着),判据全在缺口这条 issue 上,不看旁账那条 `coordinate:` 运行有没有留下结论
|
|
239533
239827
|
(Bug 0213;前两句 T-104 / T-113 已验收,逐字不动)。 */
|
|
239534
|
-
coordinatingGap: (coordinator, node2) => `${coordinator} \u6B63\u5728\u5904\u7406\u300A${node2}\u300B\u7684\
|
|
239535
|
-
coordinatorFixedGap: (coordinator, executor) => `${coordinator} \u5DF2\
|
|
239536
|
-
coordinatorEscalated: (coordinator, node2, target) => `${coordinator} \
|
|
239828
|
+
coordinatingGap: (coordinator, node2) => `${coordinator} \u6B63\u5728\u5904\u7406\u300A${node2}\u300B\u7684\u6C42\u52A9\u3002`,
|
|
239829
|
+
coordinatorFixedGap: (coordinator, executor) => `${coordinator} \u5DF2\u89E3\u51B3\u6C42\u52A9\uFF0C${executor} \u7EE7\u7EED\u6267\u884C\u3002`,
|
|
239830
|
+
coordinatorEscalated: (coordinator, node2, target) => `${coordinator} \u89E3\u51B3\u4E0D\u4E86\u300A${node2}\u300B\u7684\u6C42\u52A9\uFF0C\u5DF2\u8F6C\u7ED9 @${target} \u5904\u7406\u3002`,
|
|
239537
239831
|
/**
|
|
239538
239832
|
* 缺口还开着、也没升级给人,而这一段协调运行已经结束且没跑成(failed / orphaned / timeout)——
|
|
239539
239833
|
* 如实说这一轮没跑成,别说「正在处理」(没人在处理),也别替它宣布一个没发生的结局。
|
|
@@ -239541,7 +239835,7 @@ var init_activity2 = __esm({
|
|
|
239541
239835
|
* 🚨 兜底句「{协调者} 处理《X》的缺口,这一段没有结论」**已删**(Bug 0213):那句是拿 run 的结论
|
|
239542
239836
|
* 拼卡时的产物——取不到结论就替这一段下一个空结论。缺口自己的状态永远答得出「补上了没有」。
|
|
239543
239837
|
*/
|
|
239544
|
-
coordinatorFailed: (node2) => `\u5904\u7406\u300A${node2}\u300B\u7684\
|
|
239838
|
+
coordinatorFailed: (node2) => `\u5904\u7406\u300A${node2}\u300B\u7684\u6C42\u52A9\u65F6\u8FD9\u4E00\u8F6E\u6CA1\u8DD1\u6210\u3002`,
|
|
239545
239839
|
/**
|
|
239546
239840
|
* 这一轮**被计划变更打断**(P15)。与卡点中断同级:计划一动,这一轮就不再是「还在跑」,
|
|
239547
239841
|
* 而是被引擎当场顶掉了——`plan.delete_node` 直接 `killLatestWork`;`plan.update_spec`(spec 真变)
|
|
@@ -239566,7 +239860,7 @@ var init_activity2 = __esm({
|
|
|
239566
239860
|
* **上游出了新版本**,在跑的这一轮因此被引擎顶掉(Bug 0068)。上游是根节点任务说明、而且能认出是谁改的,
|
|
239567
239861
|
* 走 {@link interruptedBySpecChange}(控制台「编辑任务说明」就是这条路径);其余上游换版走这一句。
|
|
239568
239862
|
*/
|
|
239569
|
-
interruptedByUpstreamVersion: (upstream, node2) => `\u300A${upstream}\u300B
|
|
239863
|
+
interruptedByUpstreamVersion: (upstream, node2, m2) => `\u300A${upstream}\u300B${m2 !== void 0 ? `\u51FA\u4E86\u7B2C ${m2} \u7248` : "\u6709\u65B0\u7248"}\uFF0C\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\u5230\u6B64\u4E2D\u65AD\u3002`,
|
|
239570
239864
|
/** 换人那一档点破接手的人——卡到此为止,下一轮是新执行人的新卡。 */
|
|
239571
239865
|
interruptedByReassign: (node2, next) => `\u300A${node2}\u300B\u672C\u8F6E\u6267\u884C\u56E0\u8BA1\u5212\u8C03\u6574\u4E2D\u65AD\uFF0C\u5DF2\u6539\u7531 ${next} \u63A5\u624B\u3002`,
|
|
239572
239866
|
/** 节点被移出计划:这一轮再没有下文,也不会有新卡。 */
|
|
@@ -239577,7 +239871,7 @@ var init_activity2 = __esm({
|
|
|
239577
239871
|
* 只剩**节点最新一轮、且查不到卡在哪**会落到这里(多半是引擎马上要续派 / 收口的那几秒);同节点已有
|
|
239578
239872
|
* 下一轮接手的见 {@link stageHandedOver},交稿后卡在续跑审批 / 暂停 / 回压上的见 `heldBy*`。
|
|
239579
239873
|
*/
|
|
239580
|
-
awaitingConclude: (node2) => `\u300A${node2}\u300B\u5DF2\
|
|
239874
|
+
awaitingConclude: (node2) => `\u300A${node2}\u300B\u5DF2\u505A\u5B8C\uFF0C\u7CFB\u7EDF\u6B63\u5728\u786E\u8BA4\u3002`,
|
|
239581
239875
|
/**
|
|
239582
239876
|
* **阶段交付已被接手**:这一轮交了稿、没收口,同节点已经派出下一轮接着做(分批 `propose --checkpoint
|
|
239583
239877
|
* --continue`,或派活说明要求先别收口)。这一段到此已经交付——等收口的是接手的那一轮,不是它。
|
|
@@ -239586,14 +239880,14 @@ var init_activity2 = __esm({
|
|
|
239586
239880
|
*
|
|
239587
239881
|
* 不说「已完成」:节点并没有完成,说了会让人以为这一步做完、在等审核。
|
|
239588
239882
|
*/
|
|
239589
|
-
stageHandedOver: (node2) => `\u300A${node2}\u300B\u5DF2\u63D0\u4EA4\u9636\u6BB5\u6210\u679C\uFF0C\
|
|
239883
|
+
stageHandedOver: (node2) => `\u300A${node2}\u300B\u5DF2\u63D0\u4EA4\u9636\u6BB5\u6210\u679C\uFF0C\u4E0B\u4E00\u8F6E\u63A5\u7740\u505A\u3002`,
|
|
239590
239884
|
/** 同一节点上紧挨着的阶段交付轮折成一张(与连败折叠同一套机制),批数写进句子。 */
|
|
239591
|
-
foldedStageHandedOver: (node2, n) => `\u300A${node2}\u300B\u5DF2\u5206 ${n} \
|
|
239885
|
+
foldedStageHandedOver: (node2, n) => `\u300A${node2}\u300B\u5DF2\u5206 ${n} \u6B21\u63D0\u4EA4\u9636\u6BB5\u6210\u679C\uFF0C\u4E0B\u4E00\u8F6E\u63A5\u7740\u505A\u3002`,
|
|
239592
239886
|
/**
|
|
239593
239887
|
* 这一批的续跑额度用完、引擎落了续跑申请(ADR 0549):执行卡这一段到此结束(灰、无按钮)。
|
|
239594
239888
|
* 同一批里紧挨着的阶段交付轮照旧折进来,句子只说到这一批为止;下一批是新卡,排在续跑申请卡后面。
|
|
239595
239889
|
*/
|
|
239596
|
-
stageBatchExhausted: (node2, batch, rounds) => `\u300A${node2}\u300B\u5DF2\u4EA4\
|
|
239890
|
+
stageBatchExhausted: (node2, batch, rounds) => `\u300A${node2}\u300B\u5DF2\u63D0\u4EA4\u7B2C ${batch} \u6279\u9636\u6BB5\u6210\u679C\uFF08\u672C\u6279 ${rounds} \u8F6E\u5DF2\u7528\u5B8C\uFF09\u3002`,
|
|
239597
239891
|
/* ── 续跑申请卡(奕璇 2026-09-28 定稿,附件《续跑申请卡方案》)────────────────────────────────────
|
|
239598
239892
|
署名工单真人负责人;等决定 / 暂停中砖红,决定按钮直接在卡上;同意 / 恢复 / 接受 / 取消之后灰、无按钮。 */
|
|
239599
239893
|
continuationPending: (node2, rounds, owner) => `\u300A${node2}\u300B\u672C\u6279 ${rounds} \u8F6E\u5DF2\u7528\u5B8C\uFF0C\u9700\u8981 @${owner} \u51B3\u5B9A\uFF1A\u518D\u8DD1\u4E00\u6279\uFF0C\u6216\u63A5\u53D7\u5F53\u524D\u6210\u679C\u3002`,
|
|
@@ -239602,14 +239896,14 @@ var init_activity2 = __esm({
|
|
|
239602
239896
|
* 暂停中(仍砖红,按钮是「恢复续跑 / 接受当前成果」)。理由是负责人自己写的,照铺(与 Bug 0236 的判据一致:
|
|
239603
239897
|
* 人写的照铺、agent 写的不上卡);没填就去掉冒号那半句。
|
|
239604
239898
|
*/
|
|
239605
|
-
continuationDenied: (owner, reason) => `@${owner} \
|
|
239606
|
-
continuationResumed: (owner, rounds) => `@${owner} \
|
|
239607
|
-
continuationOutputAccepted: (owner, node2) => `@${owner} \u63A5\u53D7\u4E86\u5F53\u524D\u6210\u679C\uFF0C\u300A${node2}\u300B\u5DF2\u5B8C\u6210\u3002`,
|
|
239899
|
+
continuationDenied: (owner, reason) => `@${owner} \u9009\u62E9\u5148\u4E0D\u7EE7\u7EED${reason ? `\uFF1A${reason.replace(/[。..]+$/, "")}` : ""}\u3002\u4E4B\u540E\u53EF\u4EE5\u5728\u8FD9\u91CC\u7EE7\u7EED\u6267\u884C\uFF0C\u6216\u63A5\u53D7\u5F53\u524D\u6210\u679C\u3002`,
|
|
239900
|
+
continuationResumed: (owner, rounds) => `@${owner} \u51B3\u5B9A\u7EE7\u7EED\u6267\u884C\uFF0C\u8FFD\u52A0 ${rounds} \u8F6E\u3002`,
|
|
239901
|
+
continuationOutputAccepted: (owner, node2, v2) => `@${owner} \u63A5\u53D7\u4E86\u5F53\u524D\u6210\u679C\uFF0C\u300A${node2}\u300B${versionPhrase(v2)}\u5DF2\u5B8C\u6210\u3002`,
|
|
239608
239902
|
/** 还没决定,节点的真实交付就被验收了(ADR 0549 D4 关闭遗留额度卡):这次申请不用再决定。 */
|
|
239609
|
-
continuationSettled: (node2) => `\u300A${node2}\u300B\u5DF2\
|
|
239610
|
-
continuationNodeRemoved:
|
|
239903
|
+
continuationSettled: (node2) => `\u300A${node2}\u300B\u5DF2\u5B8C\u6210\uFF0C\u8FD9\u6B21\u7533\u8BF7\u4E0D\u7528\u518D\u5904\u7406\u3002`,
|
|
239904
|
+
continuationNodeRemoved: (node2) => `\u300A${node2}\u300B\u5DF2\u53D6\u6D88\uFF0C\u8FD9\u6B21\u7533\u8BF7\u4E0D\u7528\u518D\u5904\u7406\u3002`,
|
|
239611
239905
|
/** 续跑申请卡正文(展开区):申请那一刻的轮数账。执行人的进展说明不上卡。 */
|
|
239612
|
-
continuationRounds: (used, authorized, next) => `\u5DF2\
|
|
239906
|
+
continuationRounds: (used, authorized, next) => `\u5DF2\u8DD1 ${used} \u8F6E / \u5DF2\u6279\u51C6 ${authorized} \u8F6E \xB7 \u4E0B\u4E00\u6279 ${next} \u8F6E`,
|
|
239613
239907
|
/* ── 交了稿没收口、**卡在别处**(Bug 0053 D2,ADR 0588)────────────────────────────
|
|
239614
239908
|
这一轮结束到下一轮开工之间(没有下一轮就是「到现在」)查得到明确原因 ⇒ 执行中断,小状态说清卡在哪、
|
|
239615
239909
|
等谁。此前一律「已交付,等待收口」+ 进行中:生产 9/17 最后两张进行中卡就是这一档,一张续跑被拒、
|
|
@@ -239617,14 +239911,14 @@ var init_activity2 = __esm({
|
|
|
239617
239911
|
/* 续跑额度那两句(「等待批准继续」「节点已暂停,等待放行」)**2026-09-28 删掉**(奕璇拍板续跑申请纳入卡片规范):
|
|
239618
239912
|
等人决定这件事由负责人那张续跑申请卡说(砖红 + 「去处理」),执行卡只说自己这一段交了什么——
|
|
239619
239913
|
「等待放行」还让人一直等一个并不存在的按钮。执行卡这一档见 {@link ACTIVITY_COPY.stageBatchExhausted}。 */
|
|
239620
|
-
heldByWorkorderPause: (node2) => `\u300A${node2}\u300B\u5DF2\u4EA4\
|
|
239914
|
+
heldByWorkorderPause: (node2) => `\u300A${node2}\u300B\u5DF2\u63D0\u4EA4\u9636\u6BB5\u6210\u679C\uFF0C\u4EFB\u52A1\u5DF2\u6682\u505C\uFF0C\u7B49\u5F85\u6062\u590D\u3002`,
|
|
239621
239915
|
/** 只剩「交完稿、这一轮结束之后才补提」的那一档;同一轮里提的见 {@link ACTIVITY_COPY.backpressureAfterStage}(ADR 0623 补章)。 */
|
|
239622
|
-
heldByBackpressure: (node2, upstreams) => `\u300A${node2}\u300B\u5DF2\
|
|
239916
|
+
heldByBackpressure: (node2, upstreams) => `\u300A${node2}\u300B\u5DF2\u505A\u5B8C\uFF0C\u7B49${upstreams.map((u) => `\u300A${u}\u300B`).join("\u3001")}\u6309\u4FEE\u6539\u8981\u6C42\u6539\u597D\u540E\u624D\u7B97\u5B8C\u6210\u3002`,
|
|
239623
239917
|
/** `works.status=retry`:这一轮没跑成,等引擎重派。谁按的重试由 `plan.node_retry` 补进这句。 */
|
|
239624
|
-
awaitingRedispatch: (executor, node2) => `${executor} \u8FD9\u4E00\u8F6E\u6CA1\u8DD1\u6210\u300A${node2}\u300B\uFF0C\
|
|
239625
|
-
doneAwaitingReview: (name) => `\u300A${name}\u300B\u5DF2\u5B8C\
|
|
239626
|
-
done: (name) => `\u300A${name}\u300B\u5DF2\u5B8C\u6210\u3002`,
|
|
239627
|
-
finalDelivered: (acceptor) => `\u6700\u7EC8\u4EA4\u4ED8\u5DF2\u4E0A\u4F20\uFF0C\u7B49\u5F85 ${acceptor} \u9A8C\u6536\u3002`,
|
|
239918
|
+
awaitingRedispatch: (executor, node2) => `${executor} \u8FD9\u4E00\u8F6E\u6CA1\u8DD1\u6210\u300A${node2}\u300B\uFF0C\u7CFB\u7EDF\u7A0D\u540E\u81EA\u52A8\u91CD\u8BD5\u3002`,
|
|
239919
|
+
doneAwaitingReview: (name, v2) => `\u300A${name}\u300B${versionPhrase(v2)}\u5DF2\u505A\u5B8C\uFF0C\u7B49\u5F85\u5BA1\u6838\u3002`,
|
|
239920
|
+
done: (name, v2) => `\u300A${name}\u300B${versionPhrase(v2)}\u5DF2\u5B8C\u6210\u3002`,
|
|
239921
|
+
finalDelivered: (acceptor, v2) => `\u6700\u7EC8\u4EA4\u4ED8${versionPhrase(v2)}\u5DF2\u4E0A\u4F20\uFF0C\u7B49\u5F85 ${acceptor} \u9A8C\u6536\u3002`,
|
|
239628
239922
|
/* 🚨 审核卡那一族文案(待审 / 正在审 / 通过 / 不通过 / 超时 / 熔断)**不在这里**:
|
|
239629
239923
|
审核卡改成按「被审交付 × 评审人」合卡之后,它的小状态由 `review-activity.ts` 的
|
|
239630
239924
|
`reviewSummary()` 按该评审人的**有效判定**整句给出,不是逐事件套模板。这里此前留着一份
|
|
@@ -239632,9 +239926,9 @@ var init_activity2 = __esm({
|
|
|
239632
239926
|
死副本上,页面纹丝不动。删掉,别再留第二个事实源。
|
|
239633
239927
|
留在这里的只有下面这一句——它不是小状态,是**审核意见条**上那个判定词,由本文件拼卡时用。 */
|
|
239634
239928
|
reviewNoteLabel: (rejected) => rejected ? "\u5BA1\u6838\u4E0D\u901A\u8FC7" : "\u5BA1\u6838\u610F\u89C1",
|
|
239635
|
-
acceptPending: "\u8BF7\u9A8C\u6536\u6700\u7EC8\u4EA4\u4ED8\u3002",
|
|
239636
|
-
accepted:
|
|
239637
|
-
acceptedNode: (name) => `\u300A${name}\u300B\u5DF2\u9A8C\u6536\u3002`,
|
|
239929
|
+
acceptPending: (v2) => v2 !== void 0 ? `\u8BF7\u9A8C\u6536\u6700\u7EC8\u4EA4\u4ED8\uFF08\u7B2C ${v2} \u7248\uFF09\u3002` : "\u8BF7\u9A8C\u6536\u6700\u7EC8\u4EA4\u4ED8\u3002",
|
|
239930
|
+
accepted: (v2) => `\u6700\u7EC8\u4EA4\u4ED8${versionPhrase(v2)}\u5DF2\u9A8C\u6536\u3002`,
|
|
239931
|
+
acceptedNode: (name, v2) => `\u300A${name}\u300B${versionPhrase(v2)}\u5DF2\u9A8C\u6536\u3002`,
|
|
239638
239932
|
/**
|
|
239639
239933
|
* **有评审人、却没经过他** —— 引擎跳过评审自己盖了章。
|
|
239640
239934
|
*
|
|
@@ -239646,8 +239940,8 @@ var init_activity2 = __esm({
|
|
|
239646
239940
|
* 此前动态把这一拍渲染成「验收最终交付已完成验收。」、执行者是翻不出名字的「—」——
|
|
239647
239941
|
* **看起来就像她批过了**。这两句的存在就是为了不让那件事再被盖住:谁该点头、事实上没点。
|
|
239648
239942
|
*/
|
|
239649
|
-
autoAccepted: (reviewer) =>
|
|
239650
|
-
autoAcceptedNode: (name, reviewer) => `\u300A${name}\u300B\
|
|
239943
|
+
autoAccepted: (reviewer) => `${reviewer} \u6CA1\u6709\u5728\u65F6\u9650\u5185\u786E\u8BA4\uFF0C\u7CFB\u7EDF\u5DF2\u81EA\u52A8\u9A8C\u6536\u3002`,
|
|
239944
|
+
autoAcceptedNode: (name, reviewer) => `\u300A${name}\u300B\uFF1A${reviewer} \u6CA1\u6709\u5728\u65F6\u9650\u5185\u786E\u8BA4\uFF0C\u7CFB\u7EDF\u5DF2\u81EA\u52A8\u9A8C\u6536\u3002`,
|
|
239651
239945
|
paused: (actor) => `${actor}\u5DF2\u6682\u505C\u4EFB\u52A1\u3002`,
|
|
239652
239946
|
resumedWorkorder: (actor) => `${actor}\u5DF2\u6062\u590D\u4EFB\u52A1\u3002`,
|
|
239653
239947
|
goalChanged: (actor, manager) => `${actor}\u4FEE\u6539\u4E86\u4EFB\u52A1\u76EE\u6807\uFF0C\u9700\u8981 ${manager}\u91CD\u65B0\u8BC4\u4F30\u3002`,
|
|
@@ -239691,7 +239985,7 @@ var init_activity2 = __esm({
|
|
|
239691
239985
|
* 被要求方按修改要求交出了新一版(agent / 真人同一句)。取代「《X》已完成」「已修订目标」——
|
|
239692
239986
|
* 此前同一件事还另有一张回压卡收口成「{X} 已基于 {Z} 的留言更新了一版」,一件事三张卡。
|
|
239693
239987
|
*/
|
|
239694
|
-
backpressureAddressed: (raisers, node2) => `\u5DF2\u6309 ${raisers} \u7684\u4FEE\u6539\u8981\u6C42\u66F4\u65B0\u300A${node2}\u300B\u3002`,
|
|
239988
|
+
backpressureAddressed: (raisers, node2, v2) => v2 !== void 0 ? `\u5DF2\u6309 ${raisers} \u7684\u4FEE\u6539\u8981\u6C42\u628A\u300A${node2}\u300B\u66F4\u65B0\u5230\u7B2C ${v2} \u7248\u3002` : `\u5DF2\u6309 ${raisers} \u7684\u4FEE\u6539\u8981\u6C42\u66F4\u65B0\u300A${node2}\u300B\u3002`,
|
|
239695
239989
|
/**
|
|
239696
239990
|
* 被回压节点的负责人是**真人**时,系统为他开的那一轮(奕璇 2026-09-22 定):这一轮不会自己跑,
|
|
239697
239991
|
* 是在等他动手——不能再说「正在根据反馈调整」(`issueDriven`),那句会让一张没人在动的卡挂成「进行中」。
|
|
@@ -239709,11 +240003,11 @@ var init_activity2 = __esm({
|
|
|
239709
240003
|
卡左边是执行者(被留言节点的负责人),这几句**不再重复执行者的名字**;留言人只出现在句子里。
|
|
239710
240004
|
上面 `commentRaised` / `commentHandling` 与下面 `commentResolved` 那套旧句子只剩缺口唤醒信的
|
|
239711
240005
|
第二种来源(`ann:recovery:`,D8 未定)在用;`commentAddressed` / `commentResolved` 另给修改要求卡收口用。 */
|
|
239712
|
-
commentWaiting: (author, node2, n) => n > 1 ? `${author} \u5728\u300A${node2}\u300B\u7559\u4E86 ${n} \u6761\u8A00\uFF0C\u7B49\u5F85\u67E5\u770B\u3002` : `${author} \u5728\u300A${node2}\u300B\u7559\u8A00\uFF0C\u7B49\u5F85\u67E5\u770B\u3002`,
|
|
240006
|
+
commentWaiting: (author, node2, n) => n > 1 ? `${author} \u5728\u300A${node2}\u300B\u7559\u4E86 ${n} \u6761\u7559\u8A00\uFF0C\u7B49\u5F85\u67E5\u770B\u3002` : `${author} \u5728\u300A${node2}\u300B\u7559\u8A00\uFF0C\u7B49\u5F85\u67E5\u770B\u3002`,
|
|
239713
240007
|
commentInProgress: (author) => `\u6B63\u5728\u5904\u7406 ${author} \u7684\u7559\u8A00\u3002`,
|
|
239714
|
-
commentUpdated: (author, node2) => `\u5DF2\u6309 ${author} \u7684\u7559\u8A00\u66F4\u65B0\
|
|
240008
|
+
commentUpdated: (author, node2, v2) => v2 !== void 0 ? `\u5DF2\u6309 ${author} \u7684\u7559\u8A00\u628A\u300A${node2}\u300B\u66F4\u65B0\u5230\u7B2C ${v2} \u7248\u3002` : `\u5DF2\u6309 ${author} \u7684\u7559\u8A00\u66F4\u65B0\u4E86\u300A${node2}\u300B\u3002`,
|
|
239715
240009
|
commentReplied: (author) => `\u5DF2\u56DE\u590D ${author} \u7684\u7559\u8A00\uFF0C\u672C\u6B21\u4E0D\u6539\u3002`,
|
|
239716
|
-
commentViewed: (author) => `\u770B
|
|
240010
|
+
commentViewed: (author) => `\u5DF2\u67E5\u770B ${author} \u7684\u7559\u8A00\uFF0C\u65E0\u9700\u4FEE\u6539\u3002`,
|
|
239717
240011
|
/**
|
|
239718
240012
|
* 确认沿用(ADR 0607):上游换版,执行人确认不影响已接受的交付。
|
|
239719
240013
|
*
|
|
@@ -239721,7 +240015,7 @@ var init_activity2 = __esm({
|
|
|
239721
240015
|
* 自由写的,除了长度截断没有任何语域约束,产品负责人 2026-09-23 在真页面上看到的是
|
|
239722
240016
|
* 「任务1:…沿用 `wk:artifact:qa:…:1`,不产新版。」这种任务书编号腔 + 裸 work id。
|
|
239723
240017
|
*/
|
|
239724
|
-
upstreamAcked: (node2) => `\u4E0A\u6E38\u6709\u65B0\u7248\uFF0C\u786E\u8BA4\u4E0D\u5F71\u54CD\u300A${node2}\u300B\uFF0C\
|
|
240018
|
+
upstreamAcked: (node2, v2) => `\u4E0A\u6E38\u6709\u65B0\u7248\uFF0C\u786E\u8BA4\u4E0D\u5F71\u54CD\u300A${node2}\u300B\uFF0C${v2 !== void 0 ? `\u7EE7\u7EED\u7528\u7B2C ${v2} \u7248\u6210\u679C` : "\u7EE7\u7EED\u7528\u539F\u6765\u7684\u6210\u679C"}\u3002`,
|
|
239725
240019
|
commentWithdrawn: (author) => `${author} \u64A4\u56DE\u4E86\u7559\u8A00\uFF0C\u65E0\u9700\u5904\u7406\u3002`,
|
|
239726
240020
|
/** 节点被移出计划(任务还没到头):引擎把挂在上面的留言一并按「不改」关掉(`plan.delete_node`)。 */
|
|
239727
240021
|
commentNodeRemoved: (node2) => `\u300A${node2}\u300B\u5DF2\u4ECE\u8BA1\u5212\u4E2D\u79FB\u9664\uFF0C\u7559\u8A00\u968F\u4E4B\u5173\u95ED\u3002`,
|
|
@@ -239731,13 +240025,13 @@ var init_activity2 = __esm({
|
|
|
239731
240025
|
* 全库实测 `ws:wo-56bba3c1` 那条收口后小状态仍是 **8096 字**。全文去留言线看。
|
|
239732
240026
|
*/
|
|
239733
240027
|
/** 有人接手这条留言、开工了——由 `work.create` 的 `reasons` 引用该 issueId 判定。 */
|
|
239734
|
-
commentHandling: (executor, author) => `${executor} \u6B63\u5728\u5904\u7406
|
|
240028
|
+
commentHandling: (executor, author) => `${executor} \u6B63\u5728\u5904\u7406 ${author} \u7684\u7559\u8A00\u3002`,
|
|
239735
240029
|
/**
|
|
239736
240030
|
* 处理完**并且真出了新一版**。
|
|
239737
240031
|
* ⚠ 只在那一轮真有 conclusion 时才说「更新了一版」——resolve 也可能是「看了但不改」,
|
|
239738
240032
|
* 那种情况说出了新版就是一句卡面兑现不了的断言(同「未经 X 确认」那一族)。
|
|
239739
240033
|
*/
|
|
239740
|
-
commentAddressed: (executor, author, node2) => `${executor} \u5DF2\
|
|
240034
|
+
commentAddressed: (executor, author, node2, v2) => v2 !== void 0 ? `${executor} \u5DF2\u6309 ${author} \u7684\u7559\u8A00\u628A\u300A${node2}\u300B\u66F4\u65B0\u5230\u7B2C ${v2} \u7248\u3002` : `${executor} \u5DF2\u6309 ${author} \u7684\u7559\u8A00\u66F4\u65B0\u4E86\u300A${node2}\u300B\u3002`,
|
|
239741
240035
|
commentResolved: (by, node2) => `${by} \u5DF2\u5904\u7406\u300A${node2}\u300B\u7684\u7559\u8A00\u3002`,
|
|
239742
240036
|
issueResolved: (note) => note
|
|
239743
240037
|
};
|
|
@@ -239813,7 +240107,7 @@ function buildWorkorderActivityTrace(input) {
|
|
|
239813
240107
|
const gap2 = snap.issues.find((i) => i.id === coordinatorGapId && i.kind === "gap");
|
|
239814
240108
|
const gapNodeId = gap2 ? gap2.aboutNodeId ?? gap2.raisedByNodeId : null;
|
|
239815
240109
|
const run = gap2 && gapNodeId ? coordinatorRunOfGap(gap2, (input.coordinatorRuns ?? []).filter((r) => r.nodeId === gapNodeId)) : void 0;
|
|
239816
|
-
if (!run) return { ...empty2, notice: "\u534F\u8C03\u8005\u5904\u7406\u8FD9\u6761\
|
|
240110
|
+
if (!run) return { ...empty2, notice: "\u534F\u8C03\u8005\u5904\u7406\u8FD9\u6761\u6C42\u52A9\u65F6\u6CA1\u6709\u7559\u4E0B\u8FD0\u884C\u8BB0\u5F55\uFF0C\u6682\u65F6\u770B\u4E0D\u5230\u6267\u884C\u8FC7\u7A0B\u3002" };
|
|
239817
240111
|
const node2 = snap.nodes.find((n) => n.id === run.nodeId);
|
|
239818
240112
|
const spec = node2?.spec?.trim();
|
|
239819
240113
|
return {
|
|
@@ -239838,7 +240132,7 @@ function buildWorkorderActivityTrace(input) {
|
|
|
239838
240132
|
if (gap && !card2?.traceWorkIds?.length) return {
|
|
239839
240133
|
...empty2,
|
|
239840
240134
|
works: [],
|
|
239841
|
-
notice: "\
|
|
240135
|
+
notice: "\u8FD9\u6761\u6C42\u52A9\u6CA1\u6709\u5BF9\u5E94\u5230\u5177\u4F53\u54EA\u4E00\u6B21\u6267\u884C\uFF0C\u6682\u65F6\u770B\u4E0D\u5230\u6267\u884C\u8FC7\u7A0B\u3002"
|
|
239842
240136
|
};
|
|
239843
240137
|
const workIds = card2?.traceWorkIds ?? (cardId.startsWith("work:") ? [cardId.slice(5)] : []);
|
|
239844
240138
|
if (workIds.length > 0) {
|
|
@@ -239891,7 +240185,7 @@ function buildWorkorderActivityTrace(input) {
|
|
|
239891
240185
|
cardId,
|
|
239892
240186
|
briefing: firstBriefing,
|
|
239893
240187
|
works,
|
|
239894
|
-
...gap && !gap.aboutWorkId ? { notice: "\
|
|
240188
|
+
...gap && !gap.aboutWorkId ? { notice: "\u6309\u6C42\u52A9\u63D0\u51FA\u65F6\u7684\u8BB0\u5F55\uFF0C\u5BF9\u5E94\u5230\u8FD9\u4E00\u6B65\u5F53\u65F6\u552F\u4E00\u7684\u4E00\u6B21\u6267\u884C\u3002" } : {},
|
|
239895
240189
|
attempts: works.flatMap((w2) => w2.attempts).sort((a, b2) => a.at.localeCompare(b2.at) || a.runId.localeCompare(b2.runId))
|
|
239896
240190
|
};
|
|
239897
240191
|
}
|
|
@@ -240043,13 +240337,13 @@ function buildReviewHistory(input, targetWorkId, reviewerActorId, allReviews) {
|
|
|
240043
240337
|
let detail;
|
|
240044
240338
|
switch (e.kind) {
|
|
240045
240339
|
case "review.create":
|
|
240046
|
-
label2 = "\
|
|
240340
|
+
label2 = "\u53D1\u8D77\u5BA1\u6838";
|
|
240047
240341
|
break;
|
|
240048
240342
|
case "review.started":
|
|
240049
240343
|
label2 = "\u5F00\u59CB\u5BA1\u6838";
|
|
240050
240344
|
break;
|
|
240051
240345
|
case "review.timeout":
|
|
240052
|
-
label2 = "\u5BA1\u6838\
|
|
240346
|
+
label2 = "\u5BA1\u6838\u8D85\u65F6 / \u5931\u8D25";
|
|
240053
240347
|
break;
|
|
240054
240348
|
case "review.kill":
|
|
240055
240349
|
label2 = "\u5BA1\u6838\u5DF2\u505C\u6B62";
|
|
@@ -240060,7 +240354,7 @@ function buildReviewHistory(input, targetWorkId, reviewerActorId, allReviews) {
|
|
|
240060
240354
|
detail = e.note ?? void 0;
|
|
240061
240355
|
break;
|
|
240062
240356
|
case "plan.node_retry":
|
|
240063
|
-
label2 = "\
|
|
240357
|
+
label2 = "\u91CD\u65B0\u8FD0\u884C";
|
|
240064
240358
|
break;
|
|
240065
240359
|
default:
|
|
240066
240360
|
continue;
|
|
@@ -240098,6 +240392,8 @@ function buildReviewHistory(input, targetWorkId, reviewerActorId, allReviews) {
|
|
|
240098
240392
|
targetWorkId,
|
|
240099
240393
|
nodeTitle: snap.nodes.find((n) => n.id === nodeId)?.title ?? nodeId,
|
|
240100
240394
|
...work?.outputVersionNo != null ? { outputVersionNo: work.outputVersionNo } : {},
|
|
240395
|
+
/* 侧栏上给人看的「第 {N} 版」:与卡片同一张表(activity-version.ts),不是引擎那个只在验收时发号的 outputVersionNo。 */
|
|
240396
|
+
.../* @__PURE__ */ ((v2) => v2 !== void 0 ? { versionNo: v2 } : {})(outputVersionNumbers(snap).get(targetWorkId)),
|
|
240101
240397
|
artifacts: work ? artifactsOfWork(work, input) : [],
|
|
240102
240398
|
reviews,
|
|
240103
240399
|
events,
|
|
@@ -240113,6 +240409,7 @@ var init_activity_trace = __esm({
|
|
|
240113
240409
|
init_src();
|
|
240114
240410
|
init_activity2();
|
|
240115
240411
|
init_workorder_manager();
|
|
240412
|
+
init_activity_version();
|
|
240116
240413
|
init_src7();
|
|
240117
240414
|
}
|
|
240118
240415
|
});
|
|
@@ -240122,14 +240419,14 @@ function commandCardLine(command2) {
|
|
|
240122
240419
|
return command2.displayLabel?.trim() || stripInternalIds(command2.effectLabel ?? "");
|
|
240123
240420
|
}
|
|
240124
240421
|
function changeConfirmSummary(r) {
|
|
240125
|
-
if (r.continuation) return `\
|
|
240422
|
+
if (r.continuation) return `\u672C\u6279\u8F6E\u6570\u5DF2\u7528\u5B8C\uFF0C\u7B49\u4F60\u51B3\u5B9A\u662F\u5426\u7EE7\u7EED\uFF1A${r.plan.reason}`;
|
|
240126
240423
|
const why = r.plan.reason.slice(0, 100);
|
|
240127
240424
|
if (r.kind === "command" && r.command) {
|
|
240128
240425
|
return `\u7BA1\u7406\u8005\u8BF7\u6C42\u6267\u884C\u4E00\u4E2A\u9AD8\u5371\u64CD\u4F5C\uFF0C\u7B49\u4F60\u6388\u6743\uFF1A${commandCardLine(r.command)}`;
|
|
240129
240426
|
}
|
|
240130
240427
|
const ops = r.plan.ops ?? [];
|
|
240131
240428
|
if (ops.length > 0 && ops.every((o) => o.action === "resolveEscalation")) {
|
|
240132
|
-
return `\
|
|
240429
|
+
return `\u534F\u8C03\u8005\u8BA4\u4E3A\u8FD9\u6761\u5F85\u529E\u53EF\u4EE5\u5173\u95ED\u4E86\uFF0C\u7B49\u4F60\u786E\u8BA4\uFF1A${why}`;
|
|
240133
240430
|
}
|
|
240134
240431
|
const what = r.nonMonotonicOps.map((a) => C_ACTION_LABEL[a] ?? a).join("\u3001");
|
|
240135
240432
|
return `\u7BA1\u7406\u8005\u63D0\u4E86\u4E00\u4EFD\u9700\u8981\u4F60\u786E\u8BA4\u7684\u6539\u52A8\uFF08${what || "\u9500\u6BC1\u6027\u6539\u56FE"}\uFF09\uFF1A${why}`;
|
|
@@ -240240,7 +240537,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
240240
240537
|
// 这里只补通用结构位:actor(== reporter)、impact(重复上报次数)、overdue(要决策恒真)。
|
|
240241
240538
|
title: nodeLabel(a),
|
|
240242
240539
|
actor: actorRef2(gap.by),
|
|
240243
|
-
...gapReportCount > 1 ? { impact: `\u5DF2\
|
|
240540
|
+
...gapReportCount > 1 ? { impact: `\u5DF2\u7ECF\u7B2C ${gapReportCount} \u6B21\u6C42\u52A9` } : {},
|
|
240244
240541
|
overdue: exactEscalation ? true : overdueSince(gapSince) ?? false,
|
|
240245
240542
|
// ADR 0079 D1:把挂在这条 gap 上的那条上报 id 带到**顶层**(前端「沟通聊聊」据它绑定会话 → 关上报可省 id)。
|
|
240246
240543
|
...exactEscalation?.escalationId ? { escalationId: exactEscalation.escalationId } : {},
|
|
@@ -240274,7 +240571,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
240274
240571
|
// ADR-0108 D10:**不再截到 100 字**。熔断升级卡走的正是这条「无 gap」分支,而 D10 刚
|
|
240275
240572
|
// 往里放进了真正有用的东西(末次失败原文、哪台机器死了多久、去哪改绑)——一刀切到 100 字
|
|
240276
240573
|
// 会把它们全砍掉,只剩「连败 N 次」这种人早就知道的部分。前端按卡片排版自己收,不在这里截。
|
|
240277
|
-
summary: `\u300C${nodeLabel(a)}\u300D\
|
|
240574
|
+
summary: `\u300C${nodeLabel(a)}\u300D\u9700\u8981\u4F60\u5904\u7406${who}\uFF1A${e.reason}`
|
|
240278
240575
|
});
|
|
240279
240576
|
}
|
|
240280
240577
|
}
|
|
@@ -240321,7 +240618,7 @@ function buildInbox(model, me, leadOf, resolveActor, markers = [], slaMs, nowIso
|
|
|
240321
240618
|
workspace: a.workspace,
|
|
240322
240619
|
since: pause.at,
|
|
240323
240620
|
actionRequired: true,
|
|
240324
|
-
summary: "\
|
|
240621
|
+
summary: "\u5DF2\u9009\u62E9\u5148\u4E0D\u7EE7\u7EED\uFF0C\u4E4B\u540E\u7531\u4F60\u51B3\u5B9A\u662F\u5426\u7EE7\u7EED\u6267\u884C",
|
|
240325
240622
|
draftId: pause.requestId,
|
|
240326
240623
|
activityCardId: pause.requestId,
|
|
240327
240624
|
title: nodeLabel(a),
|
|
@@ -240565,10 +240862,10 @@ var init_inbox = __esm({
|
|
|
240565
240862
|
unlink: "\u65AD\u5F00\u4F9D\u8D56\u8FB9",
|
|
240566
240863
|
pin: "\u6539\u9489\u7248\u672C",
|
|
240567
240864
|
assign: "\u6539\u6D3E\u8D1F\u8D23\u4EBA",
|
|
240568
|
-
seal: "\u7EC8\
|
|
240569
|
-
reopen: "\
|
|
240865
|
+
seal: "\u7EC8\u6B62\u8FD9\u4E00\u6B65",
|
|
240866
|
+
reopen: "\u6062\u590D\u8FD9\u4E00\u6B65",
|
|
240570
240867
|
cancelPart: "\u64A4\u6389\u90E8\u4EF6",
|
|
240571
|
-
resolveEscalation: "\u5173\u95ED\
|
|
240868
|
+
resolveEscalation: "\u5173\u95ED\u5F85\u529E",
|
|
240572
240869
|
"edit:reviewers": "\u6539\u5BA1\u6838\u4EBA"
|
|
240573
240870
|
};
|
|
240574
240871
|
}
|
|
@@ -246013,13 +246310,21 @@ var init_sender = __esm({
|
|
|
246013
246310
|
});
|
|
246014
246311
|
|
|
246015
246312
|
// ../server/src/domains/runtime-allocation/faults.ts
|
|
246313
|
+
function isProviderAuthFailure(errorMessage2) {
|
|
246314
|
+
if (!errorMessage2) return false;
|
|
246315
|
+
return PROVIDER_AUTH_FAILURE_PATTERNS.some((p2) => p2.test(errorMessage2));
|
|
246316
|
+
}
|
|
246016
246317
|
function faultReasonOfExit(reason, errorMessage2) {
|
|
246017
246318
|
if (reason === "server-unreachable") return "node-error";
|
|
246018
246319
|
if (reason === "auth-error") return "node-error";
|
|
246019
246320
|
if (reason === "rate-limit") return "quota-exhausted";
|
|
246020
246321
|
if (reason === "error" && errorMessage2?.startsWith("\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5728\u8282\u70B9\u4E0A\u542F\u52A8\uFF1A")) return "startup-failed";
|
|
246322
|
+
if (reason === "error" && isProviderAuthFailure(errorMessage2)) return "unauthenticated";
|
|
246021
246323
|
return null;
|
|
246022
246324
|
}
|
|
246325
|
+
function faultScopeOf(fault) {
|
|
246326
|
+
return RUNTIME_FAULT_SCOPE[fault.reason];
|
|
246327
|
+
}
|
|
246023
246328
|
function probeIntervalMs(attempt) {
|
|
246024
246329
|
const raw = RUNTIME_FAULT_PROBE_INITIAL_MS * 2 ** Math.max(0, attempt - 1);
|
|
246025
246330
|
return Math.min(raw, RUNTIME_FAULT_PROBE_MAX_INTERVAL_MS);
|
|
@@ -246047,7 +246352,7 @@ function faultAfterFailure(previous3, input, now) {
|
|
|
246047
246352
|
return { ...base, nextProbeAt: new Date(now + probeIntervalMs(attempts)).toISOString() };
|
|
246048
246353
|
}
|
|
246049
246354
|
function quotaClearsFault(fault, quotaStatus) {
|
|
246050
|
-
if (RUNTIME_FAULT_RECOVERY[fault.reason] !== "readonly-probe"
|
|
246355
|
+
if (RUNTIME_FAULT_RECOVERY[fault.reason] !== "readonly-probe") return false;
|
|
246051
246356
|
return quotaStatus === "ok";
|
|
246052
246357
|
}
|
|
246053
246358
|
function describeFault(fault, now) {
|
|
@@ -246058,10 +246363,22 @@ function describeFault(fault, now) {
|
|
|
246058
246363
|
const mins = Math.max(0, Math.round(waitMs / 6e4));
|
|
246059
246364
|
return `${head}\uFF0C\u5DF2\u8BD5 ${fault.attempts} \u6B21\uFF0C${mins} \u5206\u949F\u540E\u653E\u4E00\u6761\u65B0\u4F1A\u8BDD\u8FC7\u53BB\u8BD5`;
|
|
246060
246365
|
}
|
|
246366
|
+
var PROVIDER_AUTH_FAILURE_PATTERNS;
|
|
246061
246367
|
var init_faults = __esm({
|
|
246062
246368
|
"../server/src/domains/runtime-allocation/faults.ts"() {
|
|
246063
246369
|
"use strict";
|
|
246064
246370
|
init_src();
|
|
246371
|
+
PROVIDER_AUTH_FAILURE_PATTERNS = [
|
|
246372
|
+
/Identity verification is required/i,
|
|
246373
|
+
/API Error:\s*40[13]\b/i,
|
|
246374
|
+
/Failed to authenticate/i,
|
|
246375
|
+
/OAuth (?:session|token) (?:has )?expired/i,
|
|
246376
|
+
/invalid (?:x-)?api[ _-]?key/i,
|
|
246377
|
+
/authentication_error/i,
|
|
246378
|
+
/Please run \/login/i,
|
|
246379
|
+
/\bNot logged in\b/i,
|
|
246380
|
+
/\b401 Unauthorized\b/i
|
|
246381
|
+
];
|
|
246065
246382
|
}
|
|
246066
246383
|
});
|
|
246067
246384
|
|
|
@@ -246795,9 +247112,13 @@ function nodesDomain(deps) {
|
|
|
246795
247112
|
const QUOTA_CAPABLE_KINDS = /* @__PURE__ */ new Set(["codex", "claude-code"]);
|
|
246796
247113
|
const UPDATE_TIMEOUT_MS = 15e4;
|
|
246797
247114
|
const nodeUpdates = /* @__PURE__ */ new Map();
|
|
247115
|
+
function nodeScopedFaultOf(nodeId) {
|
|
247116
|
+
for (const f2 of faultByTarget.values()) if (f2.nodeId === nodeId && faultScopeOf(f2) === "node") return f2;
|
|
247117
|
+
return void 0;
|
|
247118
|
+
}
|
|
246798
247119
|
function runtimeInfoOf(r) {
|
|
246799
247120
|
const quota = quotaByNode.get(r.nodeId)?.find((q2) => q2.kind === r.kind);
|
|
246800
|
-
const fault = faultByTarget.get(faultKey(r.nodeId, r.kind));
|
|
247121
|
+
const fault = faultByTarget.get(faultKey(r.nodeId, r.kind)) ?? nodeScopedFaultOf(r.nodeId);
|
|
246801
247122
|
const activeRunCount = deps.activeRunCountOf?.(r.nodeId, r.kind) ?? 0;
|
|
246802
247123
|
const activeRuns = deps.activeRunsOf?.(r.nodeId, r.kind);
|
|
246803
247124
|
return {
|
|
@@ -246827,6 +247148,61 @@ function nodesDomain(deps) {
|
|
|
246827
247148
|
}
|
|
246828
247149
|
daemon?.close();
|
|
246829
247150
|
}
|
|
247151
|
+
const emptySince = /* @__PURE__ */ new Map();
|
|
247152
|
+
const restartEmptyClock = (nodeId) => {
|
|
247153
|
+
emptySince.set(nodeId, Date.now());
|
|
247154
|
+
};
|
|
247155
|
+
async function removeNode(nodeId, releaseAs) {
|
|
247156
|
+
const kinds = [...new Set((await deps.nodeStore.listRuntimes(nodeId)).map((r) => r.kind))];
|
|
247157
|
+
revokeNodeAccess(nodeId);
|
|
247158
|
+
await deps.nodeStore.deleteNode(nodeId);
|
|
247159
|
+
emptySince.delete(nodeId);
|
|
247160
|
+
const released = [];
|
|
247161
|
+
if (releaseAs) {
|
|
247162
|
+
for (const runtimeKind of kinds) {
|
|
247163
|
+
released.push(...await deps.releaseBindingsOnRuntime?.(releaseAs.companyId, { nodeId, runtimeKind }, releaseAs.actor) ?? []);
|
|
247164
|
+
}
|
|
247165
|
+
}
|
|
247166
|
+
return released;
|
|
247167
|
+
}
|
|
247168
|
+
async function sweepEmptyNodes(graceMs) {
|
|
247169
|
+
const nowMs = Date.now();
|
|
247170
|
+
const nodes = await deps.nodeStore.listNodes();
|
|
247171
|
+
const withRuntime = new Set((await deps.nodeStore.listRuntimes()).map((r) => r.nodeId));
|
|
247172
|
+
const live = new Set(nodes.map((n) => n.id));
|
|
247173
|
+
for (const id of [...emptySince.keys()]) if (!live.has(id) || withRuntime.has(id)) emptySince.delete(id);
|
|
247174
|
+
const removed = [];
|
|
247175
|
+
for (const n of nodes) {
|
|
247176
|
+
if (withRuntime.has(n.id)) continue;
|
|
247177
|
+
const since = emptySince.get(n.id);
|
|
247178
|
+
if (since === void 0) {
|
|
247179
|
+
emptySince.set(n.id, nowMs);
|
|
247180
|
+
continue;
|
|
247181
|
+
}
|
|
247182
|
+
if (nowMs - since < graceMs) continue;
|
|
247183
|
+
if ((await deps.nodeStore.listRuntimes(n.id)).length > 0) {
|
|
247184
|
+
emptySince.delete(n.id);
|
|
247185
|
+
continue;
|
|
247186
|
+
}
|
|
247187
|
+
await removeNode(n.id);
|
|
247188
|
+
removed.push(n.id);
|
|
247189
|
+
console.log(`[nodes] \u6E05\u7406\u6CA1\u6709\u7ED1\u5B9A\u8FD0\u884C\u65F6\u7684\u8282\u70B9\uFF1A${n.name || n.hostname}\uFF08${n.id}\uFF09\uFF0C\u5DF2\u7A7A\u7740\u8D85\u8FC7 ${Math.round(graceMs / 6e4)} \u5206\u949F`);
|
|
247190
|
+
}
|
|
247191
|
+
if (removed.length > 0) deps.onStatusChange?.();
|
|
247192
|
+
return removed;
|
|
247193
|
+
}
|
|
247194
|
+
if (deps.emptyNodeSweep) {
|
|
247195
|
+
const { graceMs, intervalMs } = deps.emptyNodeSweep;
|
|
247196
|
+
let sweeping = false;
|
|
247197
|
+
const timer = setInterval(() => {
|
|
247198
|
+
if (sweeping) return;
|
|
247199
|
+
sweeping = true;
|
|
247200
|
+
void sweepEmptyNodes(graceMs).catch((err) => console.warn(`[nodes] \u7A7A\u8282\u70B9\u6E05\u626B\u5931\u8D25\uFF08\u4E0B\u4E00\u62CD\u518D\u8BD5\uFF09\uFF1A${err instanceof Error ? err.message : String(err)}`)).finally(() => {
|
|
247201
|
+
sweeping = false;
|
|
247202
|
+
});
|
|
247203
|
+
}, intervalMs);
|
|
247204
|
+
timer.unref?.();
|
|
247205
|
+
}
|
|
246830
247206
|
const publicUpdateStatus = (entry, activeRunCount) => ({
|
|
246831
247207
|
state: entry.state,
|
|
246832
247208
|
requestedAt: new Date(entry.requestedAtMs).toISOString(),
|
|
@@ -247046,6 +247422,7 @@ function nodesDomain(deps) {
|
|
|
247046
247422
|
// ——那一路在 /api/nodes/exchange 里按入网令牌写名字,不经过这里。
|
|
247047
247423
|
...existing?.name ? { name: existing.name } : d.meta.nodeName ? { name: d.meta.nodeName } : {}
|
|
247048
247424
|
});
|
|
247425
|
+
restartEmptyClock(daemonId);
|
|
247049
247426
|
await nodeStore.alignRuntimeCompanies(daemonId);
|
|
247050
247427
|
await nodeStore.setNodeRuntimesOnline(daemonId, true);
|
|
247051
247428
|
} else {
|
|
@@ -247345,6 +247722,7 @@ function nodesDomain(deps) {
|
|
|
247345
247722
|
} else if (entry.companyId) {
|
|
247346
247723
|
await deps.nodeStore.setNodeCompany?.(nodeId, entry.companyId);
|
|
247347
247724
|
}
|
|
247725
|
+
restartEmptyClock(nodeId);
|
|
247348
247726
|
deps.enrollTokens.consume(enrollToken);
|
|
247349
247727
|
if (entry.name) await deps.nodeStore.updateNodeName(nodeId, entry.name);
|
|
247350
247728
|
deps.nodeTokens.clearRevocations(nodeId);
|
|
@@ -247355,8 +247733,6 @@ function nodesDomain(deps) {
|
|
|
247355
247733
|
router.patch("/api/nodes/:nodeId", async (req) => {
|
|
247356
247734
|
const nodeId = req.params["nodeId"];
|
|
247357
247735
|
if (!nodeId) return { status: 400, body: { error: "missing nodeId" } };
|
|
247358
|
-
const forbidden = await forbidUnlessOrgManager(req, "\u91CD\u547D\u540D\u8282\u70B9");
|
|
247359
|
-
if (forbidden) return forbidden;
|
|
247360
247736
|
const scope2 = req.auth.companyId !== void 0 ? { companyId: req.auth.companyId } : void 0;
|
|
247361
247737
|
const node2 = (await deps.nodeStore.listNodes(scope2)).find((n) => n.id === nodeId);
|
|
247362
247738
|
if (!node2) return { status: 404, body: { error: "NODE_NOT_FOUND", message: "\u8282\u70B9\u4E0D\u5B58\u5728\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7EC4\u7EC7" } };
|
|
@@ -247397,21 +247773,26 @@ function nodesDomain(deps) {
|
|
|
247397
247773
|
const scope2 = req.auth.companyId !== void 0 ? { companyId: req.auth.companyId } : void 0;
|
|
247398
247774
|
const node2 = (await deps.nodeStore.listNodes(scope2)).find((n) => n.id === nodeId);
|
|
247399
247775
|
if (!node2) return { status: 404, body: { error: "NODE_NOT_FOUND", message: "\u8282\u70B9\u4E0D\u5B58\u5728\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u7EC4\u7EC7" } };
|
|
247400
|
-
|
|
247776
|
+
let cleared = await deps.nodeStore.clearRuntimeFault(nodeId, runtimeKind);
|
|
247401
247777
|
faultByTarget.delete(faultKey(nodeId, runtimeKind));
|
|
247778
|
+
for (const f2 of [...faultByTarget.values()]) {
|
|
247779
|
+
if (f2.nodeId !== nodeId || faultScopeOf(f2) !== "node") continue;
|
|
247780
|
+
cleared = await deps.nodeStore.clearRuntimeFault(nodeId, f2.runtimeKind) || cleared;
|
|
247781
|
+
faultByTarget.delete(faultKey(nodeId, f2.runtimeKind));
|
|
247782
|
+
}
|
|
247402
247783
|
deps.onStatusChange?.();
|
|
247403
247784
|
return { status: 200, body: { ok: true, cleared } };
|
|
247404
247785
|
});
|
|
247405
247786
|
router.delete("/api/nodes/:nodeId", async (req) => {
|
|
247406
247787
|
const nodeId = req.params["nodeId"];
|
|
247407
247788
|
if (!nodeId) return { status: 400, body: { error: "missing nodeId" } };
|
|
247408
|
-
const
|
|
247409
|
-
|
|
247410
|
-
|
|
247411
|
-
|
|
247412
|
-
|
|
247413
|
-
released.push(...await deps.releaseBindingsOnRuntime?.(req.auth.companyId, { nodeId, runtimeKind }, req.auth.actor) ?? []);
|
|
247789
|
+
const ifNoRuntimes = req.query.get("ifNoRuntimes");
|
|
247790
|
+
if (ifNoRuntimes === "1" || ifNoRuntimes === "true") {
|
|
247791
|
+
if ((await deps.nodeStore.listRuntimes(nodeId)).length > 0) {
|
|
247792
|
+
return { status: 409, body: { error: "NODE_HAS_RUNTIMES", message: "\u8FD9\u53F0\u673A\u5668\u5DF2\u7ECF\u7ED1\u5B9A\u4E86\u8FD0\u884C\u65F6\uFF0C\u4FDD\u7559\u4E0D\u5220" } };
|
|
247793
|
+
}
|
|
247414
247794
|
}
|
|
247795
|
+
const released = await removeNode(nodeId, { companyId: req.auth.companyId, actor: req.auth.actor });
|
|
247415
247796
|
deps.onStatusChange?.();
|
|
247416
247797
|
return { status: 200, body: { ok: true, releasedActorIds: released } };
|
|
247417
247798
|
});
|
|
@@ -247646,7 +248027,7 @@ function normalizeGatewayUrl(raw) {
|
|
|
247646
248027
|
function newNodeId() {
|
|
247647
248028
|
return "node-" + (0, import_node_crypto63.randomUUID)().replace(/-/g, "").slice(0, 12);
|
|
247648
248029
|
}
|
|
247649
|
-
var import_node_crypto63, import_node_fs18, import_node_url6, import_node_path22, NODE_NAME_MAX_LENGTH;
|
|
248030
|
+
var import_node_crypto63, import_node_fs18, import_node_url6, import_node_path22, NODE_NAME_MAX_LENGTH, EMPTY_NODE_GRACE_MS, EMPTY_NODE_SWEEP_INTERVAL_MS;
|
|
247650
248031
|
var init_routes7 = __esm({
|
|
247651
248032
|
"../server/src/domains/nodes/routes.ts"() {
|
|
247652
248033
|
"use strict";
|
|
@@ -247664,6 +248045,8 @@ var init_routes7 = __esm({
|
|
|
247664
248045
|
init_usage_read();
|
|
247665
248046
|
init_node_health();
|
|
247666
248047
|
NODE_NAME_MAX_LENGTH = 64;
|
|
248048
|
+
EMPTY_NODE_GRACE_MS = 30 * 60 * 1e3;
|
|
248049
|
+
EMPTY_NODE_SWEEP_INTERVAL_MS = 60 * 1e3;
|
|
247667
248050
|
}
|
|
247668
248051
|
});
|
|
247669
248052
|
|
|
@@ -247681,12 +248064,15 @@ var init_coordinator_runs = __esm({
|
|
|
247681
248064
|
function isRuntimeDrifted(rt) {
|
|
247682
248065
|
return rt?.presentOnMachine === false;
|
|
247683
248066
|
}
|
|
247684
|
-
function runtimeDriftBlock(runtimes, nodeId, runtimeKind) {
|
|
248067
|
+
function runtimeDriftBlock(runtimes, nodeId, runtimeKind, nodeName) {
|
|
247685
248068
|
const rt = runtimes.find((r) => r.kind === runtimeKind);
|
|
247686
248069
|
if (!isRuntimeDrifted(rt)) return null;
|
|
247687
248070
|
return {
|
|
247688
248071
|
reason: "runtime-not-on-machine",
|
|
247689
|
-
errorMessage:
|
|
248072
|
+
errorMessage: (
|
|
248073
|
+
/* 奕璇 2026-09-29 审定(清单第十一节):这句上的是任务执行失败原因,给人看的,不讲登记表 / 只增不减这些内部机制。 */
|
|
248074
|
+
`\u673A\u5668\u300C${nodeName?.trim() || nodeId}\u300D\u4E0A\u627E\u4E0D\u5230 ${runtimeKind} \u4E86\uFF0C\u53EF\u80FD\u5DF2\u88AB\u5378\u8F7D\u3002\u8FD9\u4E00\u6B65\u6CA1\u6709\u6D3E\u7ED9\u5B83\u3002\u8BF7\u5728\u8FD0\u884C\u65F6\u9875\u628A\u8FD9\u4E00\u9879\u5220\u6389\uFF0C\u6216\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u91CD\u65B0\u5B89\u88C5 ${runtimeKind} \u540E\u518D\u8BD5\u3002`
|
|
248075
|
+
)
|
|
247690
248076
|
};
|
|
247691
248077
|
}
|
|
247692
248078
|
var init_runtime_drift = __esm({
|
|
@@ -247741,6 +248127,14 @@ function faultIsBlocking(fault, now) {
|
|
|
247741
248127
|
if (!fault.nextProbeAt) return true;
|
|
247742
248128
|
return Date.parse(fault.nextProbeAt) > now;
|
|
247743
248129
|
}
|
|
248130
|
+
function blockingNodeFaults(faults, now) {
|
|
248131
|
+
const out = /* @__PURE__ */ new Map();
|
|
248132
|
+
for (const fault of faults?.values() ?? []) {
|
|
248133
|
+
if (RUNTIME_FAULT_SCOPE[fault.reason] !== "node" || !faultIsBlocking(fault, now)) continue;
|
|
248134
|
+
if (!out.has(fault.nodeId)) out.set(fault.nodeId, fault);
|
|
248135
|
+
}
|
|
248136
|
+
return out;
|
|
248137
|
+
}
|
|
247744
248138
|
function failureReason(rejections) {
|
|
247745
248139
|
if (rejections.length === 0) return "no-candidates";
|
|
247746
248140
|
const causes = new Set(rejections.map((r) => r.cause));
|
|
@@ -247757,6 +248151,7 @@ function failureReason(rejections) {
|
|
|
247757
248151
|
function allocateRuntime(input, now = Date.now()) {
|
|
247758
248152
|
const rejections = [];
|
|
247759
248153
|
const eligible = [];
|
|
248154
|
+
const nodeFaults = blockingNodeFaults(input.faults, now);
|
|
247760
248155
|
for (const candidate of input.candidates) {
|
|
247761
248156
|
const key2 = runtimeTargetKey(candidate);
|
|
247762
248157
|
const node2 = input.nodes.get(candidate.nodeId);
|
|
@@ -247783,6 +248178,11 @@ function allocateRuntime(input, now = Date.now()) {
|
|
|
247783
248178
|
reject("faulted", `${fault.reason}${fault.detail ? `\uFF1A${fault.detail}` : ""}${fault.awaitingManual ? "\uFF08\u7B49\u4EBA\u5DE5\u6062\u590D\uFF09" : ""}`);
|
|
247784
248179
|
continue;
|
|
247785
248180
|
}
|
|
248181
|
+
const nodeFault = nodeFaults.get(candidate.nodeId);
|
|
248182
|
+
if (nodeFault) {
|
|
248183
|
+
reject("faulted", `\u6574\u53F0\u673A\u5668\u6545\u969C\uFF08\u5728 ${nodeFault.runtimeKind} \u4E0A\u53D1\u73B0\uFF0C${nodeFault.reason}${nodeFault.detail ? `\uFF1A${nodeFault.detail}` : ""}\uFF09${nodeFault.awaitingManual ? "\uFF08\u7B49\u4EBA\u5DE5\u6062\u590D\uFF09" : ""}`);
|
|
248184
|
+
continue;
|
|
248185
|
+
}
|
|
247786
248186
|
if (atCapacity(node2)) {
|
|
247787
248187
|
reject("at-capacity", `\u5728\u8DD1 ${node2.activeRunCount} / \u4E0A\u9650 ${node2.maxConcurrent}`);
|
|
247788
248188
|
continue;
|
|
@@ -247890,9 +248290,7 @@ var init_errors6 = __esm({
|
|
|
247890
248290
|
|
|
247891
248291
|
// ../server/src/domains/runtime-allocation/service.ts
|
|
247892
248292
|
function isRuntimeClassFailure(reason, errorMessage2) {
|
|
247893
|
-
|
|
247894
|
-
if (reason === "error" && errorMessage2?.startsWith("\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5728\u8282\u70B9\u4E0A\u542F\u52A8\uFF1A")) return true;
|
|
247895
|
-
return false;
|
|
248293
|
+
return faultReasonOfExit(reason, errorMessage2) !== null;
|
|
247896
248294
|
}
|
|
247897
248295
|
function createRuntimeAllocator(ports) {
|
|
247898
248296
|
const units = /* @__PURE__ */ new Map();
|
|
@@ -248058,6 +248456,8 @@ function createRuntimeAllocator(ports) {
|
|
|
248058
248456
|
if (!resolved || !ports.clearFault) return;
|
|
248059
248457
|
try {
|
|
248060
248458
|
await ports.clearFault(resolved);
|
|
248459
|
+
const siblings = (await ports.faults().catch(() => [])).filter((f2) => f2.nodeId === resolved.nodeId && f2.runtimeKind !== resolved.runtimeKind && faultScopeOf(f2) === "node");
|
|
248460
|
+
for (const f2 of siblings) await ports.clearFault({ nodeId: f2.nodeId, runtimeKind: f2.runtimeKind });
|
|
248061
248461
|
} catch (err) {
|
|
248062
248462
|
log3(`[runtime-alloc] \u6545\u969C\u89E3\u9664\u5931\u8D25 ${resolved.nodeId}\xB7${resolved.runtimeKind}\uFF1A${String(err)}`);
|
|
248063
248463
|
}
|
|
@@ -258078,8 +258478,9 @@ var init_daemon_adapter = __esm({
|
|
|
258078
258478
|
hub.addDisconnectListener((daemonId) => this.onNodeDown(daemonId));
|
|
258079
258479
|
hub.addConnectListener((daemon) => this.onNodeUp(daemon));
|
|
258080
258480
|
hub.addSessionConnectListener?.((i) => this.onSessionUp(i.dispatchId));
|
|
258081
|
-
hub.registerSessionClaimCheck?.(({ dispatchId }) => {
|
|
258481
|
+
hub.registerSessionClaimCheck?.(({ dispatchId, nodeId }) => {
|
|
258082
258482
|
const e = this.pending.get(dispatchId);
|
|
258483
|
+
if (e && nodeId && e.nodeId !== nodeId) return "settled";
|
|
258083
258484
|
if (e) return e.exited ? "settled" : "live";
|
|
258084
258485
|
return this.settledDispatchIds.has(dispatchId) ? "settled" : "unknown";
|
|
258085
258486
|
});
|
|
@@ -258515,6 +258916,7 @@ var init_daemon_adapter = __esm({
|
|
|
258515
258916
|
appendWaiters: []
|
|
258516
258917
|
};
|
|
258517
258918
|
this.pending.set(dispatchId, entry);
|
|
258919
|
+
this.settledDispatchIds.delete(dispatchId);
|
|
258518
258920
|
const sessionAuth = this.sessionAuth ? { ...this.sessionAuth.issue({ nodeId, dispatchId }), gatewayUrl: this.sessionAuth.gatewayUrl } : void 0;
|
|
258519
258921
|
let sent;
|
|
258520
258922
|
try {
|
|
@@ -280700,6 +281102,8 @@ __export(src_exports2, {
|
|
|
280700
281102
|
DirBlobStore: () => DirBlobStore,
|
|
280701
281103
|
DisabledSkillMarketClient: () => DisabledSkillMarketClient,
|
|
280702
281104
|
EMPTY_ACTOR_NAMES: () => EMPTY_ACTOR_NAMES,
|
|
281105
|
+
EMPTY_NODE_GRACE_MS: () => EMPTY_NODE_GRACE_MS,
|
|
281106
|
+
EMPTY_NODE_SWEEP_INTERVAL_MS: () => EMPTY_NODE_SWEEP_INTERVAL_MS,
|
|
280703
281107
|
EscalationDeliveryWorker: () => EscalationDeliveryWorker,
|
|
280704
281108
|
ExecutionContinuityService: () => ExecutionContinuityService,
|
|
280705
281109
|
FakeSkillMarketClient: () => FakeSkillMarketClient,
|
|
@@ -284089,10 +284493,14 @@ var CompanyDispatchBridges = class {
|
|
|
284089
284493
|
// ../cli/src/review-stall.ts
|
|
284090
284494
|
init_src6();
|
|
284091
284495
|
init_src5();
|
|
284496
|
+
init_stall_copy();
|
|
284092
284497
|
var STALL_SOURCE_PREFIX = "sla:stall:";
|
|
284093
284498
|
var REVIEW_STALL_SOURCE = "sla:review-stall";
|
|
284094
|
-
function stallSourceFor(kind) {
|
|
284095
|
-
return `${STALL_SOURCE_PREFIX}${kind}`;
|
|
284499
|
+
function stallSourceFor(kind, code2) {
|
|
284500
|
+
return `${STALL_SOURCE_PREFIX}${kind}${code2 ? `:${code2}` : ""}`;
|
|
284501
|
+
}
|
|
284502
|
+
function reasonCodeOf(reason) {
|
|
284503
|
+
return reason.kind === "accept-blocked" || reason.kind === "idle-unexplained" ? reason.code : void 0;
|
|
284096
284504
|
}
|
|
284097
284505
|
function isStallSource(source) {
|
|
284098
284506
|
return !!source && (source === REVIEW_STALL_SOURCE || source.startsWith(STALL_SOURCE_PREFIX));
|
|
@@ -284104,22 +284512,23 @@ function stallBackoffMsFor(priorCards, ladder = DEFAULT_STALL_BACKOFF_MS) {
|
|
|
284104
284512
|
}
|
|
284105
284513
|
var isOpenReview = (r) => !!r && !r.verdict && !r.endedAt && !r.cancelledAt;
|
|
284106
284514
|
function describeReviewStall(reqs, reviews, conclusion) {
|
|
284107
|
-
|
|
284108
|
-
|
|
284109
|
-
|
|
284110
|
-
}
|
|
284111
|
-
return "\u8FD9\u4E00\u6B65**\u6CA1\u6709\u914D\u5230\u4EFB\u4F55\u8BC4\u5BA1\u4EBA**\uFF08\u672C\u7C7B\u578B\u6CA1\u6709\u8BC4\u5BA1\u95F8\uFF0C\u6216\u5EFA\u5355\u65F6\u8BC4\u5BA1\u4EBA\u6CA1\u5C55\u5F00\u51FA\u6765\uFF09\u3002";
|
|
284112
|
-
}
|
|
284515
|
+
const code2 = reviewStallFactsCode(reqs, conclusion);
|
|
284516
|
+
if (code2 === "no-conclude") return "\u8FD9\u4E00\u6B65\u4EA4\u4E86\u6210\u679C\uFF0C\u4F46\u6267\u884C\u4EBA\u6CA1\u6709\u8BF4\u660E\u5DF2\u7ECF\u505A\u5B8C\uFF0C\u6240\u4EE5\u6CA1\u6709\u8FDB\u5165\u5BA1\u6838\u3002";
|
|
284517
|
+
if (code2 === "no-reviewers") return "\u8FD9\u4E00\u6B65\u6CA1\u6709\u914D\u5230\u5BA1\u6838\u4EBA\u3002";
|
|
284113
284518
|
const lines = reqs.map((r) => {
|
|
284114
284519
|
const lr = r.latestReviewId ? reviews.find((x2) => x2.id === r.latestReviewId) : void 0;
|
|
284115
|
-
if (!lr) return `\u300C${r.reviewGroup}\u300D\uFF1A\u8FD8\u6CA1\
|
|
284116
|
-
if (lr.verdict) return `\u300C${r.reviewGroup}\u300D\uFF1A\u5DF2\
|
|
284117
|
-
if (lr.cancelledAt || lr.endedAt) return `\u300C${r.reviewGroup}\u300D\uFF1A\
|
|
284118
|
-
return `\u300C${r.reviewGroup}\u300D\uFF1A\u5728\u7B49 ${r.reviewerActorId} \
|
|
284520
|
+
if (!lr) return `\u300C${r.reviewGroup}\u300D\uFF1A\u8FD8\u6CA1\u53D1\u8D77\u5BA1\u6838`;
|
|
284521
|
+
if (lr.verdict) return `\u300C${r.reviewGroup}\u300D\uFF1A\u5DF2\u7ED9\u51FA\u7ED3\u8BBA\uFF08${lr.verdict === "approve" ? "\u5BA1\u6838\u901A\u8FC7" : "\u5BA1\u6838\u4E0D\u901A\u8FC7"}\uFF09`;
|
|
284522
|
+
if (lr.cancelledAt || lr.endedAt) return `\u300C${r.reviewGroup}\u300D\uFF1A\u5BA1\u6838\u8D85\u65F6\u6CA1\u6709\u5B8C\u6210\uFF0C\u4E0D\u4F1A\u518D\u91CD\u65B0\u53D1\u8D77`;
|
|
284523
|
+
return `\u300C${r.reviewGroup}\u300D\uFF1A\u5728\u7B49 ${r.reviewerActorId} \u5BA1\u6838`;
|
|
284119
284524
|
});
|
|
284120
|
-
return `\u5404\
|
|
284525
|
+
return `\u5404\u5BA1\u6838\u7EC4\u7684\u72B6\u6001\uFF1A
|
|
284121
284526
|
- ${lines.join("\n- ")}`;
|
|
284122
284527
|
}
|
|
284528
|
+
function reviewStallFactsCode(reqs, conclusion) {
|
|
284529
|
+
if (reqs.length > 0) return void 0;
|
|
284530
|
+
return conclusion === null ? "no-conclude" : "no-reviewers";
|
|
284531
|
+
}
|
|
284123
284532
|
function lastActivityAt(snap, nodeId) {
|
|
284124
284533
|
let max = 0;
|
|
284125
284534
|
const bump = (v2) => {
|
|
@@ -284179,34 +284588,34 @@ function renderStallReason(reason, facts) {
|
|
|
284179
284588
|
switch (reason.kind) {
|
|
284180
284589
|
case "checkpoints-exhausted":
|
|
284181
284590
|
return {
|
|
284182
|
-
headline: `\u8FD9\u4E00\u6B65
|
|
284591
|
+
headline: `\u8FD9\u4E00\u6B65\u8FDE\u7EED ${reason.rounds} \u8F6E\u63D0\u4EA4\u7684\u5185\u5BB9\u90FD\u6CA1\u6709\u53D8\u5316\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u7EE7\u7EED\u6267\u884C\u3002`,
|
|
284183
284592
|
detail: facts,
|
|
284184
|
-
action: "\u9700\u8981\u4F60\u5904\u7406\uFF1A\
|
|
284593
|
+
action: "\u9700\u8981\u4F60\u5904\u7406\uFF1A\u5148\u770B\u6700\u8FD1\u63D0\u4EA4\u7684\u5185\u5BB9\u548C\u8FD8\u5269\u54EA\u4E9B\u6CA1\u505A\uFF0C\u8865\u5145\u8BF4\u660E\u540E\u91CD\u65B0\u8FD0\u884C\uFF1B\u5982\u679C\u5176\u5B9E\u5DF2\u7ECF\u505A\u5B8C\uFF0C\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002"
|
|
284185
284594
|
};
|
|
284186
284595
|
case "gate-rejections-exhausted":
|
|
284187
284596
|
return {
|
|
284188
|
-
headline: `\u8FD9\u4E00\u6B65
|
|
284597
|
+
headline: `\u8FD9\u4E00\u6B65\u8FDE\u7EED ${reason.rounds} \u6B21\u5BA1\u6838\u4E0D\u901A\u8FC7\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u81EA\u52A8\u8FD4\u5DE5\u3002`,
|
|
284189
284598
|
detail: facts,
|
|
284190
|
-
action: "\u9700\u8981\u4F60\u5904\u7406\uFF1A\u770B\
|
|
284599
|
+
action: "\u9700\u8981\u4F60\u5904\u7406\uFF1A\u5148\u770B\u5BA1\u6838\u610F\u89C1\u548C\u6267\u884C\u4EBA\u6BCF\u6B21\u4EA4\u7684\u5185\u5BB9\uFF08\u591A\u534A\u662F\u5185\u5BB9\u6CA1\u6709\u5B9E\u8D28\u53D8\u5316\uFF09\uFF0C\u518D\u9009\u62E9\uFF1A\u91CD\u65B0\u8FD0\u884C\u3001\u6362\u6267\u884C\u4EBA\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002"
|
|
284191
284600
|
};
|
|
284192
284601
|
case "review-exhausted":
|
|
284193
284602
|
return {
|
|
284194
|
-
headline: `\u300C${reason.group}\u300D\u7684\
|
|
284603
|
+
headline: `\u300C${reason.group}\u300D\u7684\u5BA1\u6838\u53D1\u8D77\u4E86 ${reason.rounds} \u6B21\u90FD\u6CA1\u6709\u7B49\u5230\u7ED3\u679C\uFF0C\u7CFB\u7EDF\u5DF2\u505C\u6B62\u91CD\u65B0\u53D1\u8D77\u3002`,
|
|
284195
284604
|
detail: facts,
|
|
284196
|
-
action: `\u9700\u8981\u4F60\u5904\u7406\uFF1A\u91CD\
|
|
284605
|
+
action: `\u9700\u8981\u4F60\u5904\u7406\uFF1A\u91CD\u65B0\u53D1\u8D77\u8FD9\u4E00\u8F6E\u5BA1\u6838\u3001\u6362\u4E00\u4E2A\u5BA1\u6838\u4EBA\uFF08\u5F53\u524D\u662F ${reason.reviewerActorId}\uFF09\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002`
|
|
284197
284606
|
};
|
|
284198
284607
|
case "accept-blocked":
|
|
284199
|
-
|
|
284200
|
-
|
|
284201
|
-
|
|
284202
|
-
|
|
284203
|
-
|
|
284204
|
-
|
|
284205
|
-
|
|
284206
|
-
|
|
284207
|
-
|
|
284208
|
-
|
|
284209
|
-
|
|
284608
|
+
case "idle-unexplained": {
|
|
284609
|
+
const copy = reason.code ? notDoneCopy(reason.code, reason.kind === "accept-blocked" && reason.deadReason ? { deadReason: reason.deadReason } : {}) : void 0;
|
|
284610
|
+
if (copy) {
|
|
284611
|
+
return {
|
|
284612
|
+
headline: "\u8FD9\u4E00\u8F6E\u7ED3\u675F\u4E86\uFF0C\u4F46\u8FD8\u4E0D\u80FD\u7B97\u5B8C\u6210\u3002",
|
|
284613
|
+
detail: reason.kind === "accept-blocked" ? `\u539F\u56E0\uFF1A${copy.reason}\u3002` : facts,
|
|
284614
|
+
action: `\u9700\u8981\u4F60\u5904\u7406\uFF1A${copy.fix}\u3002`
|
|
284615
|
+
};
|
|
284616
|
+
}
|
|
284617
|
+
return reason.kind === "accept-blocked" ? { headline: "\u8FD9\u4E00\u8F6E\u7ED3\u675F\u4E86\uFF0C\u4F46\u8FD8\u4E0D\u80FD\u7B97\u5B8C\u6210\u3002", detail: facts, action: "\u9700\u8981\u4F60\u5904\u7406\uFF1A\u91CD\u65B0\u8FD0\u884C\uFF0C\u6216\u76F4\u63A5\u6309\u5F53\u524D\u6210\u679C\u7B97\u5B8C\u6210\u3002" } : { headline: "\u8FD9\u4E00\u6B65\u505A\u5B8C\u4E4B\u540E\u957F\u65F6\u95F4\u6CA1\u6709\u52A8\u9759\uFF0C\u7CFB\u7EDF\u627E\u4E0D\u5230\u539F\u56E0\u3002", detail: facts, action: "\u9700\u8981\u4F60\u770B\u4E00\u4E0B\u5B83\u5361\u5728\u54EA\u91CC\u3002" };
|
|
284618
|
+
}
|
|
284210
284619
|
}
|
|
284211
284620
|
}
|
|
284212
284621
|
function collectReviewStallSignals(snap, now, opts) {
|
|
@@ -284237,7 +284646,7 @@ function collectReviewStallSignals(snap, now, opts) {
|
|
|
284237
284646
|
artifactId: node2.id,
|
|
284238
284647
|
sinceMs,
|
|
284239
284648
|
reason,
|
|
284240
|
-
source: stallSourceFor(reason.kind),
|
|
284649
|
+
source: stallSourceFor(reason.kind, reasonCodeOf(reason)),
|
|
284241
284650
|
...renderStallReason(reason, facts),
|
|
284242
284651
|
priorCards: priorCards.length,
|
|
284243
284652
|
...sinceLastReportMs !== void 0 ? { sinceLastReportMs } : {}
|
|
@@ -284258,13 +284667,19 @@ function collectReviewStallSignals(snap, now, opts) {
|
|
|
284258
284667
|
if (hasUnexemptedVeto(scanBlockersForNode(state, node2, lw), "autoConclude")) continue;
|
|
284259
284668
|
if (reqs.some((r) => isOpenReview(r.latestReviewId ? snap.reviews.find((x2) => x2.id === r.latestReviewId) : void 0))) continue;
|
|
284260
284669
|
const blocked = acceptBlock(state, lw.id);
|
|
284670
|
+
if (blocked?.code === "no-output" && node2.latestAcceptId) continue;
|
|
284261
284671
|
if (blocked) {
|
|
284672
|
+
const reason = {
|
|
284673
|
+
kind: "accept-blocked",
|
|
284674
|
+
code: blocked.code,
|
|
284675
|
+
...blocked.code === "work-dead" && lw.rejectedReason ? { deadReason: lw.rejectedReason } : {}
|
|
284676
|
+
};
|
|
284262
284677
|
out.push({
|
|
284263
284678
|
artifactId: node2.id,
|
|
284264
284679
|
sinceMs,
|
|
284265
|
-
reason
|
|
284266
|
-
source: stallSourceFor("accept-blocked"),
|
|
284267
|
-
...renderStallReason(
|
|
284680
|
+
reason,
|
|
284681
|
+
source: stallSourceFor("accept-blocked", blocked.code),
|
|
284682
|
+
...renderStallReason(reason, blocked.detail),
|
|
284268
284683
|
priorCards: priorCards.length,
|
|
284269
284684
|
...sinceLastReportMs !== void 0 ? { sinceLastReportMs } : {}
|
|
284270
284685
|
});
|
|
@@ -284273,7 +284688,8 @@ function collectReviewStallSignals(snap, now, opts) {
|
|
|
284273
284688
|
if (sinceMs <= opts.idleFallbackMs) continue;
|
|
284274
284689
|
scanTouched ??= nodesScanWillTouch(snap, new Date(now).toISOString(), tripCtx);
|
|
284275
284690
|
if (scanTouched.has(node2.id)) continue;
|
|
284276
|
-
|
|
284691
|
+
const factsCode = reviewStallFactsCode(reqs, lw.conclusion ?? null);
|
|
284692
|
+
emit({ kind: "idle-unexplained", ...factsCode ? { code: factsCode } : {} });
|
|
284277
284693
|
}
|
|
284278
284694
|
return out;
|
|
284279
284695
|
}
|
|
@@ -284291,7 +284707,7 @@ function renderStallCard(st, now, fmtSince) {
|
|
|
284291
284707
|
` : "";
|
|
284292
284708
|
const repeatNote = st.priorCards > 0 && st.sinceLastReportMs !== void 0 ? `
|
|
284293
284709
|
|
|
284294
|
-
\uFF08\u8FD9\u662F\u540C\u4E00\u4E2A\u95EE\u9898\u7684\u7B2C ${st.priorCards + 1} \u6B21\u63D0\u9192\uFF0C\u4E0A\u4E00\u6B21\u662F ${fmtSince(new Date(now - st.sinceLastReportMs).toISOString(), now)}\u3002\u8BF7\u5904\u7406\u540E\u518D\u5173\u95ED\
|
|
284710
|
+
\uFF08\u8FD9\u662F\u540C\u4E00\u4E2A\u95EE\u9898\u7684\u7B2C ${st.priorCards + 1} \u6B21\u63D0\u9192\uFF0C\u4E0A\u4E00\u6B21\u662F ${fmtSince(new Date(now - st.sinceLastReportMs).toISOString(), now)}\u3002\u8BF7\u5904\u7406\u540E\u518D\u5173\u95ED\u8FD9\u6761\u5F85\u529E\uFF1B\u5982\u679C\u8FD9\u4E00\u6B65\u4E4B\u540E\u4ECD\u7136\u505C\u7740\uFF0C\u7CFB\u7EDF\u4F1A\u6309 1 \u5C0F\u65F6 \u2192 4 \u5C0F\u65F6 \u2192 12 \u5C0F\u65F6\u7684\u95F4\u9694\u91CD\u65B0\u63D0\u9192\u3002\uFF09` : "";
|
|
284295
284711
|
return {
|
|
284296
284712
|
// ★ 通知型(提案 3c):只在等待面陈列,不挡派发/收口/自动验收——以前它与人提的上报共用
|
|
284297
284713
|
// 三轴 veto,于是**告警在制造它要报告的那个现象**。
|
|
@@ -284718,6 +285134,10 @@ function makeResumeRetryProxy(first, spawnFallback, runtimeRetry) {
|
|
|
284718
285134
|
failed = true;
|
|
284719
285135
|
}
|
|
284720
285136
|
if (sawOutput) {
|
|
285137
|
+
const exit4 = runtimeRetry ? await exitOf(failure2) : {};
|
|
285138
|
+
if (runtimeRetry && exit4.reason === "server-unreachable" && runtimeRetry.shouldRetry(exit4)) {
|
|
285139
|
+
return retryOnce(() => runtimeRetry.spawn(exit4));
|
|
285140
|
+
}
|
|
284721
285141
|
if (failed) throw failure2;
|
|
284722
285142
|
return;
|
|
284723
285143
|
}
|
|
@@ -287639,6 +288059,9 @@ async function startServe(opts) {
|
|
|
287639
288059
|
nodeTokens,
|
|
287640
288060
|
enrollTokens,
|
|
287641
288061
|
nodeStore,
|
|
288062
|
+
// ADR 0629 修订(2026-09-29,方申):一个运行时都没绑的节点不该存在。前端关掉接入第 3 步时当场删;
|
|
288063
|
+
// 人直接关浏览器、离开 onboarding 时由这里兜底——连续空着 30 分钟(= 入网令牌有效期)就删。
|
|
288064
|
+
emptyNodeSweep: { graceMs: EMPTY_NODE_GRACE_MS, intervalMs: EMPTY_NODE_SWEEP_INTERVAL_MS },
|
|
287642
288065
|
registry: registryStore,
|
|
287643
288066
|
gatewayUrl: opts.gatewayUrl ?? `ws://127.0.0.1:${opts.port ?? 7320}/node-gateway`,
|
|
287644
288067
|
repoRemote: opts.nodeRepoRemote ?? "git@github.com:open-friday/oasis-core.git",
|
|
@@ -288453,7 +288876,7 @@ async function startServe(opts) {
|
|
|
288453
288876
|
escalateDiscussRetain: new FileSideMap(path31.join(opts.dir, "escalate-discuss-retain.json")),
|
|
288454
288877
|
// 切片 2b:代署 escalate 发起会话保留(落盘)
|
|
288455
288878
|
dispatchChat: automationDispatchChat = async (chatReq) => {
|
|
288456
|
-
const dispatchChatImpl = async ({ actorId, message, dispatchId: requestDispatchId, admitDispatch, executionProfile, knowledgeAttemptKind, requiredConnectorSlugs, env: requestEnv, sessionId, chatSessionId, chatTurnId, attachments, workspace, companyId, model: sessionModelOverride, parentConversationSnapshot, extraSystemPrompt, delegatedChildTurn, workspaceBundle }) => {
|
|
288879
|
+
const dispatchChatImpl = async ({ actorId, message, dispatchId: requestDispatchId, admitDispatch, executionProfile, knowledgeAttemptKind, requiredConnectorSlugs, env: requestEnv, sessionId, chatSessionId, chatTurnId, attachments, workspace, companyId, model: sessionModelOverride, parentConversationSnapshot, extraSystemPrompt, delegatedChildTurn, workspaceBundle, retargetClaimedDispatch }) => {
|
|
288457
288880
|
const isolatedKnowledgeTurn = executionProfile === "knowledge-single-turn";
|
|
288458
288881
|
const discussionBackground = executionProfile === "discussion-background";
|
|
288459
288882
|
const isolatedBackground = isolatedKnowledgeTurn || discussionBackground;
|
|
@@ -288479,7 +288902,8 @@ async function startServe(opts) {
|
|
|
288479
288902
|
const traceRunId = requestDispatchId ? stableChatTraceRunId(requestDispatchId) : `chat-run:${(0, import_node_crypto91.randomUUID)()}`;
|
|
288480
288903
|
const artifactId = requestDispatchId ? `artifact:chat:${deterministicUuid(`chat-artifact:${requestDispatchId}`)}` : `artifact:chat:${(0, import_node_crypto91.randomUUID)()}`;
|
|
288481
288904
|
let stableDispatch = requestDispatchId ? await resolveStableChatDispatch({ store: await traceStoreFor(runCompanyId), runId: traceRunId }) : null;
|
|
288482
|
-
|
|
288905
|
+
const retargetClaim = Boolean(retargetClaimedDispatch && stableDispatch && allocatedTurn);
|
|
288906
|
+
if (stableDispatch && !stableDispatch.shouldDispatch && !retargetClaim) {
|
|
288483
288907
|
if (isHumanSubmitDispatchId(requestDispatchId)) {
|
|
288484
288908
|
throw markChatDispatchStarted(new ApiError(409, CHAT_SUBMISSION_EXISTS, "\u8FD9\u6B21\u63D0\u4EA4\u4E4B\u524D\u5DF2\u7ECF\u6D3E\u53D1\u8FC7\uFF0C\u7ED3\u679C\u4EE5\u8BB0\u5F55\u4E3A\u51C6"));
|
|
288485
288909
|
}
|
|
@@ -288497,7 +288921,7 @@ async function startServe(opts) {
|
|
|
288497
288921
|
let binding;
|
|
288498
288922
|
let runtimeTargetSource = "actor_binding";
|
|
288499
288923
|
let allocatedModelOverride;
|
|
288500
|
-
if (stableDispatch) {
|
|
288924
|
+
if (stableDispatch && !retargetClaim) {
|
|
288501
288925
|
binding = { actorId, ...stableDispatch.target, status: "active" };
|
|
288502
288926
|
} else {
|
|
288503
288927
|
const currentBinding = await resolveCompanyBinding(runCompanyId, actorId);
|
|
@@ -288677,6 +289101,29 @@ async function startServe(opts) {
|
|
|
288677
289101
|
}
|
|
288678
289102
|
}
|
|
288679
289103
|
const stableTraceWasPresent = Boolean(stableDispatch);
|
|
289104
|
+
if (retargetClaim && stableDispatch && (stableDispatch.target.nodeId !== binding.nodeId || stableDispatch.target.runtimeKind !== binding.runtimeKind)) {
|
|
289105
|
+
const store = await traceStoreFor(runCompanyId);
|
|
289106
|
+
const prior = stableDispatch.run;
|
|
289107
|
+
const run = await store.updateRun(traceRunId, {
|
|
289108
|
+
runtimeKind: traceRuntimeKind(binding.runtimeKind),
|
|
289109
|
+
runtimeInstanceId: `runtime:${binding.nodeId}:${binding.runtimeKind}`,
|
|
289110
|
+
status: "running",
|
|
289111
|
+
endedAt: null,
|
|
289112
|
+
/* 上一次在旧机器上的退出原因与报错原文一并清掉:这一行接下来记的是新目标上这一次的结果。
|
|
289113
|
+
不清的话,新机器上跑成了,记录却是「成功 + 一句旧机器的报错」(v2 run chat-run:538d40f8)。
|
|
289114
|
+
旧机器那次失败的原文仍留在事件流里,也记进了故障标记与失败链。 */
|
|
289115
|
+
exitReason: null,
|
|
289116
|
+
errorMessage: null,
|
|
289117
|
+
metadata: {
|
|
289118
|
+
...prior.metadata ?? {},
|
|
289119
|
+
nodeId: binding.nodeId,
|
|
289120
|
+
runtimeKind: binding.runtimeKind,
|
|
289121
|
+
runtimeTargetSource: "session_override"
|
|
289122
|
+
}
|
|
289123
|
+
});
|
|
289124
|
+
stableDispatch = { run, target: { nodeId: binding.nodeId, runtimeKind: binding.runtimeKind }, shouldDispatch: true };
|
|
289125
|
+
console.log(`[runtime-alloc] ${allocationUnitOfWork} \u6362\u5019\u9009\u91CD\u8BD5\uFF1A\u8BA4\u9886\u4ECE ${prior.runtimeInstanceId ?? "?"} \u6539\u5230 runtime:${binding.nodeId}:${binding.runtimeKind}`);
|
|
289126
|
+
}
|
|
288680
289127
|
if (requestDispatchId && !stableDispatch) {
|
|
288681
289128
|
stableDispatch = await resolveStableChatDispatch({
|
|
288682
289129
|
store: await traceStoreFor(runCompanyId),
|
|
@@ -289156,8 +289603,17 @@ async function startServe(opts) {
|
|
|
289156
289603
|
...exit3.detail ? { errorMessage: exit3.detail } : {}
|
|
289157
289604
|
});
|
|
289158
289605
|
}
|
|
289159
|
-
console.log(`[runtime-alloc] ${unitOfWork} \u56E0 ${exit3.reason ?? "runtime \u6545\u969C"} \u5931\u8D25
|
|
289160
|
-
|
|
289606
|
+
console.log(`[runtime-alloc] ${unitOfWork} \u56E0 ${exit3.reason ?? "runtime \u6545\u969C"} \u5931\u8D25 \u2192 \u6362\u5019\u9009\u91CD\u8D77\u8FD9\u4E00\u8F6E`);
|
|
289607
|
+
const { admitDispatch: _alreadyAdmitted, ...retryReq } = chatReq;
|
|
289608
|
+
if (!chatReq.sessionId) return dispatchChatImpl({ ...retryReq, retargetClaimedDispatch: true });
|
|
289609
|
+
const message = chatReq.fallbackMessage ?? await buildResumeFallbackMessage(chatReq) ?? chatReq.message;
|
|
289610
|
+
return dispatchChatImpl({
|
|
289611
|
+
...retryReq,
|
|
289612
|
+
sessionId: void 0,
|
|
289613
|
+
fallbackMessage: void 0,
|
|
289614
|
+
message,
|
|
289615
|
+
retargetClaimedDispatch: true
|
|
289616
|
+
});
|
|
289161
289617
|
}
|
|
289162
289618
|
};
|
|
289163
289619
|
})() : void 0;
|
|
@@ -290339,9 +290795,10 @@ async function startServe(opts) {
|
|
|
290339
290795
|
checkDispatchable: async ({ actor, binding }) => {
|
|
290340
290796
|
try {
|
|
290341
290797
|
if (!binding.nodeId) return null;
|
|
290342
|
-
const
|
|
290798
|
+
const boundNode = await nodeStore.getNode(binding.nodeId).catch(() => null);
|
|
290799
|
+
const foreign = foreignNodeBlock(boundNode, companyId);
|
|
290343
290800
|
if (foreign) return { reason: "node-not-in-company", errorMessage: foreign };
|
|
290344
|
-
const drift = runtimeDriftBlock(await nodeStore.listRuntimes(binding.nodeId), binding.nodeId, binding.runtimeKind);
|
|
290801
|
+
const drift = runtimeDriftBlock(await nodeStore.listRuntimes(binding.nodeId), binding.nodeId, binding.runtimeKind, boundNode?.name);
|
|
290345
290802
|
if (drift) return drift;
|
|
290346
290803
|
const health = healthOfNode(binding.nodeId);
|
|
290347
290804
|
if (health.healthy) return null;
|
|
@@ -297131,7 +297588,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
297131
297588
|
}
|
|
297132
297589
|
}
|
|
297133
297590
|
}
|
|
297134
|
-
var CLI_VERSION = "2.2.
|
|
297591
|
+
var CLI_VERSION = "2.2.94" ? "2.2.94" : "dev";
|
|
297135
297592
|
function apiHeaders(token, company) {
|
|
297136
297593
|
const headers = {
|
|
297137
297594
|
authorization: `Bearer ${token}`,
|
|
@@ -301102,7 +301559,7 @@ function shimScript() {
|
|
|
301102
301559
|
}
|
|
301103
301560
|
|
|
301104
301561
|
// src/index.ts
|
|
301105
|
-
var PKG_VERSION = true ? "2.2.
|
|
301562
|
+
var PKG_VERSION = true ? "2.2.94" : "dev";
|
|
301106
301563
|
var LOCAL_BIN = localBin();
|
|
301107
301564
|
var NPM_PREFIX = npmPrefix();
|
|
301108
301565
|
var INSTANCE = DEFAULT_INSTANCE;
|