oasis_test_v2 2.2.125 → 2.2.127
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 +792 -668
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1778,6 +1778,14 @@ var init_overlap = __esm({
|
|
|
1778
1778
|
"\u4E4B\u540E",
|
|
1779
1779
|
"\u4EE5\u524D",
|
|
1780
1780
|
"\u622A\u6B62",
|
|
1781
|
+
// 任务书里的套话(v2 实测:两份毫不相干的委派因为都写了「交付一个 Markdown 文件 outputs/…」被比成相近)。
|
|
1782
|
+
"\u4EA4\u4ED8",
|
|
1783
|
+
"\u6587\u4EF6",
|
|
1784
|
+
"\u80CC\u666F",
|
|
1785
|
+
"\u7528\u6237",
|
|
1786
|
+
"\u660E\u786E",
|
|
1787
|
+
"\u64B0\u5199",
|
|
1788
|
+
"\u72EC\u7ACB",
|
|
1781
1789
|
"the",
|
|
1782
1790
|
"and",
|
|
1783
1791
|
"for",
|
|
@@ -1787,7 +1795,10 @@ var init_overlap = __esm({
|
|
|
1787
1795
|
"that",
|
|
1788
1796
|
"into",
|
|
1789
1797
|
"todo",
|
|
1790
|
-
"task"
|
|
1798
|
+
"task",
|
|
1799
|
+
"markdown",
|
|
1800
|
+
"outputs",
|
|
1801
|
+
"md"
|
|
1791
1802
|
]);
|
|
1792
1803
|
isCjk = (ch) => /[㐀-鿿豈-]/u.test(ch);
|
|
1793
1804
|
COVER_MIN_SHARED = 3;
|
|
@@ -237390,6 +237401,16 @@ async function listSkillMetadataForActor(args) {
|
|
|
237390
237401
|
}
|
|
237391
237402
|
return out;
|
|
237392
237403
|
}
|
|
237404
|
+
async function skillManifestForActor(args) {
|
|
237405
|
+
const enabledConnectors = args.connectorSkills.length > 0 ? await args.service.effectiveEnabledConnectors(args.actorId) : /* @__PURE__ */ new Set();
|
|
237406
|
+
return listSkillMetadataForActor({
|
|
237407
|
+
service: args.service,
|
|
237408
|
+
actorId: args.actorId,
|
|
237409
|
+
builtins: args.builtins,
|
|
237410
|
+
connectorSkills: args.connectorSkills,
|
|
237411
|
+
enabledConnectors
|
|
237412
|
+
});
|
|
237413
|
+
}
|
|
237393
237414
|
function builtinSkillToFiles(b6) {
|
|
237394
237415
|
return Object.entries(b6.files ?? {}).map(([path50, content3]) => ({
|
|
237395
237416
|
skillId: `builtin:${b6.id}`,
|
|
@@ -238897,14 +238918,11 @@ function actorsDomain(opts) {
|
|
|
238897
238918
|
const { service } = await resolveCtx(req.auth.companyId);
|
|
238898
238919
|
const claim = req.auth.dispatch?.chatSessionId ? { chatSessionId: req.auth.dispatch.chatSessionId, companyId: req.auth.companyId } : void 0;
|
|
238899
238920
|
const builtins = await opts.getBuiltinSkills?.(claim) ?? [];
|
|
238900
|
-
const
|
|
238901
|
-
const enabledConnectors = connectorSkills.length > 0 ? await service.effectiveEnabledConnectors(req.auth.actor) : /* @__PURE__ */ new Set();
|
|
238902
|
-
const items = await listSkillMetadataForActor({
|
|
238921
|
+
const items = await skillManifestForActor({
|
|
238903
238922
|
service,
|
|
238904
238923
|
actorId: req.auth.actor,
|
|
238905
238924
|
builtins,
|
|
238906
|
-
connectorSkills
|
|
238907
|
-
enabledConnectors
|
|
238925
|
+
connectorSkills: opts.getConnectorSkills?.() ?? []
|
|
238908
238926
|
});
|
|
238909
238927
|
return { status: 200, body: { items } };
|
|
238910
238928
|
});
|
|
@@ -255147,6 +255165,562 @@ var init_renderer = __esm({
|
|
|
255147
255165
|
}
|
|
255148
255166
|
});
|
|
255149
255167
|
|
|
255168
|
+
// ../server/src/domains/trace/unit-data.ts
|
|
255169
|
+
function keysetBefore(timeExpr, idExpr, before, push2) {
|
|
255170
|
+
return `(date_trunc('milliseconds', ${timeExpr}), ${idExpr}) < (${push2(before.at)}::timestamptz, ${push2(before.id)})`;
|
|
255171
|
+
}
|
|
255172
|
+
function quoteSchema(name) {
|
|
255173
|
+
if (!/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/.test(name)) throw new Error(`invalid schema name: ${name}`);
|
|
255174
|
+
return `"${name}"`;
|
|
255175
|
+
}
|
|
255176
|
+
function dispatchSchemaIdent(name) {
|
|
255177
|
+
const s3 = name.replace(/[^a-zA-Z0-9_]/g, "");
|
|
255178
|
+
if (!s3) throw new Error(`invalid dispatch schema name: ${name}`);
|
|
255179
|
+
return `"${s3}"`;
|
|
255180
|
+
}
|
|
255181
|
+
function replyIssueIdFromWorkId(workId) {
|
|
255182
|
+
const m4 = /^wk:reply:(.+):\d+$/.exec(workId);
|
|
255183
|
+
return m4 ? m4[1] : null;
|
|
255184
|
+
}
|
|
255185
|
+
function toWork(r5) {
|
|
255186
|
+
return {
|
|
255187
|
+
id: String(r5["id"]),
|
|
255188
|
+
workorderId: String(r5["workorder_id"]),
|
|
255189
|
+
nodeId: String(r5["node_id"]),
|
|
255190
|
+
nodeType: str5(r5["node_type"]),
|
|
255191
|
+
nodeTitle: str5(r5["node_title"]),
|
|
255192
|
+
assigneeActorId: String(r5["assignee_actor_id"]),
|
|
255193
|
+
createdAt: isoReq(r5["created_at"]),
|
|
255194
|
+
startedAt: iso4(r5["started_at"]),
|
|
255195
|
+
endedAt: iso4(r5["ended_at"]),
|
|
255196
|
+
deadAt: iso4(r5["dead_at"]),
|
|
255197
|
+
status: str5(r5["status"]),
|
|
255198
|
+
outcome: str5(r5["outcome"]),
|
|
255199
|
+
// 存量 lane 为空时按 work id 前缀兜底(回信轮 id 恒为 `wk:reply:<issueId>:<n>`)。
|
|
255200
|
+
lane: r5["lane"] === "reply" || r5["lane"] == null && String(r5["id"]).startsWith("wk:reply:") ? "reply" : "main",
|
|
255201
|
+
replyIssueId: replyIssueIdFromWorkId(String(r5["id"])),
|
|
255202
|
+
continuesWorkId: str5(r5["continues_work_id"]),
|
|
255203
|
+
acceptanceState: str5(r5["acceptance_state"]) ?? null,
|
|
255204
|
+
acceptedAt: iso4(r5["accepted_at"]),
|
|
255205
|
+
rejectedReason: str5(r5["rejected_reason"]),
|
|
255206
|
+
overrideBy: str5(r5["override_by"]),
|
|
255207
|
+
overrideReason: str5(r5["override_reason"]),
|
|
255208
|
+
frozenIssueIds: strArr(r5["frozen_issue_ids"]),
|
|
255209
|
+
protocolRecovery: r5["protocol_recovery"] ?? null,
|
|
255210
|
+
killSource: str5(r5["kill_source"]),
|
|
255211
|
+
outputVersionNo: num3(r5["output_version_no"])
|
|
255212
|
+
};
|
|
255213
|
+
}
|
|
255214
|
+
function toReview(r5) {
|
|
255215
|
+
const verdict = str5(r5["verdict"]);
|
|
255216
|
+
let status = str5(r5["status"]);
|
|
255217
|
+
if (!status) {
|
|
255218
|
+
if (r5["retry_at"] != null) status = "retry";
|
|
255219
|
+
else if (r5["cancelled_at"] != null) status = "dead";
|
|
255220
|
+
else if (verdict === "approve" && r5["decided_at"] != null) status = "accept";
|
|
255221
|
+
else if (verdict === "request_changes" && r5["decided_at"] != null) status = "reject";
|
|
255222
|
+
else if (r5["ended_at"] != null) status = verdict ? verdict === "approve" ? "accept" : "reject" : "failed";
|
|
255223
|
+
else status = "running";
|
|
255224
|
+
}
|
|
255225
|
+
return {
|
|
255226
|
+
id: String(r5["id"]),
|
|
255227
|
+
workorderId: String(r5["workorder_id"]),
|
|
255228
|
+
nodeId: String(r5["node_id"]),
|
|
255229
|
+
nodeTitle: str5(r5["node_title"]),
|
|
255230
|
+
targetWorkId: String(r5["target_work_id"]),
|
|
255231
|
+
reviewerActorId: String(r5["reviewer_actor_id"]),
|
|
255232
|
+
reviewGroup: String(r5["review_group"] ?? ""),
|
|
255233
|
+
status,
|
|
255234
|
+
verdict: verdict ?? null,
|
|
255235
|
+
note: str5(r5["note"]),
|
|
255236
|
+
createdAt: isoReq(r5["created_at"]),
|
|
255237
|
+
startedAt: iso4(r5["started_at"]),
|
|
255238
|
+
endedAt: iso4(r5["ended_at"]),
|
|
255239
|
+
decidedAt: iso4(r5["decided_at"]),
|
|
255240
|
+
cancelledAt: iso4(r5["cancelled_at"]),
|
|
255241
|
+
killSource: str5(r5["kill_source"])
|
|
255242
|
+
};
|
|
255243
|
+
}
|
|
255244
|
+
function toIssue(r5) {
|
|
255245
|
+
return {
|
|
255246
|
+
id: String(r5["id"]),
|
|
255247
|
+
workorderId: String(r5["workorder_id"]),
|
|
255248
|
+
kind: String(r5["kind"]),
|
|
255249
|
+
body: String(r5["body"] ?? ""),
|
|
255250
|
+
aboutNodeId: str5(r5["about_node_id"]),
|
|
255251
|
+
aboutWorkId: str5(r5["about_work_id"]),
|
|
255252
|
+
raisedByNodeId: str5(r5["raised_by_node_id"]),
|
|
255253
|
+
authorActorId: String(r5["author_actor_id"]),
|
|
255254
|
+
resolvedAt: iso4(r5["resolved_at"]),
|
|
255255
|
+
createdAt: isoReq(r5["created_at"])
|
|
255256
|
+
};
|
|
255257
|
+
}
|
|
255258
|
+
function toDispatch(r5) {
|
|
255259
|
+
return {
|
|
255260
|
+
id: String(r5["id"]),
|
|
255261
|
+
targetKind: String(r5["target_kind"]),
|
|
255262
|
+
targetId: String(r5["target_id"]),
|
|
255263
|
+
actorId: str5(r5["actor_id"]),
|
|
255264
|
+
createdAt: isoReq(r5["created_at"]),
|
|
255265
|
+
startedAt: iso4(r5["started_at"]),
|
|
255266
|
+
endedAt: iso4(r5["ended_at"]),
|
|
255267
|
+
outcome: str5(r5["outcome"]),
|
|
255268
|
+
reason: str5(r5["reason"]),
|
|
255269
|
+
protocolRecoveryRound: num3(r5["protocol_recovery_round"])
|
|
255270
|
+
};
|
|
255271
|
+
}
|
|
255272
|
+
function toDelegation(r5) {
|
|
255273
|
+
return {
|
|
255274
|
+
id: String(r5["id"]),
|
|
255275
|
+
parentSessionId: String(r5["parent_session_id"]),
|
|
255276
|
+
parentMessageId: String(r5["parent_message_id"] ?? ""),
|
|
255277
|
+
childSessionId: String(r5["child_session_id"]),
|
|
255278
|
+
expertActorId: String(r5["expert_actor_id"]),
|
|
255279
|
+
state: String(r5["state"]),
|
|
255280
|
+
failureKind: str5(r5["failure_kind"]),
|
|
255281
|
+
failureReason: str5(r5["failure_reason"]),
|
|
255282
|
+
consecutiveFails: num3(r5["consecutive_fails"]) ?? 0,
|
|
255283
|
+
dispatchSeq: num3(r5["dispatch_seq"]),
|
|
255284
|
+
createdAt: isoReq(r5["created_at"]),
|
|
255285
|
+
settledAt: iso4(r5["settled_at"]),
|
|
255286
|
+
label: str5(r5["label"]),
|
|
255287
|
+
taskDigest: str5(r5["task_digest"])
|
|
255288
|
+
};
|
|
255289
|
+
}
|
|
255290
|
+
function toSession(r5) {
|
|
255291
|
+
return {
|
|
255292
|
+
id: String(r5["id"]),
|
|
255293
|
+
humanActorId: String(r5["human_actor_id"]),
|
|
255294
|
+
aiActorId: String(r5["ai_actor_id"]),
|
|
255295
|
+
title: str5(r5["title"]),
|
|
255296
|
+
analyzedRunId: str5(r5["analyzed_run_id"]),
|
|
255297
|
+
runtimeSessionId: str5(r5["runtime_session_id"]),
|
|
255298
|
+
touchedAt: isoReq(r5["touched_at"]),
|
|
255299
|
+
createdAt: isoReq(r5["created_at"])
|
|
255300
|
+
};
|
|
255301
|
+
}
|
|
255302
|
+
function toTurn(r5) {
|
|
255303
|
+
return {
|
|
255304
|
+
id: String(r5["id"]),
|
|
255305
|
+
chatSessionId: String(r5["chat_session_id"]),
|
|
255306
|
+
source: String(r5["source"]),
|
|
255307
|
+
status: String(r5["status"]),
|
|
255308
|
+
reservedAt: isoReq(r5["reserved_at"]),
|
|
255309
|
+
startedAt: iso4(r5["started_at"]),
|
|
255310
|
+
completedAt: iso4(r5["completed_at"]),
|
|
255311
|
+
cancelledBy: str5(r5["cancelled_by"]),
|
|
255312
|
+
dispatchId: str5(r5["dispatch_id"]),
|
|
255313
|
+
assistantRunId: str5(r5["assistant_run_id"])
|
|
255314
|
+
};
|
|
255315
|
+
}
|
|
255316
|
+
function toMessage(r5) {
|
|
255317
|
+
return {
|
|
255318
|
+
id: String(r5["id"]),
|
|
255319
|
+
sessionId: String(r5["session_id"]),
|
|
255320
|
+
role: String(r5["role"]),
|
|
255321
|
+
content: String(r5["content"] ?? ""),
|
|
255322
|
+
seq: Number(r5["seq"]),
|
|
255323
|
+
createdAt: isoReq(r5["created_at"]),
|
|
255324
|
+
runId: str5(r5["run_id"]),
|
|
255325
|
+
turnId: str5(r5["turn_id"]),
|
|
255326
|
+
source: str5(r5["source"])
|
|
255327
|
+
};
|
|
255328
|
+
}
|
|
255329
|
+
function toLink(r5) {
|
|
255330
|
+
return { sessionId: String(r5["session_id"]), workOrderId: String(r5["work_order_id"]), linkedAt: isoReq(r5["linked_at"]) };
|
|
255331
|
+
}
|
|
255332
|
+
var unitListKey, iso4, isoReq, str5, num3, strArr, WORK_COLS, REVIEW_COLS, MAX_IDS, capIds, PgUnitDataSource;
|
|
255333
|
+
var init_unit_data = __esm({
|
|
255334
|
+
"../server/src/domains/trace/unit-data.ts"() {
|
|
255335
|
+
"use strict";
|
|
255336
|
+
unitListKey = {
|
|
255337
|
+
work: (w2) => ({ at: w2.endedAt ?? w2.deadAt, id: w2.id }),
|
|
255338
|
+
review: (r5) => ({ at: r5.endedAt ?? r5.decidedAt ?? r5.cancelledAt ?? r5.createdAt, id: r5.id }),
|
|
255339
|
+
delegation: (d5) => ({ at: d5.settledAt ?? d5.createdAt, id: d5.id }),
|
|
255340
|
+
session: (s3) => ({ at: s3.touchedAt, id: s3.id })
|
|
255341
|
+
};
|
|
255342
|
+
iso4 = (v2) => v2 == null ? null : v2 instanceof Date ? v2.toISOString() : typeof v2 === "string" ? new Date(v2).toISOString() : null;
|
|
255343
|
+
isoReq = (v2) => iso4(v2) ?? (/* @__PURE__ */ new Date(0)).toISOString();
|
|
255344
|
+
str5 = (v2) => typeof v2 === "string" ? v2 : v2 == null ? null : String(v2);
|
|
255345
|
+
num3 = (v2) => v2 == null ? null : Number.isFinite(Number(v2)) ? Number(v2) : null;
|
|
255346
|
+
strArr = (v2) => Array.isArray(v2) ? v2.filter((x2) => typeof x2 === "string") : [];
|
|
255347
|
+
WORK_COLS = `w.id, w.workorder_id, w.node_id, n.type AS node_type, n.title AS node_title, w.assignee_actor_id,
|
|
255348
|
+
w.created_at, w.started_at, w.ended_at, w.dead_at, w.status, w.outcome, w.lane, w.continues_work_id,
|
|
255349
|
+
w.acceptance_state, w.accepted_at, w.rejected_reason, w.override_by, w.override_reason, w.frozen_issue_ids,
|
|
255350
|
+
w.protocol_recovery, w.kill_source, w.output_version_no`;
|
|
255351
|
+
REVIEW_COLS = `r.id, r.workorder_id, r.node_id, n.title AS node_title, r.target_work_id, r.reviewer_actor_id, r.review_group,
|
|
255352
|
+
r.status, r.verdict, r.note, r.created_at, r.started_at, r.ended_at, r.decided_at, r.cancelled_at, r.retry_at, r.kill_source`;
|
|
255353
|
+
MAX_IDS = 500;
|
|
255354
|
+
capIds = (ids2) => [...new Set(ids2)].slice(0, MAX_IDS);
|
|
255355
|
+
PgUnitDataSource = class {
|
|
255356
|
+
pool;
|
|
255357
|
+
/** 引擎 schema(works / reviews / issues / events / workflow_*)。 */
|
|
255358
|
+
e;
|
|
255359
|
+
/** chat 一族(chat_sessions / chat_messages / chat_session_turns / 委派);缺省与引擎同 schema。 */
|
|
255360
|
+
c;
|
|
255361
|
+
/** 派发台账 schema(按 dispatches store 的口径净化)。 */
|
|
255362
|
+
d;
|
|
255363
|
+
constructor(opts) {
|
|
255364
|
+
this.pool = opts.pool;
|
|
255365
|
+
this.e = quoteSchema(opts.engineSchema);
|
|
255366
|
+
this.c = quoteSchema(opts.chatSchema ?? opts.engineSchema);
|
|
255367
|
+
this.d = dispatchSchemaIdent(opts.dispatchSchema);
|
|
255368
|
+
}
|
|
255369
|
+
async q(text7, values = []) {
|
|
255370
|
+
return (await this.pool.query(text7, values)).rows;
|
|
255371
|
+
}
|
|
255372
|
+
/* ── work / review ── */
|
|
255373
|
+
async getWorks(ids2) {
|
|
255374
|
+
if (ids2.length === 0) return [];
|
|
255375
|
+
const rows = await this.q(
|
|
255376
|
+
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id WHERE w.id = ANY($1)`,
|
|
255377
|
+
[capIds(ids2)]
|
|
255378
|
+
);
|
|
255379
|
+
return rows.map(toWork);
|
|
255380
|
+
}
|
|
255381
|
+
async getReview(id) {
|
|
255382
|
+
const rows = await this.q(
|
|
255383
|
+
`SELECT ${REVIEW_COLS} FROM ${this.e}.reviews r LEFT JOIN ${this.e}.workflow_nodes n ON n.id = r.node_id WHERE r.id = $1`,
|
|
255384
|
+
[id]
|
|
255385
|
+
);
|
|
255386
|
+
return rows[0] ? toReview(rows[0]) : null;
|
|
255387
|
+
}
|
|
255388
|
+
async reviewsOfWorks(workIds) {
|
|
255389
|
+
if (workIds.length === 0) return [];
|
|
255390
|
+
const rows = await this.q(
|
|
255391
|
+
`SELECT ${REVIEW_COLS} FROM ${this.e}.reviews r LEFT JOIN ${this.e}.workflow_nodes n ON n.id = r.node_id
|
|
255392
|
+
WHERE r.target_work_id = ANY($1) ORDER BY r.created_at ASC, r.id ASC LIMIT 500`,
|
|
255393
|
+
[capIds(workIds)]
|
|
255394
|
+
);
|
|
255395
|
+
return rows.map(toReview);
|
|
255396
|
+
}
|
|
255397
|
+
async worksOfNode(nodeId, limit) {
|
|
255398
|
+
const rows = await this.q(
|
|
255399
|
+
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
255400
|
+
WHERE w.node_id = $1 ORDER BY w.created_at DESC, w.id DESC LIMIT $2`,
|
|
255401
|
+
[nodeId, limit]
|
|
255402
|
+
);
|
|
255403
|
+
return rows.map(toWork);
|
|
255404
|
+
}
|
|
255405
|
+
async workInputsOf(workIds) {
|
|
255406
|
+
if (workIds.length === 0) return [];
|
|
255407
|
+
const rows = await this.q(
|
|
255408
|
+
`SELECT work_id, upstream_node_id, upstream_work_id FROM ${this.e}.work_inputs WHERE work_id = ANY($1) LIMIT 2000`,
|
|
255409
|
+
[capIds(workIds)]
|
|
255410
|
+
);
|
|
255411
|
+
return rows.map((r5) => ({
|
|
255412
|
+
workId: String(r5["work_id"]),
|
|
255413
|
+
upstreamNodeId: String(r5["upstream_node_id"]),
|
|
255414
|
+
upstreamWorkId: String(r5["upstream_work_id"])
|
|
255415
|
+
}));
|
|
255416
|
+
}
|
|
255417
|
+
async inputNodesOf(nodeId) {
|
|
255418
|
+
const rows = await this.q(
|
|
255419
|
+
`SELECT from_node_id FROM ${this.e}.workflow_edges WHERE to_node_id = $1 AND kind = 'data' ORDER BY from_node_id LIMIT 100`,
|
|
255420
|
+
[nodeId]
|
|
255421
|
+
);
|
|
255422
|
+
return rows.map((r5) => String(r5["from_node_id"]));
|
|
255423
|
+
}
|
|
255424
|
+
async outputNodesOf(nodeId) {
|
|
255425
|
+
const rows = await this.q(
|
|
255426
|
+
`SELECT to_node_id FROM ${this.e}.workflow_edges WHERE from_node_id = $1 AND kind = 'data' ORDER BY to_node_id LIMIT 100`,
|
|
255427
|
+
[nodeId]
|
|
255428
|
+
);
|
|
255429
|
+
return rows.map((r5) => String(r5["to_node_id"]));
|
|
255430
|
+
}
|
|
255431
|
+
async latestAcceptedWorkOfNodeBefore(nodeId, beforeIso) {
|
|
255432
|
+
const rows = await this.q(
|
|
255433
|
+
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
255434
|
+
WHERE w.node_id = $1 AND w.acceptance_state = 'accepted' AND w.accepted_at IS NOT NULL AND w.accepted_at <= $2
|
|
255435
|
+
ORDER BY w.accepted_at DESC, w.id DESC LIMIT 1`,
|
|
255436
|
+
[nodeId, beforeIso]
|
|
255437
|
+
);
|
|
255438
|
+
return rows[0] ? toWork(rows[0]) : null;
|
|
255439
|
+
}
|
|
255440
|
+
async worksAcceptedInWindow(nodeIds, fromIso, toIso2, limit) {
|
|
255441
|
+
if (nodeIds.length === 0) return [];
|
|
255442
|
+
const rows = await this.q(
|
|
255443
|
+
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
255444
|
+
WHERE w.node_id = ANY($1) AND w.acceptance_state = 'accepted' AND w.accepted_at >= $2 AND w.accepted_at <= $3
|
|
255445
|
+
ORDER BY w.accepted_at ASC, w.id ASC LIMIT $4`,
|
|
255446
|
+
[capIds(nodeIds), fromIso, toIso2, limit]
|
|
255447
|
+
);
|
|
255448
|
+
return rows.map(toWork);
|
|
255449
|
+
}
|
|
255450
|
+
async reworkSourcesOf(work) {
|
|
255451
|
+
const rows = await this.q(
|
|
255452
|
+
`SELECT DISTINCT x.reason->>'workId' AS src
|
|
255453
|
+
FROM (SELECT payload FROM ${this.e}.events
|
|
255454
|
+
WHERE node_id = $1 AND kind = 'work.create' AND payload->>'workId' = $2
|
|
255455
|
+
ORDER BY seq DESC LIMIT 20) ev,
|
|
255456
|
+
LATERAL jsonb_array_elements(COALESCE(ev.payload->'reasons', '[]'::jsonb)) AS x(reason)
|
|
255457
|
+
WHERE x.reason->>'kind' = 'rework' AND x.reason->>'workId' IS NOT NULL`,
|
|
255458
|
+
[work.nodeId, work.id]
|
|
255459
|
+
);
|
|
255460
|
+
return rows.map((r5) => String(r5["src"]));
|
|
255461
|
+
}
|
|
255462
|
+
async reworkedBy(work) {
|
|
255463
|
+
const viaCol = await this.q(
|
|
255464
|
+
`SELECT id FROM ${this.e}.works WHERE node_id = $1 AND continues_work_id = $2 AND id <> $2 ORDER BY created_at ASC LIMIT 50`,
|
|
255465
|
+
[work.nodeId, work.id]
|
|
255466
|
+
);
|
|
255467
|
+
const viaEvents = await this.q(
|
|
255468
|
+
`SELECT DISTINCT ev.payload->>'workId' AS wid
|
|
255469
|
+
FROM (SELECT payload FROM ${this.e}.events WHERE node_id = $1 AND kind = 'work.create' ORDER BY seq DESC LIMIT 200) ev,
|
|
255470
|
+
LATERAL jsonb_array_elements(COALESCE(ev.payload->'reasons', '[]'::jsonb)) AS x(reason)
|
|
255471
|
+
WHERE x.reason->>'kind' = 'rework' AND x.reason->>'workId' = $2`,
|
|
255472
|
+
[work.nodeId, work.id]
|
|
255473
|
+
);
|
|
255474
|
+
const out = /* @__PURE__ */ new Set();
|
|
255475
|
+
for (const r5 of viaCol) out.add(String(r5["id"]));
|
|
255476
|
+
for (const r5 of viaEvents) if (r5["wid"] != null && r5["wid"] !== work.id) out.add(String(r5["wid"]));
|
|
255477
|
+
return [...out];
|
|
255478
|
+
}
|
|
255479
|
+
async briefNodesOf(workorderId) {
|
|
255480
|
+
const rows = await this.q(
|
|
255481
|
+
`SELECT id FROM ${this.e}.workflow_nodes WHERE workorder_id = $1 AND type = 'brief' ORDER BY created_at ASC LIMIT 10`,
|
|
255482
|
+
[workorderId]
|
|
255483
|
+
);
|
|
255484
|
+
return rows.map((r5) => String(r5["id"]));
|
|
255485
|
+
}
|
|
255486
|
+
/* ── issue ── */
|
|
255487
|
+
async issuesByIds(ids2) {
|
|
255488
|
+
if (ids2.length === 0) return [];
|
|
255489
|
+
const rows = await this.q(`SELECT * FROM ${this.e}.issues WHERE id = ANY($1)`, [capIds(ids2)]);
|
|
255490
|
+
return rows.map(toIssue);
|
|
255491
|
+
}
|
|
255492
|
+
async issuesInWorkorder(workorderId, q4) {
|
|
255493
|
+
const args = [workorderId];
|
|
255494
|
+
const conds = ["workorder_id = $1"];
|
|
255495
|
+
const ors = [];
|
|
255496
|
+
const push2 = (v2) => {
|
|
255497
|
+
args.push(v2);
|
|
255498
|
+
return `$${args.length}`;
|
|
255499
|
+
};
|
|
255500
|
+
if (q4.aboutWorkIds?.length) ors.push(`about_work_id = ANY(${push2(capIds(q4.aboutWorkIds))})`);
|
|
255501
|
+
if (q4.aboutNodeIds?.length) ors.push(`about_node_id = ANY(${push2(capIds(q4.aboutNodeIds))})`);
|
|
255502
|
+
if (q4.raisedByNodeIds?.length) ors.push(`raised_by_node_id = ANY(${push2(capIds(q4.raisedByNodeIds))})`);
|
|
255503
|
+
if (ors.length) conds.push(`(${ors.join(" OR ")})`);
|
|
255504
|
+
if (q4.fromIso) conds.push(`created_at >= ${push2(q4.fromIso)}`);
|
|
255505
|
+
if (q4.toIso) conds.push(`created_at <= ${push2(q4.toIso)}`);
|
|
255506
|
+
const rows = await this.q(
|
|
255507
|
+
`SELECT * FROM ${this.e}.issues WHERE ${conds.join(" AND ")} ORDER BY created_at ASC, id ASC LIMIT ${push2(q4.limit)}`,
|
|
255508
|
+
args
|
|
255509
|
+
);
|
|
255510
|
+
return rows.map(toIssue);
|
|
255511
|
+
}
|
|
255512
|
+
async worksHandlingIssues(workorderId, issueIds, limit) {
|
|
255513
|
+
if (issueIds.length === 0) return [];
|
|
255514
|
+
const ids2 = capIds(issueIds);
|
|
255515
|
+
const rows = await this.q(
|
|
255516
|
+
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
255517
|
+
WHERE w.workorder_id = $1
|
|
255518
|
+
AND (w.id LIKE ANY($4::text[]) OR (jsonb_typeof(w.frozen_issue_ids) = 'array' AND w.frozen_issue_ids ?| $2))
|
|
255519
|
+
ORDER BY w.created_at ASC, w.id ASC LIMIT $3`,
|
|
255520
|
+
[workorderId, ids2, limit, ids2.map((i5) => `wk:reply:${i5.replace(/[\\%_]/g, (c5) => `\\${c5}`)}:%`)]
|
|
255521
|
+
);
|
|
255522
|
+
return rows.map(toWork);
|
|
255523
|
+
}
|
|
255524
|
+
/* ── dispatches ── */
|
|
255525
|
+
async dispatchesOf(kind, targetIds) {
|
|
255526
|
+
if (targetIds.length === 0) return [];
|
|
255527
|
+
const rows = await this.q(
|
|
255528
|
+
`SELECT id, target_kind, target_id, actor_id, created_at, started_at, ended_at, outcome, reason, protocol_recovery_round
|
|
255529
|
+
FROM ${this.d}.dispatches WHERE target_kind = $1 AND target_id = ANY($2) ORDER BY created_at ASC, id ASC LIMIT 1000`,
|
|
255530
|
+
[kind, capIds(targetIds)]
|
|
255531
|
+
);
|
|
255532
|
+
return rows.map(toDispatch);
|
|
255533
|
+
}
|
|
255534
|
+
async dispatchTargetOf(runId) {
|
|
255535
|
+
const rows = await this.q(`SELECT target_kind, target_id FROM ${this.d}.dispatches WHERE id = $1`, [runId]);
|
|
255536
|
+
const r5 = rows[0];
|
|
255537
|
+
return r5 ? { targetKind: String(r5["target_kind"]), targetId: String(r5["target_id"]) } : null;
|
|
255538
|
+
}
|
|
255539
|
+
/* ── 委派 ── */
|
|
255540
|
+
async getDelegation(id) {
|
|
255541
|
+
const rows = await this.q(`SELECT * FROM ${this.c}.chat_session_delegations WHERE id = $1`, [id]);
|
|
255542
|
+
return rows[0] ? toDelegation(rows[0]) : null;
|
|
255543
|
+
}
|
|
255544
|
+
async delegationByChildSession(childSessionId) {
|
|
255545
|
+
const rows = await this.q(`SELECT * FROM ${this.c}.chat_session_delegations WHERE child_session_id = $1`, [childSessionId]);
|
|
255546
|
+
return rows[0] ? toDelegation(rows[0]) : null;
|
|
255547
|
+
}
|
|
255548
|
+
async delegationsOfParent(parentSessionId, limit) {
|
|
255549
|
+
const rows = await this.q(
|
|
255550
|
+
`SELECT * FROM ${this.c}.chat_session_delegations WHERE parent_session_id = $1 ORDER BY created_at ASC, id ASC LIMIT $2`,
|
|
255551
|
+
[parentSessionId, limit]
|
|
255552
|
+
);
|
|
255553
|
+
return rows.map(toDelegation);
|
|
255554
|
+
}
|
|
255555
|
+
async touchesOf(delegationId) {
|
|
255556
|
+
const rows = await this.q(
|
|
255557
|
+
`SELECT delegation_id, message_id, kind, at FROM ${this.c}.chat_session_delegation_touches
|
|
255558
|
+
WHERE delegation_id = $1 ORDER BY at ASC LIMIT 500`,
|
|
255559
|
+
[delegationId]
|
|
255560
|
+
);
|
|
255561
|
+
return rows.map((r5) => ({
|
|
255562
|
+
delegationId: String(r5["delegation_id"]),
|
|
255563
|
+
messageId: String(r5["message_id"]),
|
|
255564
|
+
kind: String(r5["kind"]),
|
|
255565
|
+
at: isoReq(r5["at"])
|
|
255566
|
+
}));
|
|
255567
|
+
}
|
|
255568
|
+
/* ── 会话 / 轮次 / 消息 ── */
|
|
255569
|
+
async getSession(id) {
|
|
255570
|
+
const rows = await this.q(`SELECT * FROM ${this.c}.chat_sessions WHERE id = $1`, [id]);
|
|
255571
|
+
return rows[0] ? toSession(rows[0]) : null;
|
|
255572
|
+
}
|
|
255573
|
+
async getTurn(id) {
|
|
255574
|
+
const rows = await this.q(`SELECT * FROM ${this.c}.chat_session_turns WHERE id = $1`, [id]);
|
|
255575
|
+
return rows[0] ? toTurn(rows[0]) : null;
|
|
255576
|
+
}
|
|
255577
|
+
async turnsOfSession(sessionId, limit) {
|
|
255578
|
+
const rows = await this.q(
|
|
255579
|
+
`SELECT * FROM ${this.c}.chat_session_turns WHERE chat_session_id = $1 ORDER BY reserved_at DESC, id DESC LIMIT $2`,
|
|
255580
|
+
[sessionId, limit + 1]
|
|
255581
|
+
);
|
|
255582
|
+
const truncated = rows.length > limit;
|
|
255583
|
+
const turns = (truncated ? rows.slice(0, limit) : rows).map(toTurn).reverse();
|
|
255584
|
+
return { turns, truncated };
|
|
255585
|
+
}
|
|
255586
|
+
async getMessage(id) {
|
|
255587
|
+
const rows = await this.q(`SELECT * FROM ${this.c}.chat_messages WHERE id = $1`, [id]);
|
|
255588
|
+
return rows[0] ? toMessage(rows[0]) : null;
|
|
255589
|
+
}
|
|
255590
|
+
async messagesOf(sessionId, q4) {
|
|
255591
|
+
const args = [sessionId];
|
|
255592
|
+
const push2 = (v2) => {
|
|
255593
|
+
args.push(v2);
|
|
255594
|
+
return `$${args.length}`;
|
|
255595
|
+
};
|
|
255596
|
+
const conds = ["session_id = $1"];
|
|
255597
|
+
if (q4.turnIds) {
|
|
255598
|
+
const window3 = ["turn_id IS NULL"];
|
|
255599
|
+
if (q4.fromIso) window3.push(`created_at >= ${push2(q4.fromIso)}`);
|
|
255600
|
+
if (q4.toIso) window3.push(`created_at <= ${push2(q4.toIso)}`);
|
|
255601
|
+
conds.push(`(turn_id = ANY(${push2(capIds(q4.turnIds))}) OR (${window3.join(" AND ")}))`);
|
|
255602
|
+
} else {
|
|
255603
|
+
if (q4.fromIso) conds.push(`created_at >= ${push2(q4.fromIso)}`);
|
|
255604
|
+
if (q4.toIso) conds.push(`created_at <= ${push2(q4.toIso)}`);
|
|
255605
|
+
}
|
|
255606
|
+
if (q4.roles?.length) conds.push(`role = ANY(${push2(q4.roles)})`);
|
|
255607
|
+
const rows = await this.q(
|
|
255608
|
+
`SELECT id, session_id, role, content, seq, created_at, run_id, turn_id, source FROM ${this.c}.chat_messages
|
|
255609
|
+
WHERE ${conds.join(" AND ")} ORDER BY seq ASC LIMIT ${push2(q4.limit)}`,
|
|
255610
|
+
args
|
|
255611
|
+
);
|
|
255612
|
+
return rows.map(toMessage);
|
|
255613
|
+
}
|
|
255614
|
+
async pendingMessagesOf(sessionId, fromIso, toIso2, limit) {
|
|
255615
|
+
const rows = await this.q(
|
|
255616
|
+
`SELECT id, chat_session_id, text, created_at, state, flavour FROM ${this.c}.chat_pending_messages
|
|
255617
|
+
WHERE chat_session_id = $1 AND created_at >= $2 AND created_at <= $3 ORDER BY seq ASC LIMIT $4`,
|
|
255618
|
+
[sessionId, fromIso, toIso2, limit]
|
|
255619
|
+
);
|
|
255620
|
+
return rows.map((r5) => ({
|
|
255621
|
+
id: String(r5["id"]),
|
|
255622
|
+
chatSessionId: String(r5["chat_session_id"]),
|
|
255623
|
+
text: String(r5["text"] ?? ""),
|
|
255624
|
+
createdAt: isoReq(r5["created_at"]),
|
|
255625
|
+
state: str5(r5["state"]),
|
|
255626
|
+
flavour: str5(r5["flavour"])
|
|
255627
|
+
}));
|
|
255628
|
+
}
|
|
255629
|
+
async originLinksOfWorkorder(workorderId) {
|
|
255630
|
+
const rows = await this.q(
|
|
255631
|
+
`SELECT session_id, work_order_id, linked_at FROM ${this.c}.chat_session_work_orders
|
|
255632
|
+
WHERE work_order_id = $1 AND link_kind = 'origin' ORDER BY linked_at ASC LIMIT 20`,
|
|
255633
|
+
[workorderId]
|
|
255634
|
+
);
|
|
255635
|
+
return rows.map(toLink);
|
|
255636
|
+
}
|
|
255637
|
+
async originLinksOfSession(sessionId) {
|
|
255638
|
+
const rows = await this.q(
|
|
255639
|
+
`SELECT session_id, work_order_id, linked_at FROM ${this.c}.chat_session_work_orders
|
|
255640
|
+
WHERE session_id = $1 AND link_kind = 'origin' ORDER BY linked_at ASC LIMIT 200`,
|
|
255641
|
+
[sessionId]
|
|
255642
|
+
);
|
|
255643
|
+
return rows.map(toLink);
|
|
255644
|
+
}
|
|
255645
|
+
/* ── find / peers 候选 ── */
|
|
255646
|
+
async listEndedWorks(q4) {
|
|
255647
|
+
const args = [];
|
|
255648
|
+
const push2 = (v2) => {
|
|
255649
|
+
args.push(v2);
|
|
255650
|
+
return `$${args.length}`;
|
|
255651
|
+
};
|
|
255652
|
+
const conds = [`(w.ended_at IS NOT NULL OR w.dead_at IS NOT NULL)`, `w.acceptance_state IS DISTINCT FROM 'draft'`];
|
|
255653
|
+
if (q4.sinceIso) conds.push(`COALESCE(w.ended_at, w.dead_at) >= ${push2(q4.sinceIso)}`);
|
|
255654
|
+
if (q4.actorId) conds.push(`w.assignee_actor_id = ${push2(q4.actorId)}`);
|
|
255655
|
+
if (q4.nodeType) conds.push(`n.type = ${push2(q4.nodeType)}`);
|
|
255656
|
+
if (q4.lane) conds.push(`COALESCE(w.lane, CASE WHEN w.id LIKE 'wk:reply:%' THEN 'reply' ELSE 'main' END) = ${push2(q4.lane)}`);
|
|
255657
|
+
const endExpr = `COALESCE(w.ended_at, w.dead_at)`;
|
|
255658
|
+
if (q4.before) conds.push(keysetBefore(endExpr, "w.id", q4.before, push2));
|
|
255659
|
+
const rows = await this.q(
|
|
255660
|
+
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
255661
|
+
WHERE ${conds.join(" AND ")} ORDER BY date_trunc('milliseconds', ${endExpr}) DESC, w.id DESC LIMIT ${push2(q4.limit)}`,
|
|
255662
|
+
args
|
|
255663
|
+
);
|
|
255664
|
+
return rows.map(toWork);
|
|
255665
|
+
}
|
|
255666
|
+
async listEndedReviews(q4) {
|
|
255667
|
+
const args = [];
|
|
255668
|
+
const push2 = (v2) => {
|
|
255669
|
+
args.push(v2);
|
|
255670
|
+
return `$${args.length}`;
|
|
255671
|
+
};
|
|
255672
|
+
const endExpr = `COALESCE(r.ended_at, r.decided_at, r.cancelled_at, r.created_at)`;
|
|
255673
|
+
const conds = [`r.status IN ('accept','reject','failed','dead')`];
|
|
255674
|
+
if (q4.sinceIso) conds.push(`${endExpr} >= ${push2(q4.sinceIso)}`);
|
|
255675
|
+
if (q4.actorId) conds.push(`r.reviewer_actor_id = ${push2(q4.actorId)}`);
|
|
255676
|
+
if (q4.before) conds.push(keysetBefore(endExpr, "r.id", q4.before, push2));
|
|
255677
|
+
const rows = await this.q(
|
|
255678
|
+
`SELECT ${REVIEW_COLS} FROM ${this.e}.reviews r LEFT JOIN ${this.e}.workflow_nodes n ON n.id = r.node_id
|
|
255679
|
+
WHERE ${conds.join(" AND ")} ORDER BY date_trunc('milliseconds', ${endExpr}) DESC, r.id DESC LIMIT ${push2(q4.limit)}`,
|
|
255680
|
+
args
|
|
255681
|
+
);
|
|
255682
|
+
return rows.map(toReview);
|
|
255683
|
+
}
|
|
255684
|
+
async listEndedDelegations(q4) {
|
|
255685
|
+
const args = [];
|
|
255686
|
+
const push2 = (v2) => {
|
|
255687
|
+
args.push(v2);
|
|
255688
|
+
return `$${args.length}`;
|
|
255689
|
+
};
|
|
255690
|
+
const conds = [`state IN ('done','failed')`];
|
|
255691
|
+
if (q4.sinceIso) conds.push(`COALESCE(settled_at, created_at) >= ${push2(q4.sinceIso)}`);
|
|
255692
|
+
if (q4.actorId) conds.push(`expert_actor_id = ${push2(q4.actorId)}`);
|
|
255693
|
+
if (q4.before) conds.push(keysetBefore(`COALESCE(settled_at, created_at)`, "id", q4.before, push2));
|
|
255694
|
+
const rows = await this.q(
|
|
255695
|
+
`SELECT * FROM ${this.c}.chat_session_delegations WHERE ${conds.join(" AND ")}
|
|
255696
|
+
ORDER BY date_trunc('milliseconds', COALESCE(settled_at, created_at)) DESC, id DESC LIMIT ${push2(q4.limit)}`,
|
|
255697
|
+
args
|
|
255698
|
+
);
|
|
255699
|
+
return rows.map(toDelegation);
|
|
255700
|
+
}
|
|
255701
|
+
async listRecentSessions(q4) {
|
|
255702
|
+
const args = [];
|
|
255703
|
+
const push2 = (v2) => {
|
|
255704
|
+
args.push(v2);
|
|
255705
|
+
return `$${args.length}`;
|
|
255706
|
+
};
|
|
255707
|
+
const conds = [`NOT EXISTS (SELECT 1 FROM ${this.c}.chat_session_delegations d WHERE d.child_session_id = s.id)`];
|
|
255708
|
+
if (!q4.includeAnalysis) conds.push(`s.analyzed_run_id IS NULL`);
|
|
255709
|
+
if (q4.sinceIso) conds.push(`s.touched_at >= ${push2(q4.sinceIso)}`);
|
|
255710
|
+
if (q4.aiActorId) conds.push(`s.ai_actor_id = ${push2(q4.aiActorId)}`);
|
|
255711
|
+
if (q4.before) conds.push(keysetBefore("s.touched_at", "s.id", q4.before, push2));
|
|
255712
|
+
const rows = await this.q(
|
|
255713
|
+
`SELECT s.id, s.human_actor_id, s.ai_actor_id, s.title, s.analyzed_run_id, s.runtime_session_id, s.touched_at, s.created_at
|
|
255714
|
+
FROM ${this.c}.chat_sessions s WHERE ${conds.join(" AND ")}
|
|
255715
|
+
ORDER BY date_trunc('milliseconds', s.touched_at) DESC, s.id DESC LIMIT ${push2(q4.limit)}`,
|
|
255716
|
+
args
|
|
255717
|
+
);
|
|
255718
|
+
return rows.map(toSession);
|
|
255719
|
+
}
|
|
255720
|
+
};
|
|
255721
|
+
}
|
|
255722
|
+
});
|
|
255723
|
+
|
|
255150
255724
|
// ../server/src/domains/trace/units.ts
|
|
255151
255725
|
function splitSegments(turns, gapMs = SEGMENT_IDLE_GAP_MS) {
|
|
255152
255726
|
const sorted = [...turns].sort((a5, b6) => {
|
|
@@ -255241,6 +255815,23 @@ function parseSince(since, nowMs) {
|
|
|
255241
255815
|
if (!Number.isFinite(t)) throw new RangeError(`--since \u4E0D\u5408\u6CD5\uFF1A${since}\uFF08\u8981 ISO \u65F6\u95F4\u6216 7d / 12h / 30m\uFF09`);
|
|
255242
255816
|
return new Date(t).toISOString();
|
|
255243
255817
|
}
|
|
255818
|
+
function keysetSource(list3, keyOf4, batch, toCandidates) {
|
|
255819
|
+
let before;
|
|
255820
|
+
const src = {
|
|
255821
|
+
watermark: "",
|
|
255822
|
+
async next() {
|
|
255823
|
+
if (src.watermark === null) return [];
|
|
255824
|
+
const rows = await list3(before);
|
|
255825
|
+
const last = rows[rows.length - 1];
|
|
255826
|
+
if (last) before = keyOf4(last);
|
|
255827
|
+
src.watermark = rows.length < batch || !before ? null : before.at;
|
|
255828
|
+
const out = [];
|
|
255829
|
+
for (const r5 of rows) out.push(...await toCandidates(r5));
|
|
255830
|
+
return out;
|
|
255831
|
+
}
|
|
255832
|
+
};
|
|
255833
|
+
return src;
|
|
255834
|
+
}
|
|
255244
255835
|
function memo(map3, key2, fn) {
|
|
255245
255836
|
let p4 = map3.get(key2);
|
|
255246
255837
|
if (!p4) {
|
|
@@ -255265,11 +255856,13 @@ function metaString(meta, key2) {
|
|
|
255265
255856
|
}
|
|
255266
255857
|
return null;
|
|
255267
255858
|
}
|
|
255268
|
-
var SEG_TURN_CAP, RUN_PAGE, RUN_CAP, NODE_WORK_CAP, MAX_CHAIN_NODES, MESSAGE_CAP, SIGNAL_TEXT_CAP, FIND_DEFAULT_LIMIT, FIND_MAX_LIMIT, RUN_ROW_CAP, TURN_TERMINAL, REVIEW_ENDED, DELEGATION_ENDED, SYSTEM_CANCEL_REASONS, EXOGENOUS_RUN_STATUS, UnitError, ms, turnStart, turnEnd, UnitService, unitTypeOf, segId,
|
|
255859
|
+
var SEG_TURN_CAP, RUN_PAGE, RUN_CAP, NODE_WORK_CAP, MAX_CHAIN_NODES, MESSAGE_CAP, SIGNAL_TEXT_CAP, EXOGENOUS_TEXT_CAP, EXOGENOUS_SUMMARY_CAP, FIND_DEFAULT_LIMIT, FIND_BATCH_MAX, FIND_MAX_LIMIT, RUN_ROW_CAP, TURN_TERMINAL, REVIEW_ENDED, DELEGATION_ENDED, SYSTEM_CANCEL_REASONS, EXOGENOUS_RUN_STATUS, UnitError, ms, turnStart, turnEnd, UnitService, unitTypeOf, segId, clipField, outcomeFetchCmd, exogenousFetchCmd, UnitReader;
|
|
255269
255860
|
var init_units = __esm({
|
|
255270
255861
|
"../server/src/domains/trace/units.ts"() {
|
|
255271
255862
|
"use strict";
|
|
255272
255863
|
init_src();
|
|
255864
|
+
init_unit_data();
|
|
255865
|
+
init_renderer();
|
|
255273
255866
|
SEG_TURN_CAP = 2e3;
|
|
255274
255867
|
RUN_PAGE = 200;
|
|
255275
255868
|
RUN_CAP = 2e3;
|
|
@@ -255277,7 +255870,10 @@ var init_units = __esm({
|
|
|
255277
255870
|
MAX_CHAIN_NODES = 200;
|
|
255278
255871
|
MESSAGE_CAP = 1e3;
|
|
255279
255872
|
SIGNAL_TEXT_CAP = 2e3;
|
|
255873
|
+
EXOGENOUS_TEXT_CAP = 500;
|
|
255874
|
+
EXOGENOUS_SUMMARY_CAP = 120;
|
|
255280
255875
|
FIND_DEFAULT_LIMIT = 20;
|
|
255876
|
+
FIND_BATCH_MAX = 200;
|
|
255281
255877
|
FIND_MAX_LIMIT = 200;
|
|
255282
255878
|
RUN_ROW_CAP = 50;
|
|
255283
255879
|
TURN_TERMINAL = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled", "orphaned"]);
|
|
@@ -255326,11 +255922,12 @@ var init_units = __esm({
|
|
|
255326
255922
|
async evidenceScope(unitId, maxHop) {
|
|
255327
255923
|
return this.reader().evidenceScope(unitId, maxHop);
|
|
255328
255924
|
}
|
|
255329
|
-
|
|
255330
|
-
|
|
255925
|
+
/** `full`:长文本不截(`oasis trace outcome <unit> --full`,即截断标记里给的取回命令)。 */
|
|
255926
|
+
async outcome(unitId, opts = {}) {
|
|
255927
|
+
return this.reader().outcome(unitId, opts);
|
|
255331
255928
|
}
|
|
255332
|
-
async exogenous(unitId) {
|
|
255333
|
-
return this.reader().exogenous(unitId);
|
|
255929
|
+
async exogenous(unitId, opts = {}) {
|
|
255930
|
+
return this.reader().exogenous(unitId, opts);
|
|
255334
255931
|
}
|
|
255335
255932
|
async peers(unitId, limit) {
|
|
255336
255933
|
return this.reader().peers(unitId, limit);
|
|
@@ -255341,7 +255938,9 @@ var init_units = __esm({
|
|
|
255341
255938
|
};
|
|
255342
255939
|
unitTypeOf = (u) => u.kind === "work" || u.kind === "review" ? "work" : u.kind === "delegation" ? "delegation" : "chat";
|
|
255343
255940
|
segId = (sessionId, firstTurnId) => `seg:${sessionId}:${firstTurnId}`;
|
|
255344
|
-
|
|
255941
|
+
clipField = (s3, fetchCmd, full, n3 = SIGNAL_TEXT_CAP) => full ? { text: s3, truncated: false, fullChars: s3.length, fetchCmd } : { ...truncateText(s3, n3, fetchCmd) };
|
|
255942
|
+
outcomeFetchCmd = (unitId) => `oasis trace outcome ${unitId} --full`;
|
|
255943
|
+
exogenousFetchCmd = (unitId) => `oasis trace exogenous ${unitId} --full`;
|
|
255345
255944
|
UnitReader = class {
|
|
255346
255945
|
constructor(deps) {
|
|
255347
255946
|
this.deps = deps;
|
|
@@ -255590,7 +256189,7 @@ var init_units = __esm({
|
|
|
255590
256189
|
const ended = reviewEnded(u.review);
|
|
255591
256190
|
return {
|
|
255592
256191
|
ended,
|
|
255593
|
-
endedAt: ended ?
|
|
256192
|
+
endedAt: ended ? unitListKey.review(u.review).at : null,
|
|
255594
256193
|
startedAt: u.review.startedAt ?? u.review.createdAt,
|
|
255595
256194
|
actorId: u.review.reviewerActorId,
|
|
255596
256195
|
cursor: u.unitId,
|
|
@@ -255646,14 +256245,16 @@ var init_units = __esm({
|
|
|
255646
256245
|
async find(q4) {
|
|
255647
256246
|
const limit = Math.max(1, Math.min(FIND_MAX_LIMIT, Math.floor(q4.limit ?? FIND_DEFAULT_LIMIT)));
|
|
255648
256247
|
const sinceIso = parseSince(q4.since, this.nowMs);
|
|
255649
|
-
const
|
|
256248
|
+
const batch = Math.min(FIND_BATCH_MAX, limit * 3);
|
|
255650
256249
|
const wants = (t) => !q4.type || q4.type === t;
|
|
255651
|
-
const
|
|
256250
|
+
const base = { ...sinceIso ? { sinceIso } : {}, ...q4.actor ? { actorId: q4.actor } : {} };
|
|
256251
|
+
const sources = [];
|
|
255652
256252
|
if (wants("work")) {
|
|
255653
|
-
|
|
255654
|
-
|
|
255655
|
-
|
|
255656
|
-
|
|
256253
|
+
sources.push(keysetSource(
|
|
256254
|
+
(before) => this.data.listEndedWorks({ ...base, ...before ? { before } : {}, limit: batch }),
|
|
256255
|
+
unitListKey.work,
|
|
256256
|
+
batch,
|
|
256257
|
+
async (w2) => workEnded(w2) ? [{
|
|
255657
256258
|
unitId: w2.id,
|
|
255658
256259
|
type: "work",
|
|
255659
256260
|
endedAt: w2.endedAt ?? w2.deadAt,
|
|
@@ -255661,69 +256262,81 @@ var init_units = __esm({
|
|
|
255661
256262
|
sessionId: null,
|
|
255662
256263
|
cursor: w2.id,
|
|
255663
256264
|
load: async () => this.cacheUnit({ kind: "work", unitId: w2.id, work: w2 })
|
|
255664
|
-
}
|
|
255665
|
-
|
|
255666
|
-
|
|
255667
|
-
|
|
255668
|
-
|
|
255669
|
-
|
|
256265
|
+
}] : []
|
|
256266
|
+
));
|
|
256267
|
+
sources.push(keysetSource(
|
|
256268
|
+
(before) => this.data.listEndedReviews({ ...base, ...before ? { before } : {}, limit: batch }),
|
|
256269
|
+
unitListKey.review,
|
|
256270
|
+
batch,
|
|
256271
|
+
async (r5) => reviewEnded(r5) ? [{
|
|
255670
256272
|
unitId: r5.id,
|
|
255671
256273
|
type: "work",
|
|
255672
|
-
endedAt:
|
|
256274
|
+
endedAt: unitListKey.review(r5).at,
|
|
255673
256275
|
actorId: r5.reviewerActorId,
|
|
255674
256276
|
sessionId: null,
|
|
255675
256277
|
cursor: r5.id,
|
|
255676
256278
|
load: async () => this.cacheUnit({ kind: "review", unitId: r5.id, review: r5 })
|
|
255677
|
-
}
|
|
255678
|
-
|
|
256279
|
+
}] : []
|
|
256280
|
+
));
|
|
255679
256281
|
}
|
|
255680
256282
|
if (wants("delegation")) {
|
|
255681
|
-
|
|
255682
|
-
|
|
255683
|
-
|
|
255684
|
-
|
|
255685
|
-
|
|
255686
|
-
|
|
255687
|
-
|
|
255688
|
-
|
|
255689
|
-
|
|
255690
|
-
|
|
255691
|
-
|
|
255692
|
-
|
|
255693
|
-
|
|
255694
|
-
|
|
256283
|
+
sources.push(keysetSource(
|
|
256284
|
+
(before) => this.data.listEndedDelegations({ ...base, ...before ? { before } : {}, limit: batch }),
|
|
256285
|
+
unitListKey.delegation,
|
|
256286
|
+
batch,
|
|
256287
|
+
async (d5) => {
|
|
256288
|
+
if (!delegationEnded(d5)) return [];
|
|
256289
|
+
const unitId = `dlg:${d5.id}`;
|
|
256290
|
+
return [{
|
|
256291
|
+
unitId,
|
|
256292
|
+
type: "delegation",
|
|
256293
|
+
endedAt: d5.settledAt ?? d5.createdAt,
|
|
256294
|
+
actorId: d5.expertActorId,
|
|
256295
|
+
sessionId: null,
|
|
256296
|
+
cursor: delegationCursor(d5),
|
|
256297
|
+
load: async () => this.cacheUnit({ kind: "delegation", unitId, dlg: d5 })
|
|
256298
|
+
}];
|
|
256299
|
+
}
|
|
256300
|
+
));
|
|
255695
256301
|
}
|
|
255696
256302
|
if (wants("chat")) {
|
|
255697
256303
|
const excluded = new Set(!q4.includeMeta && this.deps.reflectorSessionIds ? await this.deps.reflectorSessionIds() : []);
|
|
255698
|
-
|
|
255699
|
-
|
|
255700
|
-
|
|
255701
|
-
|
|
255702
|
-
|
|
255703
|
-
|
|
255704
|
-
|
|
255705
|
-
|
|
255706
|
-
|
|
255707
|
-
|
|
255708
|
-
|
|
255709
|
-
|
|
255710
|
-
if (
|
|
255711
|
-
const
|
|
255712
|
-
if (
|
|
255713
|
-
const
|
|
255714
|
-
|
|
255715
|
-
|
|
255716
|
-
|
|
255717
|
-
endedAt
|
|
255718
|
-
|
|
255719
|
-
|
|
255720
|
-
|
|
255721
|
-
|
|
255722
|
-
|
|
256304
|
+
sources.push(keysetSource(
|
|
256305
|
+
(before) => this.data.listRecentSessions({
|
|
256306
|
+
...sinceIso ? { sinceIso } : {},
|
|
256307
|
+
...q4.actor ? { aiActorId: q4.actor } : {},
|
|
256308
|
+
includeAnalysis: q4.includeMeta === true,
|
|
256309
|
+
...before ? { before } : {},
|
|
256310
|
+
limit: batch
|
|
256311
|
+
}),
|
|
256312
|
+
unitListKey.session,
|
|
256313
|
+
batch,
|
|
256314
|
+
// 会话按 touched_at 取:段的结束时间不晚于它,水位照样成立。
|
|
256315
|
+
async (s3) => {
|
|
256316
|
+
if (excluded.has(s3.id)) return [];
|
|
256317
|
+
const ss = await this.sessionSegments(s3.id);
|
|
256318
|
+
if (!ss) return [];
|
|
256319
|
+
const segs = [];
|
|
256320
|
+
for (let i5 = 0; i5 < ss.segments.length; i5++) {
|
|
256321
|
+
const seg = ss.segments[i5];
|
|
256322
|
+
if (!segmentEnded(seg, i5 < ss.segments.length - 1, this.nowMs)) continue;
|
|
256323
|
+
const endedAt = turnEnd(seg.turns[seg.turns.length - 1]);
|
|
256324
|
+
if (sinceIso && ms(endedAt) < ms(sinceIso)) continue;
|
|
256325
|
+
const idx = i5;
|
|
256326
|
+
segs.push({
|
|
256327
|
+
unitId: segId(s3.id, seg.firstTurnId),
|
|
256328
|
+
type: "chat",
|
|
256329
|
+
endedAt,
|
|
256330
|
+
actorId: s3.aiActorId,
|
|
256331
|
+
sessionId: s3.id,
|
|
256332
|
+
cursor: seg.lastTurnId,
|
|
256333
|
+
load: () => this.segmentUnit(ss, idx)
|
|
256334
|
+
});
|
|
256335
|
+
}
|
|
256336
|
+
return segs;
|
|
255723
256337
|
}
|
|
255724
|
-
|
|
256338
|
+
));
|
|
255725
256339
|
}
|
|
255726
|
-
cands.sort((a5, b6) => ms(b6.endedAt) - ms(a5.endedAt) || (a5.unitId < b6.unitId ? 1 : -1));
|
|
255727
256340
|
const roleCache = /* @__PURE__ */ new Map();
|
|
255728
256341
|
const roleOk = async (actorId) => {
|
|
255729
256342
|
if (!q4.role) return true;
|
|
@@ -255732,22 +256345,34 @@ var init_units = __esm({
|
|
|
255732
256345
|
const roles = await memo(roleCache, actorId, () => fn(actorId)) ?? "";
|
|
255733
256346
|
return roles.split(",").map((r5) => r5.trim()).includes(q4.role);
|
|
255734
256347
|
};
|
|
255735
|
-
const reflected = this.deps.reflectedCursors ? await this.deps.reflectedCursors(cands.map((c5) => c5.unitId)) : /* @__PURE__ */ new Map();
|
|
255736
256348
|
const out = [];
|
|
255737
|
-
|
|
255738
|
-
for (const
|
|
255739
|
-
|
|
255740
|
-
|
|
255741
|
-
|
|
255742
|
-
|
|
255743
|
-
|
|
255744
|
-
|
|
255745
|
-
const
|
|
255746
|
-
if (
|
|
255747
|
-
|
|
255748
|
-
|
|
256349
|
+
const pending = [];
|
|
256350
|
+
for (const src of sources) pending.push(...await src.next());
|
|
256351
|
+
for (; ; ) {
|
|
256352
|
+
const open3 = sources.filter((src) => src.watermark !== null);
|
|
256353
|
+
const mark = open3.length ? Math.max(...open3.map((src) => ms(src.watermark))) : -Infinity;
|
|
256354
|
+
pending.sort((a5, b6) => ms(b6.endedAt) - ms(a5.endedAt) || (a5.unitId < b6.unitId ? 1 : -1));
|
|
256355
|
+
let ready = 0;
|
|
256356
|
+
while (ready < pending.length && ms(pending[ready].endedAt) > mark) ready++;
|
|
256357
|
+
const chunk = pending.splice(0, ready);
|
|
256358
|
+
if (chunk.length > 0) {
|
|
256359
|
+
const reflected = this.deps.reflectedCursors ? await this.deps.reflectedCursors(chunk.map((c5) => c5.unitId)) : /* @__PURE__ */ new Map();
|
|
256360
|
+
for (const c5 of chunk) {
|
|
256361
|
+
if (!await roleOk(c5.actorId)) continue;
|
|
256362
|
+
if (q4.unreflected && (reflected.get(c5.unitId) ?? []).some((r5) => cursorCovers(r5, c5.cursor, c5.type))) continue;
|
|
256363
|
+
const u = await c5.load();
|
|
256364
|
+
if (!u) continue;
|
|
256365
|
+
const s3 = await this.summary(u, reflected);
|
|
256366
|
+
if (!s3.ended) continue;
|
|
256367
|
+
if (q4.outcome && s3.outcome !== q4.outcome) continue;
|
|
256368
|
+
out.push(s3);
|
|
256369
|
+
if (out.length >= limit) return out;
|
|
256370
|
+
}
|
|
256371
|
+
}
|
|
256372
|
+
if (open3.length === 0) return out;
|
|
256373
|
+
const lead = open3.reduce((a5, b6) => ms(b6.watermark) > ms(a5.watermark) ? b6 : a5);
|
|
256374
|
+
pending.push(...await lead.next());
|
|
255749
256375
|
}
|
|
255750
|
-
return out;
|
|
255751
256376
|
}
|
|
255752
256377
|
cacheUnit(u) {
|
|
255753
256378
|
if (!this.units.has(u.unitId)) this.units.set(u.unitId, Promise.resolve(u));
|
|
@@ -255948,9 +256573,10 @@ var init_units = __esm({
|
|
|
255948
256573
|
return { runHop, nodes: nodes5 };
|
|
255949
256574
|
}
|
|
255950
256575
|
/* ── outcome ── */
|
|
255951
|
-
async outcome(unitId) {
|
|
256576
|
+
async outcome(unitId, opts = {}) {
|
|
255952
256577
|
const u = await this.mustLoad(unitId);
|
|
255953
256578
|
const signals = {};
|
|
256579
|
+
const field = (s3) => clipField(s3, outcomeFetchCmd(u.unitId), opts.full === true);
|
|
255954
256580
|
switch (u.kind) {
|
|
255955
256581
|
case "work": {
|
|
255956
256582
|
const w2 = u.work;
|
|
@@ -255977,8 +256603,7 @@ var init_units = __esm({
|
|
|
255977
256603
|
decidedAt: r5.decidedAt
|
|
255978
256604
|
}));
|
|
255979
256605
|
signals["issues"] = (await this.data.issuesInWorkorder(w2.workorderId, { aboutWorkIds: [w2.id], limit: 100 })).map((i5) => {
|
|
255980
|
-
|
|
255981
|
-
return { issueId: i5.id, kind: i5.kind, author: i5.authorActorId, resolved: i5.resolvedAt != null, createdAt: i5.createdAt, body: b6.text, bodyChars: b6.chars };
|
|
256606
|
+
return { issueId: i5.id, kind: i5.kind, author: i5.authorActorId, resolved: i5.resolvedAt != null, createdAt: i5.createdAt, body: field(i5.body) };
|
|
255982
256607
|
});
|
|
255983
256608
|
signals["reworkedBy"] = await this.data.reworkedBy(w2);
|
|
255984
256609
|
break;
|
|
@@ -256024,16 +256649,16 @@ var init_units = __esm({
|
|
|
256024
256649
|
const inter = await this.segmentInterjections(u);
|
|
256025
256650
|
signals["interjections"] = [...inter].map(([turnId, msgs]) => ({
|
|
256026
256651
|
turnId,
|
|
256027
|
-
messages: msgs.map((m4) => {
|
|
256028
|
-
const c5 = clip4(m4.content);
|
|
256029
|
-
return { messageId: m4.id, at: m4.at, text: c5.text, chars: c5.chars };
|
|
256030
|
-
})
|
|
256652
|
+
messages: msgs.map((m4) => ({ messageId: m4.id, at: m4.at, body: field(m4.content) }))
|
|
256031
256653
|
}));
|
|
256032
256654
|
const endIso = new Date(last.completedAt ? ms(last.completedAt) : this.nowMs).toISOString();
|
|
256033
|
-
signals["pending"] = (await this.data.pendingMessagesOf(u.session.id, u.seg.turns[0].reservedAt, endIso, 200)).map((p4) => {
|
|
256034
|
-
|
|
256035
|
-
|
|
256036
|
-
|
|
256655
|
+
signals["pending"] = (await this.data.pendingMessagesOf(u.session.id, u.seg.turns[0].reservedAt, endIso, 200)).map((p4) => ({
|
|
256656
|
+
id: p4.id,
|
|
256657
|
+
at: p4.createdAt,
|
|
256658
|
+
state: p4.state,
|
|
256659
|
+
flavour: p4.flavour,
|
|
256660
|
+
body: field(p4.text)
|
|
256661
|
+
}));
|
|
256037
256662
|
break;
|
|
256038
256663
|
}
|
|
256039
256664
|
}
|
|
@@ -256048,9 +256673,10 @@ var init_units = __esm({
|
|
|
256048
256673
|
}
|
|
256049
256674
|
return out;
|
|
256050
256675
|
}
|
|
256051
|
-
async exogenous(unitId) {
|
|
256676
|
+
async exogenous(unitId, opts = {}) {
|
|
256052
256677
|
const u = await this.mustLoad(unitId);
|
|
256053
256678
|
const facts = [];
|
|
256679
|
+
const field = (s3) => clipField(s3, exogenousFetchCmd(u.unitId), opts.full === true, EXOGENOUS_TEXT_CAP);
|
|
256054
256680
|
const runs = await this.runRows(await this.runIdsOf(u));
|
|
256055
256681
|
for (const r5 of runs) {
|
|
256056
256682
|
const abnormal = EXOGENOUS_RUN_STATUS.has(r5.status);
|
|
@@ -256060,7 +256686,7 @@ var init_units = __esm({
|
|
|
256060
256686
|
at: r5.endedAt ?? r5.startedAt,
|
|
256061
256687
|
runId: r5.id,
|
|
256062
256688
|
summary: `run ${r5.id} \u72B6\u6001 ${r5.status}${r5.exitReason ? `\uFF0Cexit_reason=${r5.exitReason}` : ""}${r5.errorCode ? `\uFF0Cerror_code=${r5.errorCode}` : ""}`,
|
|
256063
|
-
detail: { status: r5.status, exitReason: r5.exitReason, errorCode: r5.errorCode, errorMessage: r5.errorMessage ?
|
|
256689
|
+
detail: { status: r5.status, exitReason: r5.exitReason, errorCode: r5.errorCode, errorMessage: r5.errorMessage ? field(r5.errorMessage) : null }
|
|
256064
256690
|
});
|
|
256065
256691
|
}
|
|
256066
256692
|
const instances = [...new Set(runs.map((r5) => r5.runtimeInstanceId).filter((x2) => !!x2))];
|
|
@@ -256103,11 +256729,11 @@ var init_units = __esm({
|
|
|
256103
256729
|
});
|
|
256104
256730
|
}
|
|
256105
256731
|
}
|
|
256106
|
-
if (u.kind === "work") facts.push(...await this.upstreamFacts(u.work));
|
|
256732
|
+
if (u.kind === "work") facts.push(...await this.upstreamFacts(u.work, field));
|
|
256107
256733
|
return facts;
|
|
256108
256734
|
}
|
|
256109
256735
|
/** 单元时间窗里上游(输入节点、brief)收到的 issue、出的新版本。 */
|
|
256110
|
-
async upstreamFacts(w2) {
|
|
256736
|
+
async upstreamFacts(w2, field) {
|
|
256111
256737
|
const out = [];
|
|
256112
256738
|
const from = w2.startedAt ?? w2.createdAt;
|
|
256113
256739
|
const to = w2.endedAt ?? w2.deadAt ?? new Date(this.nowMs).toISOString();
|
|
@@ -256119,13 +256745,15 @@ var init_units = __esm({
|
|
|
256119
256745
|
if (nodes5.size === 0) return out;
|
|
256120
256746
|
const nodeIds = [...nodes5];
|
|
256121
256747
|
for (const i5 of await this.data.issuesInWorkorder(w2.workorderId, { aboutNodeIds: nodeIds, fromIso: from, toIso: to, limit: 50 })) {
|
|
256122
|
-
const b6 =
|
|
256748
|
+
const b6 = field(i5.body);
|
|
256749
|
+
const head = (i5.body.split("\n")[0] ?? "").slice(0, EXOGENOUS_SUMMARY_CAP);
|
|
256750
|
+
const more = head.length < i5.body.length ? ` \u2026\uFF08\u5168\u6587 ${i5.body.length} \u5B57 \u2192 ${b6.fetchCmd}\uFF09` : "";
|
|
256123
256751
|
out.push({
|
|
256124
256752
|
kind: "upstream-issue",
|
|
256125
256753
|
at: i5.createdAt,
|
|
256126
256754
|
runId: null,
|
|
256127
|
-
summary: `\u6267\u884C\u671F\u95F4\u4E0A\u6E38\u8282\u70B9 ${i5.aboutNodeId} \u6536\u5230 ${i5.kind}\uFF1A${
|
|
256128
|
-
detail: { issueId: i5.id, kind: i5.kind, aboutNodeId: i5.aboutNodeId, author: i5.authorActorId, resolved: i5.resolvedAt != null, body: b6
|
|
256755
|
+
summary: `\u6267\u884C\u671F\u95F4\u4E0A\u6E38\u8282\u70B9 ${i5.aboutNodeId} \u6536\u5230 ${i5.kind}\uFF1A${head}${more}`,
|
|
256756
|
+
detail: { issueId: i5.id, kind: i5.kind, aboutNodeId: i5.aboutNodeId, author: i5.authorActorId, resolved: i5.resolvedAt != null, body: b6 }
|
|
256129
256757
|
});
|
|
256130
256758
|
}
|
|
256131
256759
|
for (const x2 of await this.data.worksAcceptedInWindow(nodeIds, from, to, 50)) {
|
|
@@ -256548,12 +257176,13 @@ function reflectionDomain(opts) {
|
|
|
256548
257176
|
router.get("/api/traces/units/:unit/outcome", async (req) => {
|
|
256549
257177
|
const d5 = await deps(req);
|
|
256550
257178
|
const u = await requireUnit(d5, req.params.unit);
|
|
256551
|
-
return { status: 200, body: await d5.units.outcome(u.summary.unitId).catch(unitErr) };
|
|
257179
|
+
return { status: 200, body: await d5.units.outcome(u.summary.unitId, { full: boolParam(req.query, "full") }).catch(unitErr) };
|
|
256552
257180
|
});
|
|
256553
257181
|
router.get("/api/traces/units/:unit/exogenous", async (req) => {
|
|
256554
257182
|
const d5 = await deps(req);
|
|
256555
257183
|
const u = await requireUnit(d5, req.params.unit);
|
|
256556
|
-
|
|
257184
|
+
const facts = await d5.units.exogenous(u.summary.unitId, { full: boolParam(req.query, "full") }).catch(unitErr);
|
|
257185
|
+
return { status: 200, body: { unitId: u.summary.unitId, facts } };
|
|
256557
257186
|
});
|
|
256558
257187
|
router.get("/api/traces/units/:unit/runs", async (req) => {
|
|
256559
257188
|
const d5 = await deps(req);
|
|
@@ -257714,546 +258343,6 @@ var init_reflection_service = __esm({
|
|
|
257714
258343
|
}
|
|
257715
258344
|
});
|
|
257716
258345
|
|
|
257717
|
-
// ../server/src/domains/trace/unit-data.ts
|
|
257718
|
-
function quoteSchema(name) {
|
|
257719
|
-
if (!/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/.test(name)) throw new Error(`invalid schema name: ${name}`);
|
|
257720
|
-
return `"${name}"`;
|
|
257721
|
-
}
|
|
257722
|
-
function dispatchSchemaIdent(name) {
|
|
257723
|
-
const s3 = name.replace(/[^a-zA-Z0-9_]/g, "");
|
|
257724
|
-
if (!s3) throw new Error(`invalid dispatch schema name: ${name}`);
|
|
257725
|
-
return `"${s3}"`;
|
|
257726
|
-
}
|
|
257727
|
-
function replyIssueIdFromWorkId(workId) {
|
|
257728
|
-
const m4 = /^wk:reply:(.+):\d+$/.exec(workId);
|
|
257729
|
-
return m4 ? m4[1] : null;
|
|
257730
|
-
}
|
|
257731
|
-
function toWork(r5) {
|
|
257732
|
-
return {
|
|
257733
|
-
id: String(r5["id"]),
|
|
257734
|
-
workorderId: String(r5["workorder_id"]),
|
|
257735
|
-
nodeId: String(r5["node_id"]),
|
|
257736
|
-
nodeType: str5(r5["node_type"]),
|
|
257737
|
-
nodeTitle: str5(r5["node_title"]),
|
|
257738
|
-
assigneeActorId: String(r5["assignee_actor_id"]),
|
|
257739
|
-
createdAt: isoReq(r5["created_at"]),
|
|
257740
|
-
startedAt: iso4(r5["started_at"]),
|
|
257741
|
-
endedAt: iso4(r5["ended_at"]),
|
|
257742
|
-
deadAt: iso4(r5["dead_at"]),
|
|
257743
|
-
status: str5(r5["status"]),
|
|
257744
|
-
outcome: str5(r5["outcome"]),
|
|
257745
|
-
// 存量 lane 为空时按 work id 前缀兜底(回信轮 id 恒为 `wk:reply:<issueId>:<n>`)。
|
|
257746
|
-
lane: r5["lane"] === "reply" || r5["lane"] == null && String(r5["id"]).startsWith("wk:reply:") ? "reply" : "main",
|
|
257747
|
-
replyIssueId: replyIssueIdFromWorkId(String(r5["id"])),
|
|
257748
|
-
continuesWorkId: str5(r5["continues_work_id"]),
|
|
257749
|
-
acceptanceState: str5(r5["acceptance_state"]) ?? null,
|
|
257750
|
-
acceptedAt: iso4(r5["accepted_at"]),
|
|
257751
|
-
rejectedReason: str5(r5["rejected_reason"]),
|
|
257752
|
-
overrideBy: str5(r5["override_by"]),
|
|
257753
|
-
overrideReason: str5(r5["override_reason"]),
|
|
257754
|
-
frozenIssueIds: strArr(r5["frozen_issue_ids"]),
|
|
257755
|
-
protocolRecovery: r5["protocol_recovery"] ?? null,
|
|
257756
|
-
killSource: str5(r5["kill_source"]),
|
|
257757
|
-
outputVersionNo: num3(r5["output_version_no"])
|
|
257758
|
-
};
|
|
257759
|
-
}
|
|
257760
|
-
function toReview(r5) {
|
|
257761
|
-
const verdict = str5(r5["verdict"]);
|
|
257762
|
-
let status = str5(r5["status"]);
|
|
257763
|
-
if (!status) {
|
|
257764
|
-
if (r5["retry_at"] != null) status = "retry";
|
|
257765
|
-
else if (r5["cancelled_at"] != null) status = "dead";
|
|
257766
|
-
else if (verdict === "approve" && r5["decided_at"] != null) status = "accept";
|
|
257767
|
-
else if (verdict === "request_changes" && r5["decided_at"] != null) status = "reject";
|
|
257768
|
-
else if (r5["ended_at"] != null) status = verdict ? verdict === "approve" ? "accept" : "reject" : "failed";
|
|
257769
|
-
else status = "running";
|
|
257770
|
-
}
|
|
257771
|
-
return {
|
|
257772
|
-
id: String(r5["id"]),
|
|
257773
|
-
workorderId: String(r5["workorder_id"]),
|
|
257774
|
-
nodeId: String(r5["node_id"]),
|
|
257775
|
-
nodeTitle: str5(r5["node_title"]),
|
|
257776
|
-
targetWorkId: String(r5["target_work_id"]),
|
|
257777
|
-
reviewerActorId: String(r5["reviewer_actor_id"]),
|
|
257778
|
-
reviewGroup: String(r5["review_group"] ?? ""),
|
|
257779
|
-
status,
|
|
257780
|
-
verdict: verdict ?? null,
|
|
257781
|
-
note: str5(r5["note"]),
|
|
257782
|
-
createdAt: isoReq(r5["created_at"]),
|
|
257783
|
-
startedAt: iso4(r5["started_at"]),
|
|
257784
|
-
endedAt: iso4(r5["ended_at"]),
|
|
257785
|
-
decidedAt: iso4(r5["decided_at"]),
|
|
257786
|
-
killSource: str5(r5["kill_source"])
|
|
257787
|
-
};
|
|
257788
|
-
}
|
|
257789
|
-
function toIssue(r5) {
|
|
257790
|
-
return {
|
|
257791
|
-
id: String(r5["id"]),
|
|
257792
|
-
workorderId: String(r5["workorder_id"]),
|
|
257793
|
-
kind: String(r5["kind"]),
|
|
257794
|
-
body: String(r5["body"] ?? ""),
|
|
257795
|
-
aboutNodeId: str5(r5["about_node_id"]),
|
|
257796
|
-
aboutWorkId: str5(r5["about_work_id"]),
|
|
257797
|
-
raisedByNodeId: str5(r5["raised_by_node_id"]),
|
|
257798
|
-
authorActorId: String(r5["author_actor_id"]),
|
|
257799
|
-
resolvedAt: iso4(r5["resolved_at"]),
|
|
257800
|
-
createdAt: isoReq(r5["created_at"])
|
|
257801
|
-
};
|
|
257802
|
-
}
|
|
257803
|
-
function toDispatch(r5) {
|
|
257804
|
-
return {
|
|
257805
|
-
id: String(r5["id"]),
|
|
257806
|
-
targetKind: String(r5["target_kind"]),
|
|
257807
|
-
targetId: String(r5["target_id"]),
|
|
257808
|
-
actorId: str5(r5["actor_id"]),
|
|
257809
|
-
createdAt: isoReq(r5["created_at"]),
|
|
257810
|
-
startedAt: iso4(r5["started_at"]),
|
|
257811
|
-
endedAt: iso4(r5["ended_at"]),
|
|
257812
|
-
outcome: str5(r5["outcome"]),
|
|
257813
|
-
reason: str5(r5["reason"]),
|
|
257814
|
-
protocolRecoveryRound: num3(r5["protocol_recovery_round"])
|
|
257815
|
-
};
|
|
257816
|
-
}
|
|
257817
|
-
function toDelegation(r5) {
|
|
257818
|
-
return {
|
|
257819
|
-
id: String(r5["id"]),
|
|
257820
|
-
parentSessionId: String(r5["parent_session_id"]),
|
|
257821
|
-
parentMessageId: String(r5["parent_message_id"] ?? ""),
|
|
257822
|
-
childSessionId: String(r5["child_session_id"]),
|
|
257823
|
-
expertActorId: String(r5["expert_actor_id"]),
|
|
257824
|
-
state: String(r5["state"]),
|
|
257825
|
-
failureKind: str5(r5["failure_kind"]),
|
|
257826
|
-
failureReason: str5(r5["failure_reason"]),
|
|
257827
|
-
consecutiveFails: num3(r5["consecutive_fails"]) ?? 0,
|
|
257828
|
-
dispatchSeq: num3(r5["dispatch_seq"]),
|
|
257829
|
-
createdAt: isoReq(r5["created_at"]),
|
|
257830
|
-
settledAt: iso4(r5["settled_at"]),
|
|
257831
|
-
label: str5(r5["label"]),
|
|
257832
|
-
taskDigest: str5(r5["task_digest"])
|
|
257833
|
-
};
|
|
257834
|
-
}
|
|
257835
|
-
function toSession(r5) {
|
|
257836
|
-
return {
|
|
257837
|
-
id: String(r5["id"]),
|
|
257838
|
-
humanActorId: String(r5["human_actor_id"]),
|
|
257839
|
-
aiActorId: String(r5["ai_actor_id"]),
|
|
257840
|
-
title: str5(r5["title"]),
|
|
257841
|
-
analyzedRunId: str5(r5["analyzed_run_id"]),
|
|
257842
|
-
runtimeSessionId: str5(r5["runtime_session_id"]),
|
|
257843
|
-
touchedAt: isoReq(r5["touched_at"]),
|
|
257844
|
-
createdAt: isoReq(r5["created_at"])
|
|
257845
|
-
};
|
|
257846
|
-
}
|
|
257847
|
-
function toTurn(r5) {
|
|
257848
|
-
return {
|
|
257849
|
-
id: String(r5["id"]),
|
|
257850
|
-
chatSessionId: String(r5["chat_session_id"]),
|
|
257851
|
-
source: String(r5["source"]),
|
|
257852
|
-
status: String(r5["status"]),
|
|
257853
|
-
reservedAt: isoReq(r5["reserved_at"]),
|
|
257854
|
-
startedAt: iso4(r5["started_at"]),
|
|
257855
|
-
completedAt: iso4(r5["completed_at"]),
|
|
257856
|
-
cancelledBy: str5(r5["cancelled_by"]),
|
|
257857
|
-
dispatchId: str5(r5["dispatch_id"]),
|
|
257858
|
-
assistantRunId: str5(r5["assistant_run_id"])
|
|
257859
|
-
};
|
|
257860
|
-
}
|
|
257861
|
-
function toMessage(r5) {
|
|
257862
|
-
return {
|
|
257863
|
-
id: String(r5["id"]),
|
|
257864
|
-
sessionId: String(r5["session_id"]),
|
|
257865
|
-
role: String(r5["role"]),
|
|
257866
|
-
content: String(r5["content"] ?? ""),
|
|
257867
|
-
seq: Number(r5["seq"]),
|
|
257868
|
-
createdAt: isoReq(r5["created_at"]),
|
|
257869
|
-
runId: str5(r5["run_id"]),
|
|
257870
|
-
turnId: str5(r5["turn_id"]),
|
|
257871
|
-
source: str5(r5["source"])
|
|
257872
|
-
};
|
|
257873
|
-
}
|
|
257874
|
-
function toLink(r5) {
|
|
257875
|
-
return { sessionId: String(r5["session_id"]), workOrderId: String(r5["work_order_id"]), linkedAt: isoReq(r5["linked_at"]) };
|
|
257876
|
-
}
|
|
257877
|
-
var iso4, isoReq, str5, num3, strArr, WORK_COLS, REVIEW_COLS, MAX_IDS, capIds, PgUnitDataSource;
|
|
257878
|
-
var init_unit_data = __esm({
|
|
257879
|
-
"../server/src/domains/trace/unit-data.ts"() {
|
|
257880
|
-
"use strict";
|
|
257881
|
-
iso4 = (v2) => v2 == null ? null : v2 instanceof Date ? v2.toISOString() : typeof v2 === "string" ? new Date(v2).toISOString() : null;
|
|
257882
|
-
isoReq = (v2) => iso4(v2) ?? (/* @__PURE__ */ new Date(0)).toISOString();
|
|
257883
|
-
str5 = (v2) => typeof v2 === "string" ? v2 : v2 == null ? null : String(v2);
|
|
257884
|
-
num3 = (v2) => v2 == null ? null : Number.isFinite(Number(v2)) ? Number(v2) : null;
|
|
257885
|
-
strArr = (v2) => Array.isArray(v2) ? v2.filter((x2) => typeof x2 === "string") : [];
|
|
257886
|
-
WORK_COLS = `w.id, w.workorder_id, w.node_id, n.type AS node_type, n.title AS node_title, w.assignee_actor_id,
|
|
257887
|
-
w.created_at, w.started_at, w.ended_at, w.dead_at, w.status, w.outcome, w.lane, w.continues_work_id,
|
|
257888
|
-
w.acceptance_state, w.accepted_at, w.rejected_reason, w.override_by, w.override_reason, w.frozen_issue_ids,
|
|
257889
|
-
w.protocol_recovery, w.kill_source, w.output_version_no`;
|
|
257890
|
-
REVIEW_COLS = `r.id, r.workorder_id, r.node_id, n.title AS node_title, r.target_work_id, r.reviewer_actor_id, r.review_group,
|
|
257891
|
-
r.status, r.verdict, r.note, r.created_at, r.started_at, r.ended_at, r.decided_at, r.cancelled_at, r.retry_at, r.kill_source`;
|
|
257892
|
-
MAX_IDS = 500;
|
|
257893
|
-
capIds = (ids2) => [...new Set(ids2)].slice(0, MAX_IDS);
|
|
257894
|
-
PgUnitDataSource = class {
|
|
257895
|
-
pool;
|
|
257896
|
-
/** 引擎 schema(works / reviews / issues / events / workflow_*)。 */
|
|
257897
|
-
e;
|
|
257898
|
-
/** chat 一族(chat_sessions / chat_messages / chat_session_turns / 委派);缺省与引擎同 schema。 */
|
|
257899
|
-
c;
|
|
257900
|
-
/** 派发台账 schema(按 dispatches store 的口径净化)。 */
|
|
257901
|
-
d;
|
|
257902
|
-
constructor(opts) {
|
|
257903
|
-
this.pool = opts.pool;
|
|
257904
|
-
this.e = quoteSchema(opts.engineSchema);
|
|
257905
|
-
this.c = quoteSchema(opts.chatSchema ?? opts.engineSchema);
|
|
257906
|
-
this.d = dispatchSchemaIdent(opts.dispatchSchema);
|
|
257907
|
-
}
|
|
257908
|
-
async q(text7, values = []) {
|
|
257909
|
-
return (await this.pool.query(text7, values)).rows;
|
|
257910
|
-
}
|
|
257911
|
-
/* ── work / review ── */
|
|
257912
|
-
async getWorks(ids2) {
|
|
257913
|
-
if (ids2.length === 0) return [];
|
|
257914
|
-
const rows = await this.q(
|
|
257915
|
-
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id WHERE w.id = ANY($1)`,
|
|
257916
|
-
[capIds(ids2)]
|
|
257917
|
-
);
|
|
257918
|
-
return rows.map(toWork);
|
|
257919
|
-
}
|
|
257920
|
-
async getReview(id) {
|
|
257921
|
-
const rows = await this.q(
|
|
257922
|
-
`SELECT ${REVIEW_COLS} FROM ${this.e}.reviews r LEFT JOIN ${this.e}.workflow_nodes n ON n.id = r.node_id WHERE r.id = $1`,
|
|
257923
|
-
[id]
|
|
257924
|
-
);
|
|
257925
|
-
return rows[0] ? toReview(rows[0]) : null;
|
|
257926
|
-
}
|
|
257927
|
-
async reviewsOfWorks(workIds) {
|
|
257928
|
-
if (workIds.length === 0) return [];
|
|
257929
|
-
const rows = await this.q(
|
|
257930
|
-
`SELECT ${REVIEW_COLS} FROM ${this.e}.reviews r LEFT JOIN ${this.e}.workflow_nodes n ON n.id = r.node_id
|
|
257931
|
-
WHERE r.target_work_id = ANY($1) ORDER BY r.created_at ASC, r.id ASC LIMIT 500`,
|
|
257932
|
-
[capIds(workIds)]
|
|
257933
|
-
);
|
|
257934
|
-
return rows.map(toReview);
|
|
257935
|
-
}
|
|
257936
|
-
async worksOfNode(nodeId, limit) {
|
|
257937
|
-
const rows = await this.q(
|
|
257938
|
-
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
257939
|
-
WHERE w.node_id = $1 ORDER BY w.created_at DESC, w.id DESC LIMIT $2`,
|
|
257940
|
-
[nodeId, limit]
|
|
257941
|
-
);
|
|
257942
|
-
return rows.map(toWork);
|
|
257943
|
-
}
|
|
257944
|
-
async workInputsOf(workIds) {
|
|
257945
|
-
if (workIds.length === 0) return [];
|
|
257946
|
-
const rows = await this.q(
|
|
257947
|
-
`SELECT work_id, upstream_node_id, upstream_work_id FROM ${this.e}.work_inputs WHERE work_id = ANY($1) LIMIT 2000`,
|
|
257948
|
-
[capIds(workIds)]
|
|
257949
|
-
);
|
|
257950
|
-
return rows.map((r5) => ({
|
|
257951
|
-
workId: String(r5["work_id"]),
|
|
257952
|
-
upstreamNodeId: String(r5["upstream_node_id"]),
|
|
257953
|
-
upstreamWorkId: String(r5["upstream_work_id"])
|
|
257954
|
-
}));
|
|
257955
|
-
}
|
|
257956
|
-
async inputNodesOf(nodeId) {
|
|
257957
|
-
const rows = await this.q(
|
|
257958
|
-
`SELECT from_node_id FROM ${this.e}.workflow_edges WHERE to_node_id = $1 AND kind = 'data' ORDER BY from_node_id LIMIT 100`,
|
|
257959
|
-
[nodeId]
|
|
257960
|
-
);
|
|
257961
|
-
return rows.map((r5) => String(r5["from_node_id"]));
|
|
257962
|
-
}
|
|
257963
|
-
async outputNodesOf(nodeId) {
|
|
257964
|
-
const rows = await this.q(
|
|
257965
|
-
`SELECT to_node_id FROM ${this.e}.workflow_edges WHERE from_node_id = $1 AND kind = 'data' ORDER BY to_node_id LIMIT 100`,
|
|
257966
|
-
[nodeId]
|
|
257967
|
-
);
|
|
257968
|
-
return rows.map((r5) => String(r5["to_node_id"]));
|
|
257969
|
-
}
|
|
257970
|
-
async latestAcceptedWorkOfNodeBefore(nodeId, beforeIso) {
|
|
257971
|
-
const rows = await this.q(
|
|
257972
|
-
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
257973
|
-
WHERE w.node_id = $1 AND w.acceptance_state = 'accepted' AND w.accepted_at IS NOT NULL AND w.accepted_at <= $2
|
|
257974
|
-
ORDER BY w.accepted_at DESC, w.id DESC LIMIT 1`,
|
|
257975
|
-
[nodeId, beforeIso]
|
|
257976
|
-
);
|
|
257977
|
-
return rows[0] ? toWork(rows[0]) : null;
|
|
257978
|
-
}
|
|
257979
|
-
async worksAcceptedInWindow(nodeIds, fromIso, toIso2, limit) {
|
|
257980
|
-
if (nodeIds.length === 0) return [];
|
|
257981
|
-
const rows = await this.q(
|
|
257982
|
-
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
257983
|
-
WHERE w.node_id = ANY($1) AND w.acceptance_state = 'accepted' AND w.accepted_at >= $2 AND w.accepted_at <= $3
|
|
257984
|
-
ORDER BY w.accepted_at ASC, w.id ASC LIMIT $4`,
|
|
257985
|
-
[capIds(nodeIds), fromIso, toIso2, limit]
|
|
257986
|
-
);
|
|
257987
|
-
return rows.map(toWork);
|
|
257988
|
-
}
|
|
257989
|
-
async reworkSourcesOf(work) {
|
|
257990
|
-
const rows = await this.q(
|
|
257991
|
-
`SELECT DISTINCT x.reason->>'workId' AS src
|
|
257992
|
-
FROM (SELECT payload FROM ${this.e}.events
|
|
257993
|
-
WHERE node_id = $1 AND kind = 'work.create' AND payload->>'workId' = $2
|
|
257994
|
-
ORDER BY seq DESC LIMIT 20) ev,
|
|
257995
|
-
LATERAL jsonb_array_elements(COALESCE(ev.payload->'reasons', '[]'::jsonb)) AS x(reason)
|
|
257996
|
-
WHERE x.reason->>'kind' = 'rework' AND x.reason->>'workId' IS NOT NULL`,
|
|
257997
|
-
[work.nodeId, work.id]
|
|
257998
|
-
);
|
|
257999
|
-
return rows.map((r5) => String(r5["src"]));
|
|
258000
|
-
}
|
|
258001
|
-
async reworkedBy(work) {
|
|
258002
|
-
const viaCol = await this.q(
|
|
258003
|
-
`SELECT id FROM ${this.e}.works WHERE node_id = $1 AND continues_work_id = $2 AND id <> $2 ORDER BY created_at ASC LIMIT 50`,
|
|
258004
|
-
[work.nodeId, work.id]
|
|
258005
|
-
);
|
|
258006
|
-
const viaEvents = await this.q(
|
|
258007
|
-
`SELECT DISTINCT ev.payload->>'workId' AS wid
|
|
258008
|
-
FROM (SELECT payload FROM ${this.e}.events WHERE node_id = $1 AND kind = 'work.create' ORDER BY seq DESC LIMIT 200) ev,
|
|
258009
|
-
LATERAL jsonb_array_elements(COALESCE(ev.payload->'reasons', '[]'::jsonb)) AS x(reason)
|
|
258010
|
-
WHERE x.reason->>'kind' = 'rework' AND x.reason->>'workId' = $2`,
|
|
258011
|
-
[work.nodeId, work.id]
|
|
258012
|
-
);
|
|
258013
|
-
const out = /* @__PURE__ */ new Set();
|
|
258014
|
-
for (const r5 of viaCol) out.add(String(r5["id"]));
|
|
258015
|
-
for (const r5 of viaEvents) if (r5["wid"] != null && r5["wid"] !== work.id) out.add(String(r5["wid"]));
|
|
258016
|
-
return [...out];
|
|
258017
|
-
}
|
|
258018
|
-
async briefNodesOf(workorderId) {
|
|
258019
|
-
const rows = await this.q(
|
|
258020
|
-
`SELECT id FROM ${this.e}.workflow_nodes WHERE workorder_id = $1 AND type = 'brief' ORDER BY created_at ASC LIMIT 10`,
|
|
258021
|
-
[workorderId]
|
|
258022
|
-
);
|
|
258023
|
-
return rows.map((r5) => String(r5["id"]));
|
|
258024
|
-
}
|
|
258025
|
-
/* ── issue ── */
|
|
258026
|
-
async issuesByIds(ids2) {
|
|
258027
|
-
if (ids2.length === 0) return [];
|
|
258028
|
-
const rows = await this.q(`SELECT * FROM ${this.e}.issues WHERE id = ANY($1)`, [capIds(ids2)]);
|
|
258029
|
-
return rows.map(toIssue);
|
|
258030
|
-
}
|
|
258031
|
-
async issuesInWorkorder(workorderId, q4) {
|
|
258032
|
-
const args = [workorderId];
|
|
258033
|
-
const conds = ["workorder_id = $1"];
|
|
258034
|
-
const ors = [];
|
|
258035
|
-
const push2 = (v2) => {
|
|
258036
|
-
args.push(v2);
|
|
258037
|
-
return `$${args.length}`;
|
|
258038
|
-
};
|
|
258039
|
-
if (q4.aboutWorkIds?.length) ors.push(`about_work_id = ANY(${push2(capIds(q4.aboutWorkIds))})`);
|
|
258040
|
-
if (q4.aboutNodeIds?.length) ors.push(`about_node_id = ANY(${push2(capIds(q4.aboutNodeIds))})`);
|
|
258041
|
-
if (q4.raisedByNodeIds?.length) ors.push(`raised_by_node_id = ANY(${push2(capIds(q4.raisedByNodeIds))})`);
|
|
258042
|
-
if (ors.length) conds.push(`(${ors.join(" OR ")})`);
|
|
258043
|
-
if (q4.fromIso) conds.push(`created_at >= ${push2(q4.fromIso)}`);
|
|
258044
|
-
if (q4.toIso) conds.push(`created_at <= ${push2(q4.toIso)}`);
|
|
258045
|
-
const rows = await this.q(
|
|
258046
|
-
`SELECT * FROM ${this.e}.issues WHERE ${conds.join(" AND ")} ORDER BY created_at ASC, id ASC LIMIT ${push2(q4.limit)}`,
|
|
258047
|
-
args
|
|
258048
|
-
);
|
|
258049
|
-
return rows.map(toIssue);
|
|
258050
|
-
}
|
|
258051
|
-
async worksHandlingIssues(workorderId, issueIds, limit) {
|
|
258052
|
-
if (issueIds.length === 0) return [];
|
|
258053
|
-
const ids2 = capIds(issueIds);
|
|
258054
|
-
const rows = await this.q(
|
|
258055
|
-
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
258056
|
-
WHERE w.workorder_id = $1
|
|
258057
|
-
AND (w.id LIKE ANY($4::text[]) OR (jsonb_typeof(w.frozen_issue_ids) = 'array' AND w.frozen_issue_ids ?| $2))
|
|
258058
|
-
ORDER BY w.created_at ASC, w.id ASC LIMIT $3`,
|
|
258059
|
-
[workorderId, ids2, limit, ids2.map((i5) => `wk:reply:${i5.replace(/[\\%_]/g, (c5) => `\\${c5}`)}:%`)]
|
|
258060
|
-
);
|
|
258061
|
-
return rows.map(toWork);
|
|
258062
|
-
}
|
|
258063
|
-
/* ── dispatches ── */
|
|
258064
|
-
async dispatchesOf(kind, targetIds) {
|
|
258065
|
-
if (targetIds.length === 0) return [];
|
|
258066
|
-
const rows = await this.q(
|
|
258067
|
-
`SELECT id, target_kind, target_id, actor_id, created_at, started_at, ended_at, outcome, reason, protocol_recovery_round
|
|
258068
|
-
FROM ${this.d}.dispatches WHERE target_kind = $1 AND target_id = ANY($2) ORDER BY created_at ASC, id ASC LIMIT 1000`,
|
|
258069
|
-
[kind, capIds(targetIds)]
|
|
258070
|
-
);
|
|
258071
|
-
return rows.map(toDispatch);
|
|
258072
|
-
}
|
|
258073
|
-
async dispatchTargetOf(runId) {
|
|
258074
|
-
const rows = await this.q(`SELECT target_kind, target_id FROM ${this.d}.dispatches WHERE id = $1`, [runId]);
|
|
258075
|
-
const r5 = rows[0];
|
|
258076
|
-
return r5 ? { targetKind: String(r5["target_kind"]), targetId: String(r5["target_id"]) } : null;
|
|
258077
|
-
}
|
|
258078
|
-
/* ── 委派 ── */
|
|
258079
|
-
async getDelegation(id) {
|
|
258080
|
-
const rows = await this.q(`SELECT * FROM ${this.c}.chat_session_delegations WHERE id = $1`, [id]);
|
|
258081
|
-
return rows[0] ? toDelegation(rows[0]) : null;
|
|
258082
|
-
}
|
|
258083
|
-
async delegationByChildSession(childSessionId) {
|
|
258084
|
-
const rows = await this.q(`SELECT * FROM ${this.c}.chat_session_delegations WHERE child_session_id = $1`, [childSessionId]);
|
|
258085
|
-
return rows[0] ? toDelegation(rows[0]) : null;
|
|
258086
|
-
}
|
|
258087
|
-
async delegationsOfParent(parentSessionId, limit) {
|
|
258088
|
-
const rows = await this.q(
|
|
258089
|
-
`SELECT * FROM ${this.c}.chat_session_delegations WHERE parent_session_id = $1 ORDER BY created_at ASC, id ASC LIMIT $2`,
|
|
258090
|
-
[parentSessionId, limit]
|
|
258091
|
-
);
|
|
258092
|
-
return rows.map(toDelegation);
|
|
258093
|
-
}
|
|
258094
|
-
async touchesOf(delegationId) {
|
|
258095
|
-
const rows = await this.q(
|
|
258096
|
-
`SELECT delegation_id, message_id, kind, at FROM ${this.c}.chat_session_delegation_touches
|
|
258097
|
-
WHERE delegation_id = $1 ORDER BY at ASC LIMIT 500`,
|
|
258098
|
-
[delegationId]
|
|
258099
|
-
);
|
|
258100
|
-
return rows.map((r5) => ({
|
|
258101
|
-
delegationId: String(r5["delegation_id"]),
|
|
258102
|
-
messageId: String(r5["message_id"]),
|
|
258103
|
-
kind: String(r5["kind"]),
|
|
258104
|
-
at: isoReq(r5["at"])
|
|
258105
|
-
}));
|
|
258106
|
-
}
|
|
258107
|
-
/* ── 会话 / 轮次 / 消息 ── */
|
|
258108
|
-
async getSession(id) {
|
|
258109
|
-
const rows = await this.q(`SELECT * FROM ${this.c}.chat_sessions WHERE id = $1`, [id]);
|
|
258110
|
-
return rows[0] ? toSession(rows[0]) : null;
|
|
258111
|
-
}
|
|
258112
|
-
async getTurn(id) {
|
|
258113
|
-
const rows = await this.q(`SELECT * FROM ${this.c}.chat_session_turns WHERE id = $1`, [id]);
|
|
258114
|
-
return rows[0] ? toTurn(rows[0]) : null;
|
|
258115
|
-
}
|
|
258116
|
-
async turnsOfSession(sessionId, limit) {
|
|
258117
|
-
const rows = await this.q(
|
|
258118
|
-
`SELECT * FROM ${this.c}.chat_session_turns WHERE chat_session_id = $1 ORDER BY reserved_at DESC, id DESC LIMIT $2`,
|
|
258119
|
-
[sessionId, limit + 1]
|
|
258120
|
-
);
|
|
258121
|
-
const truncated = rows.length > limit;
|
|
258122
|
-
const turns = (truncated ? rows.slice(0, limit) : rows).map(toTurn).reverse();
|
|
258123
|
-
return { turns, truncated };
|
|
258124
|
-
}
|
|
258125
|
-
async getMessage(id) {
|
|
258126
|
-
const rows = await this.q(`SELECT * FROM ${this.c}.chat_messages WHERE id = $1`, [id]);
|
|
258127
|
-
return rows[0] ? toMessage(rows[0]) : null;
|
|
258128
|
-
}
|
|
258129
|
-
async messagesOf(sessionId, q4) {
|
|
258130
|
-
const args = [sessionId];
|
|
258131
|
-
const push2 = (v2) => {
|
|
258132
|
-
args.push(v2);
|
|
258133
|
-
return `$${args.length}`;
|
|
258134
|
-
};
|
|
258135
|
-
const conds = ["session_id = $1"];
|
|
258136
|
-
if (q4.turnIds) {
|
|
258137
|
-
const window3 = ["turn_id IS NULL"];
|
|
258138
|
-
if (q4.fromIso) window3.push(`created_at >= ${push2(q4.fromIso)}`);
|
|
258139
|
-
if (q4.toIso) window3.push(`created_at <= ${push2(q4.toIso)}`);
|
|
258140
|
-
conds.push(`(turn_id = ANY(${push2(capIds(q4.turnIds))}) OR (${window3.join(" AND ")}))`);
|
|
258141
|
-
} else {
|
|
258142
|
-
if (q4.fromIso) conds.push(`created_at >= ${push2(q4.fromIso)}`);
|
|
258143
|
-
if (q4.toIso) conds.push(`created_at <= ${push2(q4.toIso)}`);
|
|
258144
|
-
}
|
|
258145
|
-
if (q4.roles?.length) conds.push(`role = ANY(${push2(q4.roles)})`);
|
|
258146
|
-
const rows = await this.q(
|
|
258147
|
-
`SELECT id, session_id, role, content, seq, created_at, run_id, turn_id, source FROM ${this.c}.chat_messages
|
|
258148
|
-
WHERE ${conds.join(" AND ")} ORDER BY seq ASC LIMIT ${push2(q4.limit)}`,
|
|
258149
|
-
args
|
|
258150
|
-
);
|
|
258151
|
-
return rows.map(toMessage);
|
|
258152
|
-
}
|
|
258153
|
-
async pendingMessagesOf(sessionId, fromIso, toIso2, limit) {
|
|
258154
|
-
const rows = await this.q(
|
|
258155
|
-
`SELECT id, chat_session_id, text, created_at, state, flavour FROM ${this.c}.chat_pending_messages
|
|
258156
|
-
WHERE chat_session_id = $1 AND created_at >= $2 AND created_at <= $3 ORDER BY seq ASC LIMIT $4`,
|
|
258157
|
-
[sessionId, fromIso, toIso2, limit]
|
|
258158
|
-
);
|
|
258159
|
-
return rows.map((r5) => ({
|
|
258160
|
-
id: String(r5["id"]),
|
|
258161
|
-
chatSessionId: String(r5["chat_session_id"]),
|
|
258162
|
-
text: String(r5["text"] ?? ""),
|
|
258163
|
-
createdAt: isoReq(r5["created_at"]),
|
|
258164
|
-
state: str5(r5["state"]),
|
|
258165
|
-
flavour: str5(r5["flavour"])
|
|
258166
|
-
}));
|
|
258167
|
-
}
|
|
258168
|
-
async originLinksOfWorkorder(workorderId) {
|
|
258169
|
-
const rows = await this.q(
|
|
258170
|
-
`SELECT session_id, work_order_id, linked_at FROM ${this.c}.chat_session_work_orders
|
|
258171
|
-
WHERE work_order_id = $1 AND link_kind = 'origin' ORDER BY linked_at ASC LIMIT 20`,
|
|
258172
|
-
[workorderId]
|
|
258173
|
-
);
|
|
258174
|
-
return rows.map(toLink);
|
|
258175
|
-
}
|
|
258176
|
-
async originLinksOfSession(sessionId) {
|
|
258177
|
-
const rows = await this.q(
|
|
258178
|
-
`SELECT session_id, work_order_id, linked_at FROM ${this.c}.chat_session_work_orders
|
|
258179
|
-
WHERE session_id = $1 AND link_kind = 'origin' ORDER BY linked_at ASC LIMIT 200`,
|
|
258180
|
-
[sessionId]
|
|
258181
|
-
);
|
|
258182
|
-
return rows.map(toLink);
|
|
258183
|
-
}
|
|
258184
|
-
/* ── find / peers 候选 ── */
|
|
258185
|
-
async listEndedWorks(q4) {
|
|
258186
|
-
const args = [];
|
|
258187
|
-
const push2 = (v2) => {
|
|
258188
|
-
args.push(v2);
|
|
258189
|
-
return `$${args.length}`;
|
|
258190
|
-
};
|
|
258191
|
-
const conds = [`(w.ended_at IS NOT NULL OR w.dead_at IS NOT NULL)`, `w.acceptance_state IS DISTINCT FROM 'draft'`];
|
|
258192
|
-
if (q4.sinceIso) conds.push(`COALESCE(w.ended_at, w.dead_at) >= ${push2(q4.sinceIso)}`);
|
|
258193
|
-
if (q4.actorId) conds.push(`w.assignee_actor_id = ${push2(q4.actorId)}`);
|
|
258194
|
-
if (q4.nodeType) conds.push(`n.type = ${push2(q4.nodeType)}`);
|
|
258195
|
-
if (q4.lane) conds.push(`COALESCE(w.lane, CASE WHEN w.id LIKE 'wk:reply:%' THEN 'reply' ELSE 'main' END) = ${push2(q4.lane)}`);
|
|
258196
|
-
const rows = await this.q(
|
|
258197
|
-
`SELECT ${WORK_COLS} FROM ${this.e}.works w LEFT JOIN ${this.e}.workflow_nodes n ON n.id = w.node_id
|
|
258198
|
-
WHERE ${conds.join(" AND ")} ORDER BY COALESCE(w.ended_at, w.dead_at) DESC, w.id DESC LIMIT ${push2(q4.limit)}`,
|
|
258199
|
-
args
|
|
258200
|
-
);
|
|
258201
|
-
return rows.map(toWork);
|
|
258202
|
-
}
|
|
258203
|
-
async listEndedReviews(q4) {
|
|
258204
|
-
const args = [];
|
|
258205
|
-
const push2 = (v2) => {
|
|
258206
|
-
args.push(v2);
|
|
258207
|
-
return `$${args.length}`;
|
|
258208
|
-
};
|
|
258209
|
-
const endExpr = `COALESCE(r.ended_at, r.decided_at, r.cancelled_at, r.created_at)`;
|
|
258210
|
-
const conds = [`r.status IN ('accept','reject','failed','dead')`];
|
|
258211
|
-
if (q4.sinceIso) conds.push(`${endExpr} >= ${push2(q4.sinceIso)}`);
|
|
258212
|
-
if (q4.actorId) conds.push(`r.reviewer_actor_id = ${push2(q4.actorId)}`);
|
|
258213
|
-
const rows = await this.q(
|
|
258214
|
-
`SELECT ${REVIEW_COLS} FROM ${this.e}.reviews r LEFT JOIN ${this.e}.workflow_nodes n ON n.id = r.node_id
|
|
258215
|
-
WHERE ${conds.join(" AND ")} ORDER BY ${endExpr} DESC, r.id DESC LIMIT ${push2(q4.limit)}`,
|
|
258216
|
-
args
|
|
258217
|
-
);
|
|
258218
|
-
return rows.map(toReview);
|
|
258219
|
-
}
|
|
258220
|
-
async listEndedDelegations(q4) {
|
|
258221
|
-
const args = [];
|
|
258222
|
-
const push2 = (v2) => {
|
|
258223
|
-
args.push(v2);
|
|
258224
|
-
return `$${args.length}`;
|
|
258225
|
-
};
|
|
258226
|
-
const conds = [`state IN ('done','failed')`];
|
|
258227
|
-
if (q4.sinceIso) conds.push(`COALESCE(settled_at, created_at) >= ${push2(q4.sinceIso)}`);
|
|
258228
|
-
if (q4.actorId) conds.push(`expert_actor_id = ${push2(q4.actorId)}`);
|
|
258229
|
-
const rows = await this.q(
|
|
258230
|
-
`SELECT * FROM ${this.c}.chat_session_delegations WHERE ${conds.join(" AND ")}
|
|
258231
|
-
ORDER BY COALESCE(settled_at, created_at) DESC, id DESC LIMIT ${push2(q4.limit)}`,
|
|
258232
|
-
args
|
|
258233
|
-
);
|
|
258234
|
-
return rows.map(toDelegation);
|
|
258235
|
-
}
|
|
258236
|
-
async listRecentSessions(q4) {
|
|
258237
|
-
const args = [];
|
|
258238
|
-
const push2 = (v2) => {
|
|
258239
|
-
args.push(v2);
|
|
258240
|
-
return `$${args.length}`;
|
|
258241
|
-
};
|
|
258242
|
-
const conds = [`NOT EXISTS (SELECT 1 FROM ${this.c}.chat_session_delegations d WHERE d.child_session_id = s.id)`];
|
|
258243
|
-
if (!q4.includeAnalysis) conds.push(`s.analyzed_run_id IS NULL`);
|
|
258244
|
-
if (q4.sinceIso) conds.push(`s.touched_at >= ${push2(q4.sinceIso)}`);
|
|
258245
|
-
if (q4.aiActorId) conds.push(`s.ai_actor_id = ${push2(q4.aiActorId)}`);
|
|
258246
|
-
const rows = await this.q(
|
|
258247
|
-
`SELECT s.id, s.human_actor_id, s.ai_actor_id, s.title, s.analyzed_run_id, s.runtime_session_id, s.touched_at, s.created_at
|
|
258248
|
-
FROM ${this.c}.chat_sessions s WHERE ${conds.join(" AND ")} ORDER BY s.touched_at DESC, s.id DESC LIMIT ${push2(q4.limit)}`,
|
|
258249
|
-
args
|
|
258250
|
-
);
|
|
258251
|
-
return rows.map(toSession);
|
|
258252
|
-
}
|
|
258253
|
-
};
|
|
258254
|
-
}
|
|
258255
|
-
});
|
|
258256
|
-
|
|
258257
258346
|
// ../server/src/domains/trace/index.ts
|
|
258258
258347
|
function createTraceDomain(opts) {
|
|
258259
258348
|
const service = new TraceService({ store: opts.store });
|
|
@@ -261512,7 +261601,7 @@ function shown(field, v2, nameOf2) {
|
|
|
261512
261601
|
if (v2 === void 0 || v2 === "") return "\uFF08\u7A7A\uFF09";
|
|
261513
261602
|
if (field === "dueDate" || field === "startDate") return formatTodoDue(v2);
|
|
261514
261603
|
if (field === "assignee") return nameOf2(v2);
|
|
261515
|
-
return
|
|
261604
|
+
return clip4(v2);
|
|
261516
261605
|
}
|
|
261517
261606
|
function assignedTitle(who2, todo) {
|
|
261518
261607
|
return `${who2} \u6D3E\u7ED9\u4F60\uFF1A${todo.title}\uFF0C${formatTodoSpan(todo)}`;
|
|
@@ -261523,13 +261612,13 @@ function unseenTitle(assigneeName, todo) {
|
|
|
261523
261612
|
function changedTitle(who2, todo, changes, nameOf2) {
|
|
261524
261613
|
const parts = changes.map((c5) => `${FIELD_LABEL[c5.field] ?? c5.field} ${shown(c5.field, c5.oldValue, nameOf2)} \u2192 ${shown(c5.field, c5.newValue, nameOf2)}`);
|
|
261525
261614
|
const reason2 = changes.find((c5) => c5.reason)?.reason;
|
|
261526
|
-
return `${who2} \u6539\u4E86\u300C${todo.title}\u300D\uFF1A${parts.join("\uFF1B")}${reason2 ? `\uFF1B\u539F\u56E0\uFF1A${
|
|
261615
|
+
return `${who2} \u6539\u4E86\u300C${todo.title}\u300D\uFF1A${parts.join("\uFF1B")}${reason2 ? `\uFF1B\u539F\u56E0\uFF1A${clip4(reason2)}` : ""}`;
|
|
261527
261616
|
}
|
|
261528
261617
|
function statusTitle(who2, todo, kind, reason2, result) {
|
|
261529
261618
|
const verb = kind === "todo-done" ? "\u5B8C\u6210\u4E86" : kind === "todo-reopened" ? "\u91CD\u65B0\u6253\u5F00\u4E86" : "\u53D6\u6D88\u4E86";
|
|
261530
|
-
return `${who2} ${verb}\u300C${todo.title}\u300D${result ? `\uFF1B\u7ED3\u679C\uFF1A${
|
|
261619
|
+
return `${who2} ${verb}\u300C${todo.title}\u300D${result ? `\uFF1B\u7ED3\u679C\uFF1A${clip4(result)}` : ""}${reason2 ? `\uFF1B\u539F\u56E0\uFF1A${clip4(reason2)}` : ""}`;
|
|
261531
261620
|
}
|
|
261532
|
-
var VALUE_MAX, FIELD_LABEL,
|
|
261621
|
+
var VALUE_MAX, FIELD_LABEL, clip4, todoAssignedSourceKey, todoChangeSourceKey, todoUnseenSourceKey;
|
|
261533
261622
|
var init_notices = __esm({
|
|
261534
261623
|
"../server/src/domains/todos/notices.ts"() {
|
|
261535
261624
|
"use strict";
|
|
@@ -261546,7 +261635,7 @@ var init_notices = __esm({
|
|
|
261546
261635
|
assignee: "\u627F\u63A5\u4EBA",
|
|
261547
261636
|
result: "\u7ED3\u679C\u5728\u54EA"
|
|
261548
261637
|
};
|
|
261549
|
-
|
|
261638
|
+
clip4 = (v2) => v2.length > VALUE_MAX ? `${v2.slice(0, VALUE_MAX)}\u2026` : v2;
|
|
261550
261639
|
todoAssignedSourceKey = (todoId) => `todo:${todoId}@assigned`;
|
|
261551
261640
|
todoChangeSourceKey = (todoId, changeId) => `todo:${todoId}@change:${changeId}`;
|
|
261552
261641
|
todoUnseenSourceKey = (todo) => `todo:${todo.id}@unseen:${todo.dueDate}`;
|
|
@@ -327226,6 +327315,7 @@ __export(src_exports2, {
|
|
|
327226
327315
|
shouldInjectResumePack: () => shouldInjectResumePack,
|
|
327227
327316
|
shouldPush: () => shouldPush,
|
|
327228
327317
|
singlePushPayload: () => singlePushPayload,
|
|
327318
|
+
skillManifestForActor: () => skillManifestForActor,
|
|
327229
327319
|
skillsDirForRuntime: () => skillsDirForRuntime,
|
|
327230
327320
|
splitKnowledgeChunks: () => splitKnowledgeChunks,
|
|
327231
327321
|
stableChatTraceRunId: () => stableChatTraceRunId,
|
|
@@ -331029,6 +331119,18 @@ function skillContentHash(files) {
|
|
|
331029
331119
|
}
|
|
331030
331120
|
return `sha256:${h5.digest("hex")}`;
|
|
331031
331121
|
}
|
|
331122
|
+
function inMemorySkillFiles(skillId, pools) {
|
|
331123
|
+
const toFiles = (files) => Object.entries(files).map(([path50, content3]) => ({ path: path50, content: content3 }));
|
|
331124
|
+
if (skillId.startsWith("builtin:")) {
|
|
331125
|
+
const b6 = pools.builtins.find((x2) => `builtin:${x2.id}` === skillId);
|
|
331126
|
+
return b6 ? toFiles(b6.files) : null;
|
|
331127
|
+
}
|
|
331128
|
+
if (skillId.startsWith("connector:")) {
|
|
331129
|
+
const c5 = pools.connectorSkills.find((x2) => x2.id === skillId);
|
|
331130
|
+
return c5 ? toFiles(c5.files) : null;
|
|
331131
|
+
}
|
|
331132
|
+
return void 0;
|
|
331133
|
+
}
|
|
331032
331134
|
function scopedTrace(trace, scope2) {
|
|
331033
331135
|
if (scope2.companyScoped) return trace;
|
|
331034
331136
|
const allows = traceReadAllows(scope2);
|
|
@@ -331154,7 +331256,10 @@ ${f6.content}`).join("\n\n");
|
|
|
331154
331256
|
const svc = await exposureServiceFor(cid, await deps.traceStoreFor(cid), reflection);
|
|
331155
331257
|
await svc.recordDispatch({
|
|
331156
331258
|
runId: input.runId,
|
|
331157
|
-
skills: await deps.listSkills(cid, input.actorId, {
|
|
331259
|
+
skills: await deps.listSkills(cid, input.actorId, {
|
|
331260
|
+
builtins: input.builtins,
|
|
331261
|
+
...input.chatSessionId !== void 0 ? { chatSessionId: input.chatSessionId } : {}
|
|
331262
|
+
}),
|
|
331158
331263
|
memories: input.memories ? input.memories.map((m4) => ({ memId: m4.memId, version: m4.version })) : null
|
|
331159
331264
|
});
|
|
331160
331265
|
})().catch((e5) => log3(`[reflection] ${cid} chat run ${input.runId} \u57CB\u70B9\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u5BF9\u8BDD\uFF09\uFF1A${String(e5)}`));
|
|
@@ -334938,9 +335043,12 @@ async function startServe(opts) {
|
|
|
334938
335043
|
traceReadScopeFor: (cid) => traceReadScopeFor(cid),
|
|
334939
335044
|
blobStoreFor: (cid) => blobStoreFor(cid),
|
|
334940
335045
|
readBundleFile: (id, rel) => trajReader.readBundleFile(id, rel),
|
|
335046
|
+
// 与 `GET /api/skill-cache/manifest` 同一个函数、同一组参数(ADR 0641 §3.3):内置按会话 claim 投影
|
|
335047
|
+
//(管理者会话不给委派变体),连接器技能按该员工启用的 connector 门禁——节点拿到什么就记什么。
|
|
334941
335048
|
listSkills: async (cid, actorId, o3) => {
|
|
334942
335049
|
const { service } = await actors.resolveCtx(cid);
|
|
334943
|
-
|
|
335050
|
+
const builtins = o3.builtins ? await chatBuiltinSkillsForClaim(o3.chatSessionId ? { chatSessionId: o3.chatSessionId, companyId: cid } : void 0) : [];
|
|
335051
|
+
return skillManifestForActor({ service, actorId, builtins, connectorSkills });
|
|
334944
335052
|
},
|
|
334945
335053
|
readMemories: async (cid, actorId, memIds) => {
|
|
334946
335054
|
const svc = await actorMemoryFor(cid);
|
|
@@ -334957,11 +335065,8 @@ async function startServe(opts) {
|
|
|
334957
335065
|
return cfg ? { prompt: cfg.prompt ?? "", version: cfg.version } : null;
|
|
334958
335066
|
},
|
|
334959
335067
|
readSkillFiles: async (cid, skillId) => {
|
|
334960
|
-
|
|
334961
|
-
|
|
334962
|
-
return b6 ? Object.entries(b6.files).map(([path50, content3]) => ({ path: path50, content: content3 })) : null;
|
|
334963
|
-
}
|
|
334964
|
-
if (skillId.startsWith("connector:")) return null;
|
|
335068
|
+
const mem = inMemorySkillFiles(skillId, { builtins: effectiveBuiltinSkills(), connectorSkills });
|
|
335069
|
+
if (mem !== void 0) return mem;
|
|
334965
335070
|
const files = await (await actors.resolveCtx(cid)).service.listSkillFiles(skillId).catch(() => []);
|
|
334966
335071
|
return files.length ? files.map((f6) => ({ path: f6.path, content: f6.content })) : null;
|
|
334967
335072
|
},
|
|
@@ -336475,6 +336580,7 @@ async function startServe(opts) {
|
|
|
336475
336580
|
actorId,
|
|
336476
336581
|
turnId: chatTurnId,
|
|
336477
336582
|
builtins: !isolatedBackground,
|
|
336583
|
+
...chatSessionId !== void 0 ? { chatSessionId } : {},
|
|
336478
336584
|
memories: chatInjectedMemories,
|
|
336479
336585
|
files: { ...files },
|
|
336480
336586
|
systemPromptFingerprint: null
|
|
@@ -343820,18 +343926,24 @@ var COMMAND_DECLS = {
|
|
|
343820
343926
|
},
|
|
343821
343927
|
"trace outcome": {
|
|
343822
343928
|
group: "\u6267\u884C\u8BB0\u5F55\uFF08trace\uFF09",
|
|
343823
|
-
usage: "oasis trace outcome <unit> [--json]",
|
|
343824
|
-
description: "\u539F\u59CB\u7ED3\u679C\u4FE1\u53F7\uFF08\u72B6\u6001\u3001\u9A8C\u6536\u3001\u8BC4\u5BA1 verdict \u4E0E note\u3001issue\u3001\u8FD4\u5DE5\u3001\u5F3A\u5236\u901A\u8FC7\u3001\u53EB\u505C\u3001\u63D2\u8BDD\u3001\u8FFD\u95EE\u2026\u2026\uFF09\uFF0C\u5E73\u53F0\u4E0D\u4E0B\u7ED3\u8BBA\uFF0C\u6027\u8D28\u7531\u4F60\u5224\u65AD\u3002",
|
|
343929
|
+
usage: "oasis trace outcome <unit> [--full] [--json]",
|
|
343930
|
+
description: "\u539F\u59CB\u7ED3\u679C\u4FE1\u53F7\uFF08\u72B6\u6001\u3001\u9A8C\u6536\u3001\u8BC4\u5BA1 verdict \u4E0E note\u3001issue\u3001\u8FD4\u5DE5\u3001\u5F3A\u5236\u901A\u8FC7\u3001\u53EB\u505C\u3001\u63D2\u8BDD\u3001\u8FFD\u95EE\u2026\u2026\uFF09\uFF0C\u5E73\u53F0\u4E0D\u4E0B\u7ED3\u8BBA\uFF0C\u6027\u8D28\u7531\u4F60\u5224\u65AD\u3002issue / \u63D2\u8BDD / \u8FFD\u95EE\u539F\u6587\u8FC7\u957F\u65F6\u622A\u65AD\u5E76\u5E26 `[\u5DF2\u7701\u7565 N \u5B57 \u2192 oasis trace outcome <unit> --full]`\u3002",
|
|
343825
343931
|
positional: [{ name: "<unit>", required: true, desc: "\u5355\u5143 id \u6216 run id" }],
|
|
343826
|
-
flags: [
|
|
343932
|
+
flags: [
|
|
343933
|
+
{ name: "full", desc: "\u957F\u6587\u672C\u4E0D\u622A\u65AD", boolean: true, own: true },
|
|
343934
|
+
{ name: "json", desc: "\u8F93\u51FA\u5951\u7EA6 JSON", boolean: true, own: true }
|
|
343935
|
+
],
|
|
343827
343936
|
examples: ["oasis trace outcome dlg:7f2c"]
|
|
343828
343937
|
},
|
|
343829
343938
|
"trace exogenous": {
|
|
343830
343939
|
group: "\u6267\u884C\u8BB0\u5F55\uFF08trace\uFF09",
|
|
343831
|
-
usage: "oasis trace exogenous <unit> [--json]",
|
|
343832
|
-
description: "\u5916\u90E8\u56E0\u7D20\u4E8B\u5B9E\uFF1Arun \u8D85\u65F6 / \u88AB\u6740 / \u5931\u8054\u3001\u767B\u5F55\u5931\u6548\u4E0E\u989D\u5EA6\u4E00\u7C7B\u9519\u8BEF\u7801\u3001\u6362\u673A\u3001\u7CFB\u7EDF\u539F\u56E0\u7684\u53EB\u505C\u3001\u534F\u8BAE\u6062\u590D\u3001\u4E0A\u6E38 issue\u3001\u6267\u884C\u671F\u95F4\u9700\u6C42\u53D8\u4E86\u3002\u53CD\u601D\u65F6\u5148\u770B\u5B83\uFF0C\u5C5E\u4E8E\u5916\u90E8\u539F\u56E0\u7684\u6539\u8FDB\u70B9\u6807 category=external\u3002",
|
|
343940
|
+
usage: "oasis trace exogenous <unit> [--full] [--json]",
|
|
343941
|
+
description: "\u5916\u90E8\u56E0\u7D20\u4E8B\u5B9E\uFF1Arun \u8D85\u65F6 / \u88AB\u6740 / \u5931\u8054\u3001\u767B\u5F55\u5931\u6548\u4E0E\u989D\u5EA6\u4E00\u7C7B\u9519\u8BEF\u7801\u3001\u6362\u673A\u3001\u7CFB\u7EDF\u539F\u56E0\u7684\u53EB\u505C\u3001\u534F\u8BAE\u6062\u590D\u3001\u4E0A\u6E38 issue\u3001\u6267\u884C\u671F\u95F4\u9700\u6C42\u53D8\u4E86\u3002\u53CD\u601D\u65F6\u5148\u770B\u5B83\uFF0C\u5C5E\u4E8E\u5916\u90E8\u539F\u56E0\u7684\u6539\u8FDB\u70B9\u6807 category=external\u3002\u6BCF\u6761\u4E8B\u5B9E\u4E0B\u65B9\u7F29\u8FDB\u6253\u51FA run \u7684\u9519\u8BEF\u4FE1\u606F\u4E0E\u4E0A\u6E38 issue \u6B63\u6587\uFF1B\u8FC7\u957F\u65F6\u622A\u65AD\u5E76\u5E26 `[\u5DF2\u7701\u7565 N \u5B57 \u2192 oasis trace exogenous <unit> --full]`\uFF0C\u52A0 --full \u6253\u51FA\u5168\u6587\u3002",
|
|
343833
343942
|
positional: [{ name: "<unit>", required: true, desc: "\u5355\u5143 id \u6216 run id" }],
|
|
343834
|
-
flags: [
|
|
343943
|
+
flags: [
|
|
343944
|
+
{ name: "full", desc: "\u957F\u6587\u672C\u4E0D\u622A\u65AD", boolean: true, own: true },
|
|
343945
|
+
{ name: "json", desc: "\u8F93\u51FA\u5951\u7EA6 JSON", boolean: true, own: true }
|
|
343946
|
+
],
|
|
343835
343947
|
examples: ["oasis trace exogenous wk:n-abc:2"]
|
|
343836
343948
|
},
|
|
343837
343949
|
"trace runs": {
|
|
@@ -344881,6 +344993,7 @@ function buildTraceRequest(sub, positional, flags, now = Date.now()) {
|
|
|
344881
344993
|
return { method: "GET", path: `${unitPath("brief")}${qs({ budget: intFlag(flags, "budget", 6e3, 1) })}` };
|
|
344882
344994
|
case "outcome":
|
|
344883
344995
|
case "exogenous":
|
|
344996
|
+
return { method: "GET", path: `${unitPath(sub)}${qs({ full: on(flags, "full") ? 1 : void 0 })}` };
|
|
344884
344997
|
case "runs":
|
|
344885
344998
|
return { method: "GET", path: unitPath(sub) };
|
|
344886
344999
|
case "events": {
|
|
@@ -344948,6 +345061,9 @@ var fmtMs = (ms2) => {
|
|
|
344948
345061
|
return s3 < 120 ? `${s3}s` : `${Math.round(s3 / 60)}min`;
|
|
344949
345062
|
};
|
|
344950
345063
|
var scalar = (v2) => typeof v2 === "string" ? v2 : JSON.stringify(v2);
|
|
345064
|
+
var isTruncatedField = (v2) => typeof v2 === "object" && v2 !== null && typeof v2.text === "string" && typeof v2.truncated === "boolean" && typeof v2.fullChars === "number";
|
|
345065
|
+
var EXOGENOUS_TEXT_LABELS = { errorMessage: "\u9519\u8BEF\u4FE1\u606F", body: "\u6B63\u6587" };
|
|
345066
|
+
var EXOGENOUS_TEXT_INDENT = " ";
|
|
344951
345067
|
function renderEventPreview(e5, opts = {}) {
|
|
344952
345068
|
const head = `#${e5.seq} [${e5.eventType}] ${e5.kind}${e5.toolName ? ` ${e5.toolName}` : ""}${e5.level === "error" ? " \u26A0error" : ""}`;
|
|
344953
345069
|
const tail = e5.ingestTruncated ? " [\u5165\u5E93\u524D\u5DF2\u88AB\u9002\u914D\u5668\u622A\u65AD\uFF0C\u539F\u6837\u7ED9\u51FA]" : "";
|
|
@@ -344986,7 +345102,14 @@ function renderTrace(sub, data, flags, println) {
|
|
|
344986
345102
|
return;
|
|
344987
345103
|
}
|
|
344988
345104
|
println(`${r5.unitId} \u7684\u5916\u90E8\u56E0\u7D20\uFF08${r5.facts.length} \u6761\uFF09\uFF1A`);
|
|
344989
|
-
for (const f6 of r5.facts)
|
|
345105
|
+
for (const f6 of r5.facts) {
|
|
345106
|
+
println(` [${f6.kind}] ${orDash(f6.at)}${f6.runId ? ` ${f6.runId}` : ""} ${oneLine3(f6.summary)}`);
|
|
345107
|
+
for (const [k6, v2] of Object.entries(f6.detail ?? {})) {
|
|
345108
|
+
if (!isTruncatedField(v2)) continue;
|
|
345109
|
+
println(` ${EXOGENOUS_TEXT_LABELS[k6] ?? k6}\uFF08\u5171 ${v2.fullChars} \u5B57${v2.truncated ? `\uFF0C\u5DF2\u622A\u65AD\uFF0C\u53D6\u5168\u6587\uFF1A${v2.fetchCmd}` : ""}\uFF09\uFF1A`);
|
|
345110
|
+
println(v2.text.replace(/^/gm, EXOGENOUS_TEXT_INDENT));
|
|
345111
|
+
}
|
|
345112
|
+
}
|
|
344990
345113
|
return;
|
|
344991
345114
|
}
|
|
344992
345115
|
case "runs": {
|
|
@@ -345915,7 +346038,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback2) {
|
|
|
345915
346038
|
}
|
|
345916
346039
|
}
|
|
345917
346040
|
}
|
|
345918
|
-
var CLI_VERSION = "2.2.
|
|
346041
|
+
var CLI_VERSION = "2.2.127" ? "2.2.127" : "dev";
|
|
345919
346042
|
function apiHeaders(token2, company) {
|
|
345920
346043
|
const headers = {
|
|
345921
346044
|
authorization: `Bearer ${token2}`,
|
|
@@ -346721,16 +346844,17 @@ ${round.text}`);
|
|
|
346721
346844
|
{ to, task, ...flags.get("as") ? { as: flags.get("as") } : {}, ...fileArgs.length ? { files: fileArgs } : {} }
|
|
346722
346845
|
);
|
|
346723
346846
|
if (asJson2) {
|
|
346724
|
-
const
|
|
346725
|
-
println(JSON.stringify({ ...started, ...
|
|
346847
|
+
const overlap2 = await overlapLines("delegate", task, started.delegationId);
|
|
346848
|
+
println(JSON.stringify({ ...started, ...overlap2.length ? { overlap: overlap2 } : {} }, null, 2));
|
|
346726
346849
|
break;
|
|
346727
346850
|
}
|
|
346728
346851
|
println(`\u5DF2\u4EA4\u7ED9 ${to} \u53BB\u505A\uFF08\u5F02\u6B65\uFF0C\u4E0D\u7528\u7B49\uFF09\u3002`);
|
|
346729
346852
|
println(` \u77ED\u540D\uFF08--follow-up \u7528\u8FD9\u4E2A\uFF09\uFF1A${started.label}`);
|
|
346730
346853
|
println(` delegationId\uFF1A${started.delegationId}`);
|
|
346731
346854
|
if (started.attachedFiles?.length) println(` \u5E26\u8FC7\u53BB\u7684\u6587\u4EF6\uFF1A${started.attachedFiles.join("\u3001")}`);
|
|
346732
|
-
|
|
346733
|
-
|
|
346855
|
+
const overlap = await overlapLines("delegate", task, started.delegationId);
|
|
346856
|
+
for (const line2 of overlap) println(line2);
|
|
346857
|
+
println(overlap.length ? "\u7ED3\u679C\u5E72\u5B8C\u4E86\u4F1A\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\u3002\u6536\u5C3E\u524D\u5148\u6309\u4E0A\u9762\u300C\u76F8\u8FD1\u7684\u4E8B\u9879\u300D\u9010\u6761\u67E5\u5B8C\uFF08\u786E\u5B9E\u76F8\u5173\u624D\u987A\u5E26\u544A\u8BC9\u7528\u6237\uFF09\uFF0C\u7136\u540E\u8FD9\u4E00\u8F6E\u5C31\u6536\u5C3E\u2014\u2014\u4E0D\u7528\u7B49\u4E13\u5BB6\u3002" : "\u7ED3\u679C\u5E72\u5B8C\u4E86\u4F1A\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\u3002\u8FD9\u4E00\u8F6E\u5148\u6536\u5C3E\u2014\u2014\u53EF\u4EE5\u987A\u624B\u8DDF\u7528\u6237\u8BF4\u4E00\u53E5\u4F60\u628A\u8FD9\u4EF6\u4E8B\u6D3E\u51FA\u53BB\u4E86\u3002");
|
|
346734
346858
|
break;
|
|
346735
346859
|
}
|
|
346736
346860
|
case "kb": {
|
|
@@ -350228,7 +350352,7 @@ function shimScript() {
|
|
|
350228
350352
|
}
|
|
350229
350353
|
|
|
350230
350354
|
// src/index.ts
|
|
350231
|
-
var PKG_VERSION = true ? "2.2.
|
|
350355
|
+
var PKG_VERSION = true ? "2.2.127" : "dev";
|
|
350232
350356
|
var LOCAL_BIN = localBin();
|
|
350233
350357
|
var NPM_PREFIX = npmPrefix();
|
|
350234
350358
|
var INSTANCE = DEFAULT_INSTANCE;
|