oasis_test_v2 2.2.83 → 2.2.85
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 +524 -86
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1347,6 +1347,21 @@ function actualModelId(model) {
|
|
|
1347
1347
|
if (!t) return void 0;
|
|
1348
1348
|
return isPseudoModelId(t) ? void 0 : t;
|
|
1349
1349
|
}
|
|
1350
|
+
function modelSourceRank(model, source) {
|
|
1351
|
+
if (!actualModelId(model)) return -1;
|
|
1352
|
+
return source ? MODEL_SOURCE_RANK[source] ?? 1 : 1;
|
|
1353
|
+
}
|
|
1354
|
+
function preferRunModel(existing, incoming, tie = "keep") {
|
|
1355
|
+
const incomingModel = actualModelId(incoming.effectiveModel);
|
|
1356
|
+
if (!incomingModel) return null;
|
|
1357
|
+
const existingRank = modelSourceRank(existing.effectiveModel, existing.modelSource);
|
|
1358
|
+
const incomingRank = modelSourceRank(incomingModel, incoming.modelSource);
|
|
1359
|
+
if (incomingRank > existingRank) return { effectiveModel: incomingModel, modelSource: incoming.modelSource ?? null };
|
|
1360
|
+
if (incomingRank === existingRank && tie === "replace") {
|
|
1361
|
+
return { effectiveModel: incomingModel, modelSource: incoming.modelSource ?? null };
|
|
1362
|
+
}
|
|
1363
|
+
return null;
|
|
1364
|
+
}
|
|
1350
1365
|
function legacyScopeIsEmpty(scope2) {
|
|
1351
1366
|
return scope2.artifactIds.length === 0 && scope2.chatSessionIds.length === 0 && (scope2.runtimeInstanceIds?.length ?? 0) === 0;
|
|
1352
1367
|
}
|
|
@@ -1356,11 +1371,20 @@ function legacyScopeMatcher(scope2) {
|
|
|
1356
1371
|
const runtimes = new Set(scope2.runtimeInstanceIds ?? []);
|
|
1357
1372
|
return (run) => run.artifactId != null && artifacts.has(run.artifactId) || run.chatSessionId != null && sessions.has(run.chatSessionId) || run.runtimeInstanceId != null && runtimes.has(run.runtimeInstanceId);
|
|
1358
1373
|
}
|
|
1359
|
-
var PSEUDO_MODEL_IDS, DISPLAY_CNY_PER_USD, USAGE_POINT_FINAL_SEQ;
|
|
1374
|
+
var PSEUDO_MODEL_IDS, MODEL_SOURCE_RANK, DISPLAY_CNY_PER_USD, USAGE_POINT_FINAL_SEQ;
|
|
1360
1375
|
var init_trace = __esm({
|
|
1361
1376
|
"../contract/src/trace.ts"() {
|
|
1362
1377
|
"use strict";
|
|
1363
1378
|
PSEUDO_MODEL_IDS = ["default", "default[]", "auto"];
|
|
1379
|
+
MODEL_SOURCE_RANK = {
|
|
1380
|
+
runtime: 2,
|
|
1381
|
+
runtime_rollout: 2,
|
|
1382
|
+
requested: 1,
|
|
1383
|
+
session_override: 1,
|
|
1384
|
+
actor_config: 1,
|
|
1385
|
+
runtime_default: 1,
|
|
1386
|
+
unknown: 0
|
|
1387
|
+
};
|
|
1364
1388
|
DISPLAY_CNY_PER_USD = 7.2;
|
|
1365
1389
|
USAGE_POINT_FINAL_SEQ = 2147483647;
|
|
1366
1390
|
}
|
|
@@ -2953,6 +2977,7 @@ async function fetchResultPackage(base, fetchImpl, runId) {
|
|
|
2953
2977
|
function toEpochMs(v2) {
|
|
2954
2978
|
if (typeof v2 === "number" && Number.isFinite(v2)) return v2;
|
|
2955
2979
|
if (typeof v2 === "string" && v2.length > 0) {
|
|
2980
|
+
if (/^\d+(\.\d+)?$/.test(v2.trim())) return Number(v2.trim());
|
|
2956
2981
|
const ms = Date.parse(v2);
|
|
2957
2982
|
return Number.isNaN(ms) ? void 0 : ms;
|
|
2958
2983
|
}
|
|
@@ -2969,6 +2994,98 @@ function latestSucceededRun(runs) {
|
|
|
2969
2994
|
}
|
|
2970
2995
|
return best;
|
|
2971
2996
|
}
|
|
2997
|
+
function liveBoardRuns(st) {
|
|
2998
|
+
const out = [];
|
|
2999
|
+
const known = /* @__PURE__ */ new Set();
|
|
3000
|
+
for (const t of st.turns ?? []) {
|
|
3001
|
+
if (t.runId !== null) known.add(t.runId);
|
|
3002
|
+
if (isTerminalRunStatus(t.status)) continue;
|
|
3003
|
+
out.push({ key: t.runId ?? `msg:${t.messageId ?? "?"}`, status: t.status, ...t.agentId ? { agentId: t.agentId } : {}, source: "conversation" });
|
|
3004
|
+
}
|
|
3005
|
+
for (const r of st.runs) {
|
|
3006
|
+
if (known.has(r.runId) || r.runId.length === 0) continue;
|
|
3007
|
+
if (r.status !== "running" && r.status !== "queued") continue;
|
|
3008
|
+
out.push({ key: r.runId, status: r.status, ...r.agentId ? { agentId: r.agentId } : {}, source: "registry" });
|
|
3009
|
+
}
|
|
3010
|
+
return out;
|
|
3011
|
+
}
|
|
3012
|
+
function latestEndedRun(st) {
|
|
3013
|
+
let best;
|
|
3014
|
+
for (const t of st.turns ?? []) {
|
|
3015
|
+
if (!isTerminalRunStatus(t.status)) continue;
|
|
3016
|
+
if (best === void 0 || (t.endedAt ?? Number.NEGATIVE_INFINITY) > (best.endedAt ?? Number.NEGATIVE_INFINITY)) best = t;
|
|
3017
|
+
}
|
|
3018
|
+
if (best) return { runId: best.runId, status: best.status, ...best.agentId ? { agentId: best.agentId } : {}, ...best.error ? { error: best.error } : {} };
|
|
3019
|
+
const r = st.runs.find((x2) => isTerminalRunStatus(x2.status));
|
|
3020
|
+
return r ? { runId: r.runId, status: r.status, ...r.agentId ? { agentId: r.agentId } : {}, ...r.error ? { error: r.error } : {} } : void 0;
|
|
3021
|
+
}
|
|
3022
|
+
function snapshotSourceRunId(st) {
|
|
3023
|
+
let best;
|
|
3024
|
+
for (const t of st.turns ?? []) {
|
|
3025
|
+
if (t.status !== "succeeded" || t.runId === null) continue;
|
|
3026
|
+
if (best === void 0 || (t.endedAt ?? Number.NEGATIVE_INFINITY) > (best.endedAt ?? Number.NEGATIVE_INFINITY)) best = t;
|
|
3027
|
+
}
|
|
3028
|
+
return best?.runId ?? latestSucceededRun(st.runs)?.runId;
|
|
3029
|
+
}
|
|
3030
|
+
function nonEmptyStr(v2) {
|
|
3031
|
+
return typeof v2 === "string" && v2.trim().length > 0 ? v2 : void 0;
|
|
3032
|
+
}
|
|
3033
|
+
function turnError(m2, status) {
|
|
3034
|
+
const events = Array.isArray(m2["events"]) ? m2["events"] : [];
|
|
3035
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
3036
|
+
const e = events[i];
|
|
3037
|
+
if (!e || typeof e !== "object") continue;
|
|
3038
|
+
const ev = e;
|
|
3039
|
+
if (ev["kind"] === "status" && ev["label"] === "error" && nonEmptyStr(ev["detail"])) return ev["detail"];
|
|
3040
|
+
}
|
|
3041
|
+
return status !== "succeeded" && isTerminalRunStatus(status) ? nonEmptyStr(m2["content"]) : void 0;
|
|
3042
|
+
}
|
|
3043
|
+
async function fetchBoardTurns(base, fetchImpl, boardKey) {
|
|
3044
|
+
const convPath = `/api/projects/${encodeURIComponent(boardKey)}/conversations`;
|
|
3045
|
+
const guard = (err) => {
|
|
3046
|
+
if (err instanceof OdHttpError && (err.status === 401 || err.status === 403)) throw err;
|
|
3047
|
+
return null;
|
|
3048
|
+
};
|
|
3049
|
+
let convs;
|
|
3050
|
+
try {
|
|
3051
|
+
convs = (await odApi(base, fetchImpl, "GET", convPath)).conversations ?? [];
|
|
3052
|
+
} catch (err) {
|
|
3053
|
+
if (err instanceof OdHttpError && err.status === 404) return [];
|
|
3054
|
+
return guard(err);
|
|
3055
|
+
}
|
|
3056
|
+
const turns = [];
|
|
3057
|
+
for (const c of convs) {
|
|
3058
|
+
const cid = nonEmptyStr(c["id"]);
|
|
3059
|
+
if (cid === void 0) continue;
|
|
3060
|
+
let msgs;
|
|
3061
|
+
try {
|
|
3062
|
+
msgs = (await odApi(base, fetchImpl, "GET", `${convPath}/${encodeURIComponent(cid)}/messages`)).messages ?? [];
|
|
3063
|
+
} catch (err) {
|
|
3064
|
+
if (err instanceof OdHttpError && err.status === 404) continue;
|
|
3065
|
+
return guard(err);
|
|
3066
|
+
}
|
|
3067
|
+
for (const m2 of msgs) {
|
|
3068
|
+
if (!m2 || typeof m2 !== "object" || m2["role"] !== "assistant") continue;
|
|
3069
|
+
const status = nonEmptyStr(m2["runStatus"]);
|
|
3070
|
+
if (status === void 0) continue;
|
|
3071
|
+
const runId = nonEmptyStr(m2["runId"]) ?? null;
|
|
3072
|
+
const messageId = nonEmptyStr(m2["id"]) ?? null;
|
|
3073
|
+
if (runId === null && messageId === null) continue;
|
|
3074
|
+
const turn = { conversationId: cid, runId, messageId, status };
|
|
3075
|
+
const agentId = nonEmptyStr(m2["agentId"]);
|
|
3076
|
+
if (agentId) turn.agentId = agentId;
|
|
3077
|
+
const error2 = turnError(m2, status);
|
|
3078
|
+
if (error2) turn.error = error2;
|
|
3079
|
+
const startedAt = toEpochMs(m2["startedAt"]) ?? toEpochMs(m2["createdAt"]);
|
|
3080
|
+
if (startedAt !== void 0) turn.startedAt = startedAt;
|
|
3081
|
+
const endedAt = toEpochMs(m2["endedAt"]);
|
|
3082
|
+
if (endedAt !== void 0) turn.endedAt = endedAt;
|
|
3083
|
+
turns.push(turn);
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
turns.sort((a, b2) => (b2.startedAt ?? Number.NEGATIVE_INFINITY) - (a.startedAt ?? Number.NEGATIVE_INFINITY) || 0);
|
|
3087
|
+
return turns;
|
|
3088
|
+
}
|
|
2972
3089
|
async function fetchBoardStatus(base, fetchImpl, artifactId) {
|
|
2973
3090
|
const boardKey = deriveBoardKey(artifactId);
|
|
2974
3091
|
let boardExists = true;
|
|
@@ -3011,7 +3128,31 @@ async function fetchBoardStatus(base, fetchImpl, artifactId) {
|
|
|
3011
3128
|
} catch {
|
|
3012
3129
|
}
|
|
3013
3130
|
}
|
|
3014
|
-
|
|
3131
|
+
const turns = boardExists ? await fetchBoardTurns(base, fetchImpl, boardKey) : [];
|
|
3132
|
+
return { boardKey, boardExists, runs, turns, artifacts };
|
|
3133
|
+
}
|
|
3134
|
+
async function waitBoardSettled(base, fetchImpl, artifactId, opts = {}) {
|
|
3135
|
+
const interval = opts.intervalMs ?? 2e4;
|
|
3136
|
+
const timeout = opts.timeoutMs ?? 100 * 6e4;
|
|
3137
|
+
const sleep6 = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
3138
|
+
const now = opts.now ?? Date.now;
|
|
3139
|
+
const started = now();
|
|
3140
|
+
let lastKey = null;
|
|
3141
|
+
let waited = false;
|
|
3142
|
+
for (; ; ) {
|
|
3143
|
+
const st = await fetchBoardStatus(base, fetchImpl, artifactId);
|
|
3144
|
+
const elapsedMs = now() - started;
|
|
3145
|
+
if (!st.boardExists) return { status: st, settled: true, waited, live: [], elapsedMs };
|
|
3146
|
+
const live = liveBoardRuns(st);
|
|
3147
|
+
const unreadable = st.turns === null;
|
|
3148
|
+
if (live.length === 0 && !unreadable) return { status: st, settled: true, waited, live, elapsedMs };
|
|
3149
|
+
const key2 = unreadable && live.length === 0 ? "?" : live.map((r) => `${r.key}=${r.status}`).sort().join(",");
|
|
3150
|
+
opts.onPoll?.({ live, elapsedMs, changed: key2 !== lastKey, unreadable });
|
|
3151
|
+
lastKey = key2;
|
|
3152
|
+
if (elapsedMs >= timeout) return { status: st, settled: false, waited: true, live, elapsedMs };
|
|
3153
|
+
waited = true;
|
|
3154
|
+
await sleep6(Math.min(interval, Math.max(0, timeout - elapsedMs)));
|
|
3155
|
+
}
|
|
3015
3156
|
}
|
|
3016
3157
|
async function pumpDesignEvents(base, fetchImpl, runId, onLine) {
|
|
3017
3158
|
const res = await fetchImpl(`${base}/api/runs/${runId}/events`);
|
|
@@ -3080,16 +3221,25 @@ async function harvestBoard(base, fetchImpl, publicBase, workRoot, boardKey, run
|
|
|
3080
3221
|
}
|
|
3081
3222
|
}
|
|
3082
3223
|
}
|
|
3083
|
-
fs2.writeFileSync(
|
|
3084
|
-
path2.join(dir, "board.link"),
|
|
3085
|
-
`${publicBase}/projects/${boardKey}
|
|
3086
|
-
\u5165\u53E3\u7A3F\uFF1A${entry}
|
|
3087
|
-
\u5FEB\u7167\u6765\u6E90 run\uFF1A${runId}
|
|
3088
|
-
\uFF08\u6D3B\u753B\u677F\u2014\u2014\u7EE7\u7EED\u8FED\u4EE3\u8BF7\u56DE\u5230\u8BE5\u9879\u76EE\uFF1B\u672C\u88C5\u7BB1\u5355\u4E3A\u8BE5\u6B21\u4EA4\u4ED8\u7684\u51BB\u7ED3\u5FEB\u7167\uFF09
|
|
3089
|
-
`
|
|
3090
|
-
);
|
|
3224
|
+
fs2.writeFileSync(path2.join(dir, BOARD_LINK_FILE), formatBoardLink({ publicBase, boardKey, entry, runId }));
|
|
3091
3225
|
return { dir, entry };
|
|
3092
3226
|
}
|
|
3227
|
+
function formatBoardLink(args) {
|
|
3228
|
+
return `${args.publicBase}/projects/${args.boardKey}
|
|
3229
|
+
\u5165\u53E3\u7A3F\uFF1A${args.entry}
|
|
3230
|
+
${SOURCE_RUN_LABEL}${args.runId}
|
|
3231
|
+
\uFF08\u6D3B\u753B\u677F\u2014\u2014\u7EE7\u7EED\u8FED\u4EE3\u8BF7\u56DE\u5230\u8BE5\u9879\u76EE\uFF1B\u672C\u88C5\u7BB1\u5355\u4E3A\u8BE5\u6B21\u4EA4\u4ED8\u7684\u51BB\u7ED3\u5FEB\u7167\uFF09
|
|
3232
|
+
`;
|
|
3233
|
+
}
|
|
3234
|
+
function parseBoardLinkSourceRun(text7) {
|
|
3235
|
+
for (const line2 of text7.split(/\r?\n/)) {
|
|
3236
|
+
const t = line2.trim();
|
|
3237
|
+
if (!t.startsWith(SOURCE_RUN_LABEL)) continue;
|
|
3238
|
+
const id = t.slice(SOURCE_RUN_LABEL.length).trim();
|
|
3239
|
+
return id.length > 0 && id !== UNKNOWN_SOURCE_RUN ? id : null;
|
|
3240
|
+
}
|
|
3241
|
+
return null;
|
|
3242
|
+
}
|
|
3093
3243
|
async function startDesignChatTurn(opts) {
|
|
3094
3244
|
const fetchImpl = withOdToken(opts.fetchImpl ?? fetch, opts.token);
|
|
3095
3245
|
const boardKey = deriveBoardKey(opts.artifactId);
|
|
@@ -3119,7 +3269,7 @@ async function runDesignChatTurn(opts) {
|
|
|
3119
3269
|
const { artifacts, fileCount } = await fetchResultPackage(opts.base, fetchImpl, runId);
|
|
3120
3270
|
return { boardKey, conversationId, runId, userMessageId, artifacts, fileCount };
|
|
3121
3271
|
}
|
|
3122
|
-
var import_node_crypto2, fs2, path2, OdHttpError, TASK_CONTEXT_DIR;
|
|
3272
|
+
var import_node_crypto2, fs2, path2, OdHttpError, TASK_CONTEXT_DIR, TERMINAL_TURN_STATUS, isTerminalRunStatus, BOARD_LINK_FILE, SOURCE_RUN_LABEL, UNKNOWN_SOURCE_RUN;
|
|
3123
3273
|
var init_driver = __esm({
|
|
3124
3274
|
"../adapters/src/open-design/driver.ts"() {
|
|
3125
3275
|
"use strict";
|
|
@@ -3133,6 +3283,11 @@ var init_driver = __esm({
|
|
|
3133
3283
|
}
|
|
3134
3284
|
};
|
|
3135
3285
|
TASK_CONTEXT_DIR = "task-context/";
|
|
3286
|
+
TERMINAL_TURN_STATUS = /* @__PURE__ */ new Set(["succeeded", "failed", "canceled", "cancelled"]);
|
|
3287
|
+
isTerminalRunStatus = (s2) => TERMINAL_TURN_STATUS.has(s2);
|
|
3288
|
+
BOARD_LINK_FILE = "board.link";
|
|
3289
|
+
SOURCE_RUN_LABEL = "\u5FEB\u7167\u6765\u6E90 run\uFF1A";
|
|
3290
|
+
UNKNOWN_SOURCE_RUN = "status-pull";
|
|
3136
3291
|
}
|
|
3137
3292
|
});
|
|
3138
3293
|
|
|
@@ -8506,14 +8661,46 @@ async function runACPSession(job, cfg) {
|
|
|
8506
8661
|
let runtimeReportedModel;
|
|
8507
8662
|
let requestedModelAccepted;
|
|
8508
8663
|
const reportedModel = () => pickReportedModel({ runtime: [routedModel, runtimeReportedModel], requested: requestedModelAccepted });
|
|
8664
|
+
let turnIndex = 0;
|
|
8665
|
+
let turnStartedMs = Date.now();
|
|
8666
|
+
let freshSession = true;
|
|
8667
|
+
let routedPollInflight = false;
|
|
8509
8668
|
const pollRoutedModel = async () => {
|
|
8510
|
-
if (
|
|
8511
|
-
if (actualModelId(runtimeReportedModel)) return;
|
|
8669
|
+
if (!cfg.readRoutedModel || !capturedSessionId || exited) return false;
|
|
8670
|
+
if (actualModelId(runtimeReportedModel)) return true;
|
|
8671
|
+
if (routedPollInflight) return false;
|
|
8672
|
+
routedPollInflight = true;
|
|
8673
|
+
const turn = turnIndex;
|
|
8512
8674
|
try {
|
|
8513
|
-
|
|
8675
|
+
const found2 = actualModelId(await cfg.readRoutedModel(capturedSessionId, {
|
|
8676
|
+
turnStartedMs,
|
|
8677
|
+
freshSession
|
|
8678
|
+
}));
|
|
8679
|
+
if (!found2 || turn !== turnIndex) return false;
|
|
8680
|
+
if (found2 !== routedModel) {
|
|
8681
|
+
routedModel = found2;
|
|
8682
|
+
emitUsageCheckpoint();
|
|
8683
|
+
}
|
|
8684
|
+
return true;
|
|
8514
8685
|
} catch {
|
|
8686
|
+
return false;
|
|
8687
|
+
} finally {
|
|
8688
|
+
routedPollInflight = false;
|
|
8515
8689
|
}
|
|
8516
|
-
|
|
8690
|
+
};
|
|
8691
|
+
const ROUTED_MODEL_POLL_DELAYS_MS = [0, 150, 400, 900, 2e3];
|
|
8692
|
+
let routedSamplingTurn = -1;
|
|
8693
|
+
const startRoutedModelSampling = () => {
|
|
8694
|
+
if (!cfg.readRoutedModel || routedSamplingTurn === turnIndex) return;
|
|
8695
|
+
routedSamplingTurn = turnIndex;
|
|
8696
|
+
const turn = turnIndex;
|
|
8697
|
+
void (async () => {
|
|
8698
|
+
for (const delay of ROUTED_MODEL_POLL_DELAYS_MS) {
|
|
8699
|
+
if (delay > 0) await new Promise((r) => setTimeout(r, delay));
|
|
8700
|
+
if (exited || turn !== turnIndex) return;
|
|
8701
|
+
if (await pollRoutedModel()) return;
|
|
8702
|
+
}
|
|
8703
|
+
})();
|
|
8517
8704
|
};
|
|
8518
8705
|
const modelForUsage = () => reportedModel()?.model;
|
|
8519
8706
|
const usageCheckpointCbs = [];
|
|
@@ -8639,11 +8826,15 @@ ${note}` : note };
|
|
|
8639
8826
|
},
|
|
8640
8827
|
(text7) => {
|
|
8641
8828
|
confirmAppendBatch();
|
|
8829
|
+
startRoutedModelSampling();
|
|
8642
8830
|
if (cfg.classifyPromptFailure && turnMessage.length < PROMPT_TURN_MESSAGE_MAX) turnMessage += text7;
|
|
8643
8831
|
for (const cb of outputCbs) cb(text7);
|
|
8644
8832
|
},
|
|
8645
8833
|
(e) => {
|
|
8646
|
-
if (["message", "thought", "tool_use", "tool_result"].includes(e.kind))
|
|
8834
|
+
if (["message", "thought", "tool_use", "tool_result"].includes(e.kind)) {
|
|
8835
|
+
confirmAppendBatch();
|
|
8836
|
+
startRoutedModelSampling();
|
|
8837
|
+
}
|
|
8647
8838
|
for (const cb of telemetryCbs) cb(e);
|
|
8648
8839
|
},
|
|
8649
8840
|
// runtime 自己用 stopReason=cancelled 收尾时也保留取消语义;此前误记成 error,
|
|
@@ -8712,6 +8903,7 @@ ${note}` : note };
|
|
|
8712
8903
|
sessionId = job.runtimeSessionId;
|
|
8713
8904
|
ambiguousResume = true;
|
|
8714
8905
|
}
|
|
8906
|
+
if (sessionId) freshSession = false;
|
|
8715
8907
|
} catch {
|
|
8716
8908
|
sessionId = "";
|
|
8717
8909
|
}
|
|
@@ -8725,6 +8917,7 @@ ${note}` : note };
|
|
|
8725
8917
|
sessionId = extractSessionID(sessionRes);
|
|
8726
8918
|
runtimeReportedModel = extractCurrentModelID(sessionRes) ?? runtimeReportedModel;
|
|
8727
8919
|
if (!sessionId) throw new Error("session/new returned no sessionId");
|
|
8920
|
+
freshSession = true;
|
|
8728
8921
|
}
|
|
8729
8922
|
capturedSessionId = sessionId;
|
|
8730
8923
|
if (resolvedModel2) {
|
|
@@ -8761,6 +8954,8 @@ ${task}` : task;
|
|
|
8761
8954
|
const sendPrompt = async (text7) => {
|
|
8762
8955
|
turnMessage = "";
|
|
8763
8956
|
turnStderr = [];
|
|
8957
|
+
turnIndex += 1;
|
|
8958
|
+
turnStartedMs = Date.now();
|
|
8764
8959
|
const p2 = client.request("session/prompt", { sessionId, prompt: [{ type: "text", text: text7 }] });
|
|
8765
8960
|
inflightStopReason = p2.then((r) => extractStopReason(r), () => "");
|
|
8766
8961
|
try {
|
|
@@ -8780,6 +8975,7 @@ ${task}` : task;
|
|
|
8780
8975
|
sessionId = extractSessionID(sessionRes);
|
|
8781
8976
|
runtimeReportedModel = extractCurrentModelID(sessionRes) ?? runtimeReportedModel;
|
|
8782
8977
|
if (!sessionId) throw new Error("session/new returned no sessionId");
|
|
8978
|
+
freshSession = true;
|
|
8783
8979
|
capturedSessionId = sessionId;
|
|
8784
8980
|
emitUsageCheckpoint();
|
|
8785
8981
|
promptResult = await sendPrompt(userText);
|
|
@@ -9548,14 +9744,59 @@ function pickCursorModelName(value2) {
|
|
|
9548
9744
|
};
|
|
9549
9745
|
return visit(value2, 0) ?? fallback;
|
|
9550
9746
|
}
|
|
9551
|
-
function
|
|
9552
|
-
if (typeof cell !== "string"
|
|
9747
|
+
function parseCell(cell) {
|
|
9748
|
+
if (typeof cell !== "string") return void 0;
|
|
9553
9749
|
try {
|
|
9554
|
-
return
|
|
9750
|
+
return JSON.parse(cell);
|
|
9555
9751
|
} catch {
|
|
9556
9752
|
return void 0;
|
|
9557
9753
|
}
|
|
9558
9754
|
}
|
|
9755
|
+
function looksLikeTimeKey(key2) {
|
|
9756
|
+
const tokens2 = key2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
9757
|
+
const last = tokens2[tokens2.length - 1];
|
|
9758
|
+
if (!last || !TIME_KEY_TAILS.includes(last)) return false;
|
|
9759
|
+
return last !== "at" || tokens2.length > 1;
|
|
9760
|
+
}
|
|
9761
|
+
function cursorTimeValueMs(value2) {
|
|
9762
|
+
if (typeof value2 === "bigint") return cursorTimeValueMs(Number(value2));
|
|
9763
|
+
if (typeof value2 === "number") {
|
|
9764
|
+
if (!Number.isFinite(value2)) return void 0;
|
|
9765
|
+
if (value2 > 1e15) return Math.floor(value2 / 1e3);
|
|
9766
|
+
if (value2 > 1e12) return value2;
|
|
9767
|
+
if (value2 > 1e9) return value2 * 1e3;
|
|
9768
|
+
return void 0;
|
|
9769
|
+
}
|
|
9770
|
+
if (typeof value2 === "string") {
|
|
9771
|
+
const t = value2.trim();
|
|
9772
|
+
if (!t) return void 0;
|
|
9773
|
+
if (/^\d+$/.test(t)) return cursorTimeValueMs(Number(t));
|
|
9774
|
+
const ms = Date.parse(t);
|
|
9775
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
9776
|
+
}
|
|
9777
|
+
return void 0;
|
|
9778
|
+
}
|
|
9779
|
+
function cursorRowTimeMs(row, parsedCells) {
|
|
9780
|
+
let best;
|
|
9781
|
+
const take = (v2) => {
|
|
9782
|
+
const ms = cursorTimeValueMs(v2);
|
|
9783
|
+
if (ms !== void 0 && (best === void 0 || ms > best)) best = ms;
|
|
9784
|
+
};
|
|
9785
|
+
for (const [key2, value2] of Object.entries(row)) if (looksLikeTimeKey(key2)) take(value2);
|
|
9786
|
+
const visit = (node2, depth) => {
|
|
9787
|
+
if (depth > 8 || node2 === null || typeof node2 !== "object") return;
|
|
9788
|
+
if (Array.isArray(node2)) {
|
|
9789
|
+
for (const item of node2) visit(item, depth + 1);
|
|
9790
|
+
return;
|
|
9791
|
+
}
|
|
9792
|
+
for (const [key2, value2] of Object.entries(node2)) {
|
|
9793
|
+
if (looksLikeTimeKey(key2)) take(value2);
|
|
9794
|
+
visit(value2, depth + 1);
|
|
9795
|
+
}
|
|
9796
|
+
};
|
|
9797
|
+
for (const parsed of parsedCells) visit(parsed, 0);
|
|
9798
|
+
return best;
|
|
9799
|
+
}
|
|
9559
9800
|
async function openReadOnly(file) {
|
|
9560
9801
|
try {
|
|
9561
9802
|
const sqlite = await import("node:sqlite");
|
|
@@ -9564,7 +9805,9 @@ async function openReadOnly(file) {
|
|
|
9564
9805
|
return null;
|
|
9565
9806
|
}
|
|
9566
9807
|
}
|
|
9567
|
-
async function readCursorRoutedModel(sessionId,
|
|
9808
|
+
async function readCursorRoutedModel(sessionId, window3) {
|
|
9809
|
+
const env = window3.env ?? process.env;
|
|
9810
|
+
const earliest = window3.turnStartedMs - TURN_CLOCK_TOLERANCE_MS;
|
|
9568
9811
|
const file = cursorAcpSessionStorePath(sessionId, env);
|
|
9569
9812
|
if (!file) return void 0;
|
|
9570
9813
|
const db = await openReadOnly(file);
|
|
@@ -9580,10 +9823,17 @@ async function readCursorRoutedModel(sessionId, env = process.env) {
|
|
|
9580
9823
|
continue;
|
|
9581
9824
|
}
|
|
9582
9825
|
for (const row of rows) {
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9826
|
+
const cells = Object.values(row);
|
|
9827
|
+
if (!cells.some((cell) => typeof cell === "string" && cell.includes("modelName"))) continue;
|
|
9828
|
+
const parsed = cells.map(parseCell);
|
|
9829
|
+
const model = parsed.map((value2) => value2 === void 0 ? void 0 : pickCursorModelName(value2)).find((name) => !!name);
|
|
9830
|
+
if (!model) continue;
|
|
9831
|
+
const rowMs = cursorRowTimeMs(row, parsed);
|
|
9832
|
+
if (rowMs !== void 0) {
|
|
9833
|
+
if (rowMs >= earliest) return model;
|
|
9834
|
+
continue;
|
|
9586
9835
|
}
|
|
9836
|
+
if (window3.freshSession) return model;
|
|
9587
9837
|
}
|
|
9588
9838
|
}
|
|
9589
9839
|
return void 0;
|
|
@@ -9596,7 +9846,7 @@ async function readCursorRoutedModel(sessionId, env = process.env) {
|
|
|
9596
9846
|
}
|
|
9597
9847
|
}
|
|
9598
9848
|
}
|
|
9599
|
-
var fs10, os6, path12, MAX_TABLES, MAX_ROWS_PER_TABLE;
|
|
9849
|
+
var fs10, os6, path12, MAX_TABLES, MAX_ROWS_PER_TABLE, TURN_CLOCK_TOLERANCE_MS, TIME_KEY_TAILS;
|
|
9600
9850
|
var init_local_store = __esm({
|
|
9601
9851
|
"../adapters/src/cursor/local-store.ts"() {
|
|
9602
9852
|
"use strict";
|
|
@@ -9605,6 +9855,8 @@ var init_local_store = __esm({
|
|
|
9605
9855
|
path12 = __toESM(require("node:path"), 1);
|
|
9606
9856
|
MAX_TABLES = 24;
|
|
9607
9857
|
MAX_ROWS_PER_TABLE = 200;
|
|
9858
|
+
TURN_CLOCK_TOLERANCE_MS = 1e3;
|
|
9859
|
+
TIME_KEY_TAILS = ["at", "ts", "time", "timestamp", "date", "millis", "epoch"];
|
|
9608
9860
|
}
|
|
9609
9861
|
});
|
|
9610
9862
|
|
|
@@ -9652,7 +9904,7 @@ var init_cursor = __esm({
|
|
|
9652
9904
|
// 采集点 4:「自动」档下 cursor 对外只报 `default[]`(不是型号、查不到价,v2 上 385 条记的就是它),
|
|
9653
9905
|
// 而它自己的 `~/.cursor/acp-sessions/<会话号>/store.db` 里逐条回复都带实际路由到的模型。
|
|
9654
9906
|
// 这是 cursor 的内部格式:读不到就退回会话级自报值,绝不报错(见 local-store.ts)。
|
|
9655
|
-
readRoutedModel: (sessionId) => readCursorRoutedModel(sessionId),
|
|
9907
|
+
readRoutedModel: (sessionId, window3) => readCursorRoutedModel(sessionId, window3),
|
|
9656
9908
|
...this.opts.syncSkills ? { syncSkills: this.opts.syncSkills } : {}
|
|
9657
9909
|
});
|
|
9658
9910
|
}
|
|
@@ -140895,14 +141147,19 @@ ${m2.spec.split("\n").map((l) => ` > ${l}`).join("\n")}`);
|
|
|
140895
141147
|
})() : canvasMode ? [
|
|
140896
141148
|
// 内核只出「你产什么 + 内核权威锚点」——**设计工作流散文全在你的人设(identity/AGENTS.md「产出流程」)**,
|
|
140897
141149
|
// 那是单一真源、改它=改配置不发版(提案 design-conversational-driving 治本,2026-07-17)。这里不重复正文,
|
|
140898
|
-
//
|
|
141150
|
+
// 只钉住内核不能漂的几件事:真实 artifactId、缺前置的逃生口 gap,以及「下单后在会话里 status --wait 等结果」
|
|
141151
|
+
//(2026-09-24 加:它直接关系引擎的零产出判定——下单即退出会被判零产出→协议续唤→连败熔断;人设各公司
|
|
141152
|
+
// 各一份、未必同步更新,这条放内核才保证每个设计员工都拿得到)。
|
|
140899
141153
|
`\u4F60\u8D1F\u8D23 **design \u4EA7\u7269 \`${artifactId}\`**\uFF0C\u8FD0\u884C\u5728**\u901A\u7528\u8FD0\u884C\u65F6**\u4E0A\u2014\u2014\u4F60\u662F\u7532\u65B9\u8BBE\u8BA1\u8D1F\u8D23\u4EBA\uFF0C\u591A\u8F6E\u5BF9\u8BDD\u9A71\u52A8**\u534F\u4F5C\u753B\u677F\u5F15\u64CE**\u6253\u78E8\u754C\u9762\u7A3F\u3002`,
|
|
140900
141154
|
``,
|
|
140901
141155
|
`**\u5B8C\u6574\u5DE5\u4F5C\u6D41\uFF08\u600E\u4E48\u53D6\u8D27/\u8D77\u8F6E/\u8BFB\u4EA7\u7269/\u4EA4\u7A3F/\u522B\u624B\u6539\u677F\u6587\u4EF6\u2026\uFF09\u89C1\u4F60\u7684\u4EBA\u8BBE \`identity/AGENTS.md\` \u7684\u300C\u4EA7\u51FA\u6D41\u7A0B\uFF08design \u4EA7\u7269\uFF09\u300D**\u2014\u2014\u628A\u91CC\u9762 \`<artifactId>\` \u90FD\u6362\u6210\u672C\u4EA7\u7269 \`${artifactId}\`\u3002`,
|
|
140902
141156
|
``,
|
|
140903
|
-
`\u5185\u6838\u53EA\u5728\u6B64\u9489\
|
|
141157
|
+
`\u5185\u6838\u53EA\u5728\u6B64\u9489\u51E0\u6761\u4E0D\u53EF\u6F02\u7684\uFF1A`,
|
|
140904
141158
|
`- **\u4EA4\u7A3F\u8D70 \`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "\u2026"\`**\uFF08proposed \u624D\u8FDB\u7248\u672C\u53F2\u3001\u4E0B\u6E38\u624D\u62FF\u5F97\u5230\uFF1B\u4E0D propose = head \u4ECD \u2205\uFF09\uFF1B`,
|
|
140905
|
-
`- \u7F3A**\u8FD8\u4E0D\u5B58\u5728\u7684\u4E0A\u6E38\u524D\u7F6E** \u2192 \`oasis gap ${artifactId} --desc "<\u7F3A\u4EC0\u4E48>"\` \u4EA4\u4E0A\u53BB\uFF1B\u5DF2\u505A\u5B8C\u7684\u90E8\u5206\u7167\u5E38 \`propose\`\uFF0C\u4F46\u8FD9\u4E00\u8F6E \`conclude\` \u4F1A\u88AB\u62D2\uFF0C\u63D0\u4EA4\u5B8C\u5373\u6536\u5DE5\u3002
|
|
141159
|
+
`- \u7F3A**\u8FD8\u4E0D\u5B58\u5728\u7684\u4E0A\u6E38\u524D\u7F6E** \u2192 \`oasis gap ${artifactId} --desc "<\u7F3A\u4EC0\u4E48>"\` \u4EA4\u4E0A\u53BB\uFF1B\u5DF2\u505A\u5B8C\u7684\u90E8\u5206\u7167\u5E38 \`propose\`\uFF0C\u4F46\u8FD9\u4E00\u8F6E \`conclude\` \u4F1A\u88AB\u62D2\uFF0C\u63D0\u4EA4\u5B8C\u5373\u6536\u5DE5\u3002`,
|
|
141160
|
+
`- **\u5728\u672C\u4F1A\u8BDD\u91CC\u7B49\u753B\u677F\u51FA\u7ED3\u679C**\uFF08\u540C\u5F00\u53D1\u7B49 CI\uFF09\uFF1A\u5F00\u5DE5\u5148 \`oasis design status ${artifactId}\`\uFF08\u6062\u590D\u4F18\u5148\uFF0C\u677F\u4E0A\u5DF2\u6709\u8D27/\u5DF2\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u5C31\u522B\u91CD\u4E0B\uFF09\uFF1B\u4E0B\u5355\u7528 \`oasis design chat ${artifactId} \u2026 --async\`\uFF0C\u7136\u540E**\u7ACB\u523B** \`oasis design status ${artifactId} --wait --pull\` \u963B\u585E\u7B49\u8FD9\u4E00\u8F6E\u8DD1\u5B8C\u5E76\u62C9\u8D27\uFF08\u6700\u957F\u7EA6 100 \u5206\u949F\uFF1B\u963B\u585E\u671F\u95F4\u4E0D\u8017 token\uFF09\u3002\u6210\u529F \u2192 \u6838\u5BF9 \u2192 propose\uFF1B\u5931\u8D25 \u2192 \u6309\u5B83\u7ED9\u7684\u539F\u56E0\u6362\u5F15\u64CE\uFF08\`--agent\`\uFF09\u6216\u8865\u6E05\u9700\u6C42\u540E\u91CD\u4E0B\uFF0C\u518D \`--wait\`\u3002`,
|
|
141161
|
+
` - **\u4E0D\u8981\u4E0B\u5355\u540E\u76F4\u63A5\u7ED3\u675F\u4F1A\u8BDD**\u2014\u2014\u6CA1\u4EA4\u4E1C\u897F\u5C31\u6536\u5DE5\u4F1A\u88AB\u5224\u96F6\u4EA7\u51FA\uFF1B**\u4E5F\u4E0D\u8981\u81EA\u5DF1\u9694\u51E0\u5206\u949F\u624B\u52A8 status \u8F6E\u8BE2**\u2014\u2014\u6BCF\u67E5\u4E00\u6B21\u90FD\u8981\u63A8\u7406\u4E00\u6B21\u3002\u547D\u4EE4\u82E5\u88AB\u6267\u884C\u5DE5\u5177\u7684\u5355\u6761\u8D85\u65F6\u6253\u65AD\u6216\u8D85\u65F6\u9000\u51FA\uFF0C\u539F\u6837\u518D\u8DD1\u4E00\u6B21 \`--wait\` \u63A5\u7740\u7B49\uFF08\u5B83\u7B49\u7684\u662F\u753B\u677F\uFF0C\u4E0D\u4F1A\u91CD\u590D\u4E0B\u5355\uFF09\u3002`,
|
|
141162
|
+
`- \u88AB\u753B\u677F\u5DE1\u68C0\u7684\u4FE1\u5524\u9192\u65F6\uFF1A\u5148\u770B\u5F53\u524D\u7248\u672C\u88C5\u7BB1\u5355 board.link \u91CC\u7684\u300C\u5FEB\u7167\u6765\u6E90 run\u300D\u662F\u4E0D\u662F\u5C31\u662F\u4FE1\u91CC\u90A3\u4E00\u8F6E\u2014\u2014\u662F\u5C31 \`oasis resolve <\u4FE1 id>\`\uFF0C\u522B\u91CD\u590D propose\u3002`
|
|
140906
141163
|
] : (() => {
|
|
140907
141164
|
const codeRepo = args.codeRepo ?? null;
|
|
140908
141165
|
const repos = typeDef?.contentType === "code" ? codeRepo?.repos : void 0;
|
|
@@ -140939,16 +141196,32 @@ ${m2.spec.split("\n").map((l) => ` > ${l}`).join("\n")}`);
|
|
|
140939
141196
|
//
|
|
140940
141197
|
// 这些字段不能成为「没做完也能交」的出口:真正未满足交付标准时继续完成,外部阻塞走 oasis gap。
|
|
140941
141198
|
// 四项本身只传递一份已达标成果的非阻塞残余信息,不参与 conclude 判据。
|
|
140942
|
-
|
|
141199
|
+
//
|
|
141200
|
+
// ★ 2026-09-23(语菲,验收用例 H-01):此前只列参数名、没说挂在哪条命令上,agent 常把它们写到
|
|
141201
|
+
// `oasis conclude` 上——conclude 只收 `--note`,其余参数被静默丢掉(v2 上 143 次执行里写过这四项
|
|
141202
|
+
// 16 次,6 次写在 conclude 上、全丢)。所以点名「是 propose 的参数」并给一条**追加式**示例:
|
|
141203
|
+
// 只示范「在那条命令末尾加上什么」,不给整条 propose——design(交稿目录不是 deliverable/)、
|
|
141204
|
+
// 分批续跑(要带 --checkpoint --continue)各有自己的提交命令,照抄一整条会交错目录或漏参数。
|
|
141205
|
+
// 「没有就连参数名也不写」:只写参数名不跟值会被 parseArgs 拒(CLI 侧已对这四项放宽为空值,
|
|
141206
|
+
// 但未升级的节点包仍会拒),提示词也把这条路堵上。
|
|
141207
|
+
//
|
|
141208
|
+
// 集成会话(integrating || queueTaskDue)不出这段:那一档「怎么提交」明令「绝不要用 oasis propose」,
|
|
141209
|
+
// 而 `oasis integrate` 也不收这四项——再教「这是 propose 的参数」只会把它引去 propose,
|
|
141210
|
+
// 队列从 N 变 N+1、随后 conclude 撞 queue not quiescent(本文件「怎么提交」那段注释记的卡死形状)。
|
|
141211
|
+
...args.action === "review" || integrating || queueTaskDue ? [] : [
|
|
140943
141212
|
``,
|
|
140944
141213
|
`### \u4EA4\u4ED8\u65F6\u7684\u975E\u963B\u585E\u4FE1\u606F`,
|
|
140945
|
-
|
|
140946
|
-
|
|
141214
|
+
`\u4E0B\u9762\u51E0\u9879\u662F\u4EA4\u4ED8\u547D\u4EE4\uFF08\`oasis propose\`\uFF09\u7684\u53C2\u6570\uFF0C\u76F4\u63A5\u52A0\u5728\u90A3\u6761\u547D\u4EE4\u540E\u9762\uFF0C\u548C \`--reason\` \u5199\u5728\u4E00\u8D77\uFF1B\`oasis conclude\` \u53EA\u6536 \`--note\`\uFF0C\u5199\u5728 conclude \u4E0A\u7684\u5176\u5B83\u53C2\u6570\u4E0D\u4F1A\u88AB\u8BB0\u5F55\u3002`,
|
|
141215
|
+
`\`--reason\` \u5199\u660E\u76F8\u5BF9\u4E0A\u4E00\u7248\u6539\u4E86\u4EC0\u4E48\u3001\u4E3A\u4EC0\u4E48\u3001\u53EF\u80FD\u5F71\u54CD\u4EC0\u4E48\uFF1B\u9996\u6B21\u7248\u672C\u8BF4\u660E\u672C\u7248\u5B8C\u6210\u601D\u8DEF\u548C\u5185\u5BB9\u3002`,
|
|
141216
|
+
`\u53EA\u6709\u5F53\u524D\u7248\u672C\u5DF2\u7ECF\u8FBE\u5230\u4EA4\u4ED8\u6807\u51C6\u65F6\uFF0C\u624D\u53EF\u4EE5\u8BB0\u5F55\uFF08\u6BCF\u9879\u53EF\u4EE5\u5199\u591A\u6761\uFF0C\u7528\u82F1\u6587\u5206\u53F7 \`;\` \u9694\u5F00\uFF1B\u4EE5\u4E0B\u67D0\u4E00\u9879\u5982\u679C\u6CA1\u6709\u5C31\u4E0D\u5199\uFF0C\u540C\u65F6\u8BE5\u53C2\u6570\u4E5F\u4E0D\u5199\uFF09\uFF1A`,
|
|
140947
141217
|
`- \`--unresolved\`\uFF1A\u4EFB\u52A1\u8303\u56F4\u4E4B\u5916\u7684\u5DF2\u77E5\u95EE\u9898\uFF1B`,
|
|
140948
141218
|
`- \`--risks\`\uFF1A\u6210\u679C\u53EF\u4EA4\u4ED8\uFF0C\u4F46\u4F7F\u7528\u65F6\u9700\u6CE8\u610F\u7684\u6B8B\u4F59\u98CE\u9669\uFF1B`,
|
|
140949
141219
|
`- \`--gaps\`\uFF1A\u4E0D\u5C5E\u4E8E\u672C\u6B21\u5F3A\u5236\u9A8C\u6536\u6761\u4EF6\u7684\u9A8C\u8BC1\u8303\u56F4\u9650\u5236\uFF1B`,
|
|
140950
141220
|
`- \`--next\`\uFF1A\u4E0B\u6E38\u5982\u4F55\u4F7F\u7528\u6210\u679C\uFF0C\u4E0D\u662F\u4F60\u5269\u4F59\u6CA1\u505A\u7684\u5DE5\u4F5C\u3002`,
|
|
140951
|
-
`\
|
|
141221
|
+
`\u4F8B\u5982\u5728\u90A3\u6761\u547D\u4EE4\u672B\u5C3E\u52A0\u4E0A\uFF1A\`--risks "<\u98CE\u9669\u4E00>; <\u98CE\u9669\u4E8C>" --next "<\u4E0B\u6E38\u600E\u4E48\u7528>"\``,
|
|
141222
|
+
`\u672A\u8FBE\u5230\u4EA4\u4ED8\u6807\u51C6\u7684\u4E8B\u9879\u4E0D\u80FD\u653E\u5728\u8FD9\u91CC\uFF0C\u5E94\u7EE7\u7EED\u5B8C\u6210\u6216\u8FD0\u884C \`oasis gap\`\u3002`
|
|
141223
|
+
],
|
|
141224
|
+
...args.action === "review" ? [] : [
|
|
140952
141225
|
``,
|
|
140953
141226
|
`### \u4F1A\u8BDD\u53EF\u80FD\u88AB\u780D\uFF1A\u4E2D\u9014\u7559\u4E2A\u65AD\u70B9`,
|
|
140954
141227
|
// ★ 2026-08-18:`continuity-checkpoint` 此前在任务书里出现 **0 次**——说明书只在
|
|
@@ -227247,14 +227520,13 @@ function frameTokenTotal(usage) {
|
|
|
227247
227520
|
return (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0) + (usage.cacheReadTokens ?? 0) + (usage.cacheCreationTokens ?? 0);
|
|
227248
227521
|
}
|
|
227249
227522
|
async function backfillRunModel(target, run, model, modelSource, warn) {
|
|
227250
|
-
const
|
|
227251
|
-
|
|
227252
|
-
|
|
227523
|
+
const patch = preferRunModel(
|
|
227524
|
+
{ effectiveModel: run.effectiveModel, modelSource: run.modelSource },
|
|
227525
|
+
{ effectiveModel: model, modelSource: modelSource === "requested" ? "requested" : "runtime" }
|
|
227526
|
+
);
|
|
227527
|
+
if (!patch) return;
|
|
227253
227528
|
try {
|
|
227254
|
-
await target.store.updateRun(target.runId,
|
|
227255
|
-
effectiveModel,
|
|
227256
|
-
modelSource: modelSource === "requested" ? "requested" : "runtime"
|
|
227257
|
-
});
|
|
227529
|
+
await target.store.updateRun(target.runId, patch);
|
|
227258
227530
|
} catch (err) {
|
|
227259
227531
|
warn(`[usage-ledger] run ${target.runId} \u7684\u6A21\u578B\u540D\u8865\u5199\u5931\u8D25\uFF08\u4E0D\u5F71\u54CD\u4F1A\u8BDD\uFF09\uFF1A${String(err)}`);
|
|
227260
227532
|
}
|
|
@@ -228020,8 +228292,10 @@ var init_sink = __esm({
|
|
|
228020
228292
|
const isErr = status === "failed" || status === "timeout";
|
|
228021
228293
|
const errorFields = isErr ? { errorCode: update.exit.reason ?? "error", errorMessage: formatExitError(update.exit) } : {};
|
|
228022
228294
|
const exitModel = actualModelId(update.exit.model);
|
|
228023
|
-
const
|
|
228024
|
-
const
|
|
228295
|
+
const observedModel = actualModelId(st.observedModel);
|
|
228296
|
+
const exitIsRequestedOnly = update.exit.modelSource === "requested";
|
|
228297
|
+
const model = (exitIsRequestedOnly ? observedModel ?? exitModel : exitModel ?? observedModel) ?? null;
|
|
228298
|
+
const modelSource = model && model === exitModel && exitIsRequestedOnly && !observedModel ? "requested" : "runtime";
|
|
228025
228299
|
const exitRtId = typeof update.exit.runtimeSessionId === "string" && update.exit.runtimeSessionId.trim() ? update.exit.runtimeSessionId.trim() : void 0;
|
|
228026
228300
|
if (exitRtId) st.baseMetadata = { ...st.baseMetadata, runtimeSessionId: exitRtId };
|
|
228027
228301
|
const exitWorkdir = typeof update.exit.workdirRef === "string" && update.exit.workdirRef.trim() ? update.exit.workdirRef.trim() : void 0;
|
|
@@ -228052,6 +228326,12 @@ var init_sink = __esm({
|
|
|
228052
228326
|
createdAt: update.exit.at
|
|
228053
228327
|
});
|
|
228054
228328
|
}
|
|
228329
|
+
const currentRun = model ? await this.store.getRun(st.runId).catch(() => null) : null;
|
|
228330
|
+
const modelPatch = model ? preferRunModel(
|
|
228331
|
+
{ effectiveModel: currentRun?.effectiveModel, modelSource: currentRun?.modelSource },
|
|
228332
|
+
{ effectiveModel: model, modelSource },
|
|
228333
|
+
"replace"
|
|
228334
|
+
) : null;
|
|
228055
228335
|
const finished = await this.store.updateRun(st.runId, {
|
|
228056
228336
|
status,
|
|
228057
228337
|
endedAt: update.exit.at,
|
|
@@ -228067,7 +228347,7 @@ var init_sink = __esm({
|
|
|
228067
228347
|
// token/成本来自 adapter 解析 stream-json(含 cache);不带则不写、保持 null。
|
|
228068
228348
|
...update.exit.usage ? { usage: update.exit.usage } : {},
|
|
228069
228349
|
// effectiveModel/modelSource 喂用量聚合(聚合键含 model);与 chat/finishRun 路径一致。
|
|
228070
|
-
...
|
|
228350
|
+
...modelPatch ?? {},
|
|
228071
228351
|
// metadata 整列替换:必须带上 baseMetadata(bundleManifest/runtimeSessionId)一起写回。
|
|
228072
228352
|
// model 有则并入(前端 findModelInValue 直接读 metadata.model)。**不能只在有 model 时才写**
|
|
228073
228353
|
// ——否则无 model 的 run(如回捕型 runtime 没报模型)会把 exit 校正过的会话号丢掉。
|
|
@@ -228422,10 +228702,8 @@ function wireRecoveredChatTurn(deps) {
|
|
|
228422
228702
|
live.emit({ type: "done", ...plan.runtimeSessionId ? { sessionId: plan.runtimeSessionId } : {} });
|
|
228423
228703
|
live.finish(failed ? "error" : "done");
|
|
228424
228704
|
deps.unregister();
|
|
228425
|
-
const
|
|
228426
|
-
|
|
228427
|
-
info.runtimeSessionId
|
|
228428
|
-
) : void 0;
|
|
228705
|
+
const currentRun = await trace.getRun(plan.runId).catch(() => null);
|
|
228706
|
+
const nativeSessionMetadata = info.runtimeSessionId && info.runtimeSessionId !== plan.runtimeSessionId ? nativeRuntimeSessionMetadata(currentRun?.metadata, info.runtimeSessionId) : void 0;
|
|
228429
228707
|
enqueueTrace(async () => {
|
|
228430
228708
|
await appender.append([{
|
|
228431
228709
|
eventType: "run.finished",
|
|
@@ -228434,7 +228712,7 @@ function wireRecoveredChatTurn(deps) {
|
|
|
228434
228712
|
startedAt: finishedAt
|
|
228435
228713
|
}]);
|
|
228436
228714
|
await appender.update({
|
|
228437
|
-
...runTerminalPatch(info, plan.startedAt, finishedAt),
|
|
228715
|
+
...runTerminalPatch(info, plan.startedAt, finishedAt, currentRun),
|
|
228438
228716
|
// 运行时自己退干净了,但平台没把输出接全——运行记录不许写「成功」(Bug 0123)。
|
|
228439
228717
|
// 退出帧本身已经是失败时保持它的归因,只补一句缺口说明。
|
|
228440
228718
|
...outputGapRunPatch(droppedFrames, exitIsFailure, info),
|
|
@@ -228658,7 +228936,7 @@ async function reconcileChatExitFrame(deps) {
|
|
|
228658
228936
|
];
|
|
228659
228937
|
await deps.trace.appendEvents(row.runId, seqless.map((e, i) => ({ ...e, seq: baseSeq + i + 1 })));
|
|
228660
228938
|
await deps.trace.updateRun(row.runId, {
|
|
228661
|
-
...runTerminalPatch(info, run.startedAt, finishedAt),
|
|
228939
|
+
...runTerminalPatch(info, run.startedAt, finishedAt, run),
|
|
228662
228940
|
...outputGapRunPatch(droppedFrames, exitIsFailure, info),
|
|
228663
228941
|
// 首轮占位会话号 → runtime 报回的原生号(Bug 0171,判据见本函数上方那一段)。
|
|
228664
228942
|
...nativeSessionMetadata ? { metadata: nativeSessionMetadata } : {}
|
|
@@ -228887,6 +229165,7 @@ var init_chat_recovery = __esm({
|
|
|
228887
229165
|
"use strict";
|
|
228888
229166
|
init_file_restore();
|
|
228889
229167
|
init_continuation3();
|
|
229168
|
+
init_src();
|
|
228890
229169
|
init_chat_parts();
|
|
228891
229170
|
init_sink();
|
|
228892
229171
|
init_usage_ledger();
|
|
@@ -228914,7 +229193,7 @@ var init_chat_recovery = __esm({
|
|
|
228914
229193
|
const existing = formatExitError(info);
|
|
228915
229194
|
return { errorMessage: existing ? `${existing}\uFF1B${gap}` : gap };
|
|
228916
229195
|
};
|
|
228917
|
-
runTerminalPatch = (info, startedAt, endedAt) => ({
|
|
229196
|
+
runTerminalPatch = (info, startedAt, endedAt, current) => ({
|
|
228918
229197
|
status: classifySessionExitStatus(info),
|
|
228919
229198
|
endedAt,
|
|
228920
229199
|
durationMs: Date.parse(endedAt) - Date.parse(startedAt),
|
|
@@ -228927,7 +229206,11 @@ var init_chat_recovery = __esm({
|
|
|
228927
229206
|
// 不能用 null 覆盖,否则恢复轮的 token 会掉进「未知模型」桶。
|
|
228928
229207
|
// 伪型号(`default[]` / `auto`)不是模型名,不写;请求值(`requested`)与实际值分开记来源
|
|
228929
229208
|
// ——重挂路与 chat 主路、派发路三处必须同一判据,否则同一条 run 换条路收尾归属就变了。
|
|
228930
|
-
...
|
|
229209
|
+
...preferRunModel(
|
|
229210
|
+
{ effectiveModel: current?.effectiveModel, modelSource: current?.modelSource },
|
|
229211
|
+
chatExitModelFields(info.model, null, null, info.modelSource),
|
|
229212
|
+
"replace"
|
|
229213
|
+
) ?? {}
|
|
228931
229214
|
});
|
|
228932
229215
|
}
|
|
228933
229216
|
});
|
|
@@ -248171,8 +248454,16 @@ var init_service8 = __esm({
|
|
|
248171
248454
|
errorCode: input.errorCode ?? null,
|
|
248172
248455
|
errorMessage: input.errorMessage ?? null,
|
|
248173
248456
|
usage: input.usage ?? null,
|
|
248174
|
-
|
|
248175
|
-
|
|
248457
|
+
// 模型那两格按取值优先级挑(上游诊断 ④),不是无条件「收尾值优先」:`input` 里可能只剩
|
|
248458
|
+
// 请求值(claude 一条 init 都没吐就退出、ACP `set_model` 被接受但运行时从没回报),
|
|
248459
|
+
// 而 run 行上可能已经由运行中检查点补上了运行时回报的**实际值**——请求值顶掉实际值,
|
|
248460
|
+
// 这一轮就永远记在一个没跑过的型号头上(PR #2213 评审阻断项 1)。同档以收尾值为准
|
|
248461
|
+
// (`replace`):收尾只写一次,且它是这一轮解析链的最终结论。
|
|
248462
|
+
...preferRunModel(
|
|
248463
|
+
{ effectiveModel: run.effectiveModel, modelSource: run.modelSource },
|
|
248464
|
+
{ effectiveModel: input.effectiveModel, modelSource: input.modelSource },
|
|
248465
|
+
"replace"
|
|
248466
|
+
) ?? { effectiveModel: run.effectiveModel ?? null, modelSource: run.modelSource ?? null },
|
|
248176
248467
|
transcriptRef: input.transcriptRef ?? null
|
|
248177
248468
|
};
|
|
248178
248469
|
const updated = await this.store.updateRun(id, patch);
|
|
@@ -277331,11 +277622,18 @@ function messageError(m2, status) {
|
|
|
277331
277622
|
}
|
|
277332
277623
|
return { error: null, errorCode: null };
|
|
277333
277624
|
}
|
|
277625
|
+
function ownerIsWorking(model, a) {
|
|
277626
|
+
if (a.latestWorkState !== "running") return false;
|
|
277627
|
+
const latest = [...model.revisions.values()].filter((r) => r.artifactId === a.id && r.lane !== "reply").sort((x2, y) => y.createdAt.localeCompare(x2.createdAt))[0];
|
|
277628
|
+
return latest !== void 0 && latest.author === a.owner;
|
|
277629
|
+
}
|
|
277334
277630
|
var RUN_MARKER_PREFIX, boardWatchRunMarker, parseRunMarker, SINCE_MARKER_PREFIX, boardWatchSinceMarker, parseSinceMarker, TERMINAL_RUN_STATUS, MAX_REASON_CHARS, MAX_LISTED_FILES, BoardWatcher;
|
|
277335
277631
|
var init_board_watch = __esm({
|
|
277336
277632
|
"../server/src/design/board-watch.ts"() {
|
|
277337
277633
|
"use strict";
|
|
277634
|
+
init_src();
|
|
277338
277635
|
init_src7();
|
|
277636
|
+
init_src2();
|
|
277339
277637
|
RUN_MARKER_PREFIX = "[od-board-watch run:";
|
|
277340
277638
|
boardWatchRunMarker = (roundKey) => `${RUN_MARKER_PREFIX}${roundKey}]`;
|
|
277341
277639
|
parseRunMarker = (body2) => {
|
|
@@ -277368,6 +277666,14 @@ var init_board_watch = __esm({
|
|
|
277368
277666
|
seenConvAt = /* @__PURE__ */ new Map();
|
|
277369
277667
|
/** 公司 → 上次记下的失败原文(同样的错只记一次;成功一轮就清掉)。 */
|
|
277370
277668
|
companyLastError = /* @__PURE__ */ new Map();
|
|
277669
|
+
/** `<公司>\0<artifactId>\0<轮次键>` → 这一轮已被取走(head 来自它或更晚的一轮),不再重判。只在内存,不写假信。 */
|
|
277670
|
+
takenRounds = /* @__PURE__ */ new Set();
|
|
277671
|
+
/** `<公司>\0<boardKey>` → (runId → endedAt):判断 head 的快照来源 run 是不是「更晚的一轮」用。 */
|
|
277672
|
+
roundEndedAt = /* @__PURE__ */ new Map();
|
|
277673
|
+
/** `<公司>\0<revisionId>` → 该版 board.link 的快照来源 runId(null = 没有/读不到)。revision 内容不可变,缓存安全。 */
|
|
277674
|
+
revisionSourceRun = /* @__PURE__ */ new Map();
|
|
277675
|
+
/** 因 owner 在做而压着没写的 `<公司>\0<artifactId>`(只为日志只打一次)。 */
|
|
277676
|
+
deferredLogged = /* @__PURE__ */ new Set();
|
|
277371
277677
|
async odGet(path47) {
|
|
277372
277678
|
const fetchImpl = this.deps.fetchImpl ?? fetch;
|
|
277373
277679
|
try {
|
|
@@ -277428,7 +277734,8 @@ var init_board_watch = __esm({
|
|
|
277428
277734
|
if (listCompanies && kernelFor) {
|
|
277429
277735
|
for (const companyId of await listCompanies()) {
|
|
277430
277736
|
try {
|
|
277431
|
-
|
|
277737
|
+
const blobs = this.deps.blobsFor ? await this.deps.blobsFor(companyId) : void 0;
|
|
277738
|
+
await this.tickCompany(companyId, await kernelFor(companyId), now, denied, blobs);
|
|
277432
277739
|
this.companyLastError.delete(companyId);
|
|
277433
277740
|
} catch (err) {
|
|
277434
277741
|
const msg = String(err);
|
|
@@ -277438,7 +277745,7 @@ var init_board_watch = __esm({
|
|
|
277438
277745
|
}
|
|
277439
277746
|
}
|
|
277440
277747
|
} else {
|
|
277441
|
-
await this.tickCompany("", this.deps.kernel, now, denied);
|
|
277748
|
+
await this.tickCompany("", this.deps.kernel, now, denied, this.deps.blobs);
|
|
277442
277749
|
}
|
|
277443
277750
|
if (denied.length > 0) {
|
|
277444
277751
|
const codes = [...new Set(denied.map((d) => d.status))].join("/");
|
|
@@ -277449,7 +277756,7 @@ var init_board_watch = __esm({
|
|
|
277449
277756
|
}
|
|
277450
277757
|
}
|
|
277451
277758
|
/** 巡一家公司(company 为空串 = 单 kernel 模式);被拒的板记进 denied,由 tick 统一汇总成一行。 */
|
|
277452
|
-
async tickCompany(company, kernel, now, denied) {
|
|
277759
|
+
async tickCompany(company, kernel, now, denied, blobs) {
|
|
277453
277760
|
const { boardKeyOf, log: log3 } = this.deps;
|
|
277454
277761
|
const graceMs = this.deps.firstLookGraceMs ?? 10 * 6e4;
|
|
277455
277762
|
const maxPerTick = this.deps.maxLettersPerTick ?? 2;
|
|
@@ -277484,12 +277791,40 @@ var init_board_watch = __esm({
|
|
|
277484
277791
|
continue;
|
|
277485
277792
|
}
|
|
277486
277793
|
if (recordedSince === null && !this.pinnedSince.has(pinKey)) this.pinnedSince.set(pinKey, since);
|
|
277487
|
-
const
|
|
277794
|
+
const endedAtOf = this.roundEndedAt.get(`${company}\0${boardKey}`) ?? /* @__PURE__ */ new Map();
|
|
277795
|
+
this.roundEndedAt.set(`${company}\0${boardKey}`, endedAtOf);
|
|
277796
|
+
for (const r of read3.value.rounds) if (r.runId !== null) endedAtOf.set(r.runId, r.endedAt);
|
|
277797
|
+
const takenKey = (r) => `${company}\0${a.id}\0${r.key}`;
|
|
277798
|
+
const fresh = read3.value.rounds.filter((r) => r.endedAt > since && !lettered.has(r.key) && !this.takenRounds.has(takenKey(r))).sort((x2, y) => x2.endedAt - y.endedAt);
|
|
277799
|
+
const deferKey = `${company}\0${a.id}`;
|
|
277800
|
+
if (fresh.length > 0 && ownerIsWorking(model, a)) {
|
|
277801
|
+
if (!this.deferredLogged.has(deferKey)) {
|
|
277802
|
+
this.deferredLogged.add(deferKey);
|
|
277803
|
+
log3?.(`[board-watch] ${tag}${a.id} \u7684 owner \u6B63\u5728\u6267\u884C\u8FD9\u4E2A\u8282\u70B9\uFF0C\u677F ${boardKey} \u4E0A ${fresh.length} \u8F6E\u7ED3\u675F\u7684\u5BF9\u8BDD\u5148\u4E0D\u5199\u4FE1\uFF0C\u7B49\u5B83\u8FD9\u8F6E work \u7ED3\u675F\u518D\u770B`);
|
|
277804
|
+
}
|
|
277805
|
+
continue;
|
|
277806
|
+
}
|
|
277807
|
+
this.deferredLogged.delete(deferKey);
|
|
277808
|
+
const sourceRuns = fresh.length > 0 && blobs ? await this.headSourceRuns(company, blobs, model, a, log3, tag) : [];
|
|
277809
|
+
const takenBy = (r) => {
|
|
277810
|
+
for (const src of sourceRuns) {
|
|
277811
|
+
if (r.runId !== null && src === r.runId) return src;
|
|
277812
|
+
const srcEnded = endedAtOf.get(src);
|
|
277813
|
+
if (srcEnded !== void 0 && srcEnded >= r.endedAt) return src;
|
|
277814
|
+
}
|
|
277815
|
+
return null;
|
|
277816
|
+
};
|
|
277488
277817
|
const seen = /* @__PURE__ */ new Set();
|
|
277489
277818
|
for (const r of fresh) {
|
|
277490
277819
|
if (written >= maxPerTick) break;
|
|
277491
277820
|
if (seen.has(r.key)) continue;
|
|
277492
277821
|
seen.add(r.key);
|
|
277822
|
+
const src = takenBy(r);
|
|
277823
|
+
if (src !== null) {
|
|
277824
|
+
this.takenRounds.add(takenKey(r));
|
|
277825
|
+
log3?.(`[board-watch] ${tag}${a.id} \u2190 \u677F ${boardKey} \u4E00\u8F6E\u5BF9\u8BDD\u7ED3\u675F\uFF08${r.key.slice(0, 12)} ${r.status}\uFF09\uFF0C\u5F53\u524D\u7248\u672C\u7684\u5FEB\u7167\u6765\u6E90 run ${src} \u5DF2\u8986\u76D6\u5B83 \u2192 \u4E0D\u5199\u4FE1`);
|
|
277826
|
+
continue;
|
|
277827
|
+
}
|
|
277493
277828
|
const ok3 = r.status === "succeeded";
|
|
277494
277829
|
const reason = ok3 ? null : r.error ?? (r.runId !== null ? await this.runErrorFromRegistry(boardKey, r.runId) : null);
|
|
277495
277830
|
await kernel.annotate({ artifactId: a.id, actor, body: this.letterBody(a.id, boardKey, r, since, reason), kind: "comment" });
|
|
@@ -277502,6 +277837,36 @@ var init_board_watch = __esm({
|
|
|
277502
277837
|
}
|
|
277503
277838
|
}
|
|
277504
277839
|
}
|
|
277840
|
+
/**
|
|
277841
|
+
* 当前 head 与最近一版装箱单(两者可能不同:head 在跑空壳/被打回时回落)各自 board.link 里的快照来源 runId。
|
|
277842
|
+
* 读不到(非装箱单、没有 board.link、blob 缺失、占位 status-pull)的不算。
|
|
277843
|
+
*/
|
|
277844
|
+
async headSourceRuns(company, blobs, model, a, log3, tag) {
|
|
277845
|
+
const candidates = [];
|
|
277846
|
+
const head = a.currentRev ? model.revisions.get(a.currentRev) : void 0;
|
|
277847
|
+
if (head) candidates.push(head);
|
|
277848
|
+
const latestManifest = [...model.revisions.values()].filter((r) => r.artifactId === a.id && r.contentKind === "manifest" && r.contentRef.length > 0).sort((x2, y) => y.createdAt.localeCompare(x2.createdAt))[0];
|
|
277849
|
+
if (latestManifest && latestManifest.id !== head?.id) candidates.push(latestManifest);
|
|
277850
|
+
const out = [];
|
|
277851
|
+
for (const rev of candidates) {
|
|
277852
|
+
if (rev.contentKind !== "manifest" || rev.contentRef.length === 0) continue;
|
|
277853
|
+
const cacheKey = `${company}\0${rev.id}`;
|
|
277854
|
+
let src = this.revisionSourceRun.get(cacheKey);
|
|
277855
|
+
if (src === void 0) {
|
|
277856
|
+
try {
|
|
277857
|
+
const manifest = parseManifest(await blobs.get(rev.contentRef));
|
|
277858
|
+
const entry = manifest.entries.find((e) => e.path === BOARD_LINK_FILE);
|
|
277859
|
+
src = entry ? parseBoardLinkSourceRun(new TextDecoder().decode(await blobs.get(entry.hash))) : null;
|
|
277860
|
+
} catch (err) {
|
|
277861
|
+
log3?.(`[board-watch] ${tag}\u8BFB ${a.id} \u7248\u672C ${rev.id} \u7684 board.link \u5931\u8D25\uFF08${String(err)}\uFF09\uFF0C\u6309\u300C\u4E0D\u77E5\u9053\u6765\u81EA\u54EA\u4E00\u8F6E\u300D\u5904\u7406`);
|
|
277862
|
+
src = null;
|
|
277863
|
+
}
|
|
277864
|
+
this.revisionSourceRun.set(cacheKey, src);
|
|
277865
|
+
}
|
|
277866
|
+
if (src !== null) out.push(src);
|
|
277867
|
+
}
|
|
277868
|
+
return out;
|
|
277869
|
+
}
|
|
277505
277870
|
letterBody(artifactId, boardKey, r, since, reason) {
|
|
277506
277871
|
const marker = `${boardWatchRunMarker(r.key)} ${boardWatchSinceMarker(since)}`;
|
|
277507
277872
|
const round = `${r.runId !== null ? `run ${r.runId.slice(0, 8)}` : `\u6D88\u606F ${r.key.slice(4, 12)}`}\uFF0C\u5F15\u64CE=${r.agentId ?? "?"}\uFF0C\u7ED3\u675F\u4E8E ${new Date(r.endedAt).toISOString()}`;
|
|
@@ -277512,7 +277877,8 @@ var init_board_watch = __esm({
|
|
|
277512
277877
|
`\u753B\u677F ${boardKey} \u4E0A\u6709\u4E00\u8F6E\u5BF9\u8BDD\u8DD1\u5B8C\u4E86\uFF08${round}\uFF09\uFF0C\u8FD9\u4E00\u8F6E\u4EA7\u51FA\uFF1A`,
|
|
277513
277878
|
files,
|
|
277514
277879
|
``,
|
|
277515
|
-
`\
|
|
277880
|
+
`\u5148\u770B\u8FD9\u4E00\u8F6E\u662F\u4E0D\u662F\u5DF2\u7ECF\u4EA4\u8FC7\uFF1A\u5F53\u524D\u7248\u672C\u88C5\u7BB1\u5355\u91CC board.link \u7684\u300C\u5FEB\u7167\u6765\u6E90 run\u300D\u5982\u679C\u5C31\u662F ${r.runId ?? "\u8FD9\u4E00\u8F6E"}\uFF0C\u8BF4\u660E\u5DF2\u53D6\u8D70\uFF0C\`oasis resolve <\u672C\u4FE1 id> --as resolved\` \u5373\u53EF\uFF0C\u522B\u91CD\u590D propose\u3002`,
|
|
277881
|
+
`\u6CA1\u4EA4\u8FC7\u5C31\u53D6\u8D27\u6838\u5BF9\uFF1A\`oasis design status ${artifactId} --wait --pull\`\uFF08\u677F\u4E0A\u8FD8\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u4F1A\u5148\u7B49\u5B83\u8DD1\u5B8C\uFF09\u2192 \u5BF9\u7740 DESIGN_BRIEF.md \u4E0E inputs/ \u9010\u5B57\u6BB5\u6838\uFF08\u6570\u636E\u5BF9\u4E0D\u5BF9\u3001\u72B6\u6001\u5168\u4E0D\u5168\u3001\u6709\u6CA1\u6709\u7F16\u9020\uFF09\u3002\u591F\u597D\u5C31 \`oasis propose ${artifactId} --from-dir <\u76EE\u5F55> --reason "<\u8FD9\u7248\u505A\u4E86\u4EC0\u4E48>"\`\uFF1B\u8981\u6539\u5C31\u56DE\u677F\u4E0A\u518D\u6765\u4E00\u8F6E \`oasis design chat ${artifactId} --turn continue --message "<\u8981\u6539\u4EC0\u4E48>" --async\`\uFF0C\u968F\u540E \`oasis design status ${artifactId} --wait --pull\` \u7B49\u7ED3\u679C\uFF08\u26D4 \u522B\u628A --pull \u4E0B\u6765\u7684\u6587\u4EF6\u5728\u672C\u5730\u624B\u6539\u540E propose\uFF09\u3002\u8FD9\u4E00\u8F6E\u82E5\u662F\u4EBA\u76F4\u63A5\u5728\u677F\u4E0A\u804A\u51FA\u6765\u7684\u3001\u5185\u5BB9\u4E0D\u5FC5\u6536\u5F55\uFF0C\u56DE\u5E16\u8BF4\u660E\u540E\u6309 wontfix \u5904\u7406\u5373\u53EF\uFF08\u540C\u4E00\u8F6E\u4E0D\u4F1A\u518D\u6765\u4FE1\uFF09\u3002`
|
|
277516
277882
|
].join("\n");
|
|
277517
277883
|
}
|
|
277518
277884
|
const quoted = reason === null ? null : reason.length > MAX_REASON_CHARS ? `${reason.slice(0, MAX_REASON_CHARS)}\u2026` : reason;
|
|
@@ -277521,7 +277887,7 @@ var init_board_watch = __esm({
|
|
|
277521
277887
|
`\u753B\u677F ${boardKey} \u4E0A\u6709\u4E00\u8F6E\u5BF9\u8BDD**\u6CA1\u8DD1\u6210**\uFF08\u7EC8\u6001=${r.status}\uFF0C${round}\uFF09\u3002`,
|
|
277522
277888
|
quoted !== null ? `od \u8BB0\u7684\u539F\u56E0\uFF08\u539F\u6587\uFF09\uFF1A${quoted}${r.errorCode !== null ? `\uFF08\u9519\u8BEF\u7801 ${r.errorCode}\uFF09` : ""}` : `od \u6CA1\u6709\u8BB0\u5F55\u8FD9\u4E00\u8F6E\u7684\u5931\u8D25\u539F\u56E0\u3002`,
|
|
277523
277889
|
``,
|
|
277524
|
-
`\u5148 \`oasis design status ${artifactId}\` \u770B\u677F\u4E0A\u6709\u6CA1\u6709\u53EF\u7528\u7684\u4E0A\u4E00\u7248\uFF1A\u6709\u5C31\u7167\u5E38\u53D6\u8D27\u6838\u5BF9\u3002\u8981\u91CD\u8DD1\u5C31\u81EA\u5DF1\u5224\u65AD\uFF1A\u50CF\u662F\u989D\u5EA6/\u9650\u6D41\u5C31\u7B49\u6062\u590D\u540E\u518D\u6765\uFF0C\u6216\u6362\u4E2A\u5F15\u64CE \`oasis design chat ${artifactId} --agent <\u5F15\u64CE> --message "<\u2026>" --async\`\uFF1B\u50CF\u662F\u9700\u6C42/\u6570\u636E\u95EE\u9898\u5C31\u628A\u5B83\u4EEC\u9489\u5F97\u66F4\u6B7B\u540E\u91CD\u8D77\u4E00\u8F6E\
|
|
277890
|
+
`\u5148 \`oasis design status ${artifactId}\` \u770B\u677F\u4E0A\u6709\u6CA1\u6709\u53EF\u7528\u7684\u4E0A\u4E00\u7248\uFF1A\u6709\u5C31\u7167\u5E38\u53D6\u8D27\u6838\u5BF9\u3002\u8981\u91CD\u8DD1\u5C31\u81EA\u5DF1\u5224\u65AD\uFF1A\u50CF\u662F\u989D\u5EA6/\u9650\u6D41\u5C31\u7B49\u6062\u590D\u540E\u518D\u6765\uFF0C\u6216\u6362\u4E2A\u5F15\u64CE \`oasis design chat ${artifactId} --turn continue --agent <\u5F15\u64CE> --message "<\u2026>" --async\`\uFF1B\u50CF\u662F\u9700\u6C42/\u6570\u636E\u95EE\u9898\u5C31\u628A\u5B83\u4EEC\u9489\u5F97\u66F4\u6B7B\u540E\u91CD\u8D77\u4E00\u8F6E\u3002\u91CD\u4E0B\u4E4B\u540E\u7ACB\u523B \`oasis design status ${artifactId} --wait --pull\` \u5728\u4F1A\u8BDD\u91CC\u7B49\u7ED3\u679C\uFF0C\u522B\u4E0B\u5355\u5C31\u6536\u5DE5\u3002\u4ECD\u4E0D\u884C\u7528 \`oasis gap ${artifactId} --desc "<\u5361\u5728\u54EA>"\` \u5192\u6CE1\u7ED9\u4EBA\u3002`
|
|
277525
277891
|
].join("\n");
|
|
277526
277892
|
}
|
|
277527
277893
|
};
|
|
@@ -278654,6 +279020,7 @@ __export(src_exports2, {
|
|
|
278654
279020
|
openNewEngine: () => openNewEngine,
|
|
278655
279021
|
operatorCrossCompanyRead: () => operatorCrossCompanyRead,
|
|
278656
279022
|
outputsPartProvider: () => outputsPartProvider,
|
|
279023
|
+
ownerIsWorking: () => ownerIsWorking,
|
|
278657
279024
|
packMatches: () => packMatches,
|
|
278658
279025
|
parentConversationTaskLines: () => parentConversationTaskLines,
|
|
278659
279026
|
parseConnectorSkillId: () => parseConnectorSkillId,
|
|
@@ -286195,7 +286562,13 @@ async function startServe(opts) {
|
|
|
286195
286562
|
metadata: { ...base, dispatchId: handle.id },
|
|
286196
286563
|
// 恢复路径拿不到 dispatchChat 闭包里的 fallback 解析结果,开跑时先写进账本;退出帧若上报
|
|
286197
286564
|
// 更精确 model 仍会覆盖为 runtime 来源。
|
|
286198
|
-
|
|
286565
|
+
// 这是**请求值**(会话选择 / 员工配置 / runtime 默认),按 ④ 排在实际值之下:采集点 1 的
|
|
286566
|
+
// 首帧检查点可能已经先一步把运行时回报的实际值写进这一行(两条路都是异步入队,谁先到不定),
|
|
286567
|
+
// 预写不能把它顶掉。
|
|
286568
|
+
...preferRunModel(
|
|
286569
|
+
{ effectiveModel: run.effectiveModel, modelSource: run.modelSource },
|
|
286570
|
+
{ effectiveModel: chatModel, modelSource: chatModelSource }
|
|
286571
|
+
) ?? {}
|
|
286199
286572
|
});
|
|
286200
286573
|
});
|
|
286201
286574
|
const buffered = [];
|
|
@@ -286267,11 +286640,17 @@ async function startServe(opts) {
|
|
|
286267
286640
|
}]);
|
|
286268
286641
|
const usage = info.usage ?? null;
|
|
286269
286642
|
const modelFields = chatExitModelFields(info.model, chatModel, chatModelSource, info.modelSource);
|
|
286643
|
+
const needsNativeSessionMetadata = !!info.runtimeSessionId && info.runtimeSessionId !== runtimeSessionId;
|
|
286644
|
+
const currentRun = needsNativeSessionMetadata || "effectiveModel" in modelFields ? await (await traceStoreFor(runCompanyId)).getRun(traceRunId).catch(() => null) : null;
|
|
286270
286645
|
let nativeSessionMetadata;
|
|
286271
|
-
if (
|
|
286272
|
-
|
|
286273
|
-
nativeSessionMetadata = nativeRuntimeSessionMetadata(run?.metadata, info.runtimeSessionId);
|
|
286646
|
+
if (needsNativeSessionMetadata) {
|
|
286647
|
+
nativeSessionMetadata = nativeRuntimeSessionMetadata(currentRun?.metadata, info.runtimeSessionId);
|
|
286274
286648
|
}
|
|
286649
|
+
const modelPatch = preferRunModel(
|
|
286650
|
+
{ effectiveModel: currentRun?.effectiveModel, modelSource: currentRun?.modelSource },
|
|
286651
|
+
{ effectiveModel: modelFields.effectiveModel, modelSource: modelFields.modelSource },
|
|
286652
|
+
"replace"
|
|
286653
|
+
) ?? {};
|
|
286275
286654
|
await traceAppender.update({
|
|
286276
286655
|
status: classifySessionExitStatus(info),
|
|
286277
286656
|
endedAt,
|
|
@@ -286281,7 +286660,7 @@ async function startServe(opts) {
|
|
|
286281
286660
|
...!isHealthySessionExit(info) && info.reason !== "cancelled" ? { errorCode: info.reason ?? "error", errorMessage: formatExitError(info) } : {},
|
|
286282
286661
|
transcriptRef: info.transcriptRef ?? null,
|
|
286283
286662
|
usage,
|
|
286284
|
-
...
|
|
286663
|
+
...modelPatch,
|
|
286285
286664
|
...nativeSessionMetadata ? { metadata: nativeSessionMetadata } : {}
|
|
286286
286665
|
});
|
|
286287
286666
|
if (usage) await settleRunUsage(await traceStoreFor(runCompanyId), traceRunId);
|
|
@@ -289142,6 +289521,8 @@ ${nodeFault}` : "");
|
|
|
289142
289521
|
return [defaultCompanyId, ...active.filter((id) => id !== defaultCompanyId)];
|
|
289143
289522
|
},
|
|
289144
289523
|
kernelFor: async (companyId) => (await getEngine(companyId)).kernel,
|
|
289524
|
+
// 读 head 装箱单里的 board.link(「快照来源 run」)判断这一轮是否已被取走,已取走就不写信
|
|
289525
|
+
blobsFor: async (companyId) => (await getEngine(companyId)).blobs,
|
|
289145
289526
|
odBase,
|
|
289146
289527
|
...odToken ? { odToken } : {},
|
|
289147
289528
|
boardKeyOf: deriveBoardKey,
|
|
@@ -292401,29 +292782,32 @@ var COMMAND_DECLS = {
|
|
|
292401
292782
|
flags: [
|
|
292402
292783
|
{ name: "message", desc: "\u6D88\u606F\u5185\u5BB9", required: true },
|
|
292403
292784
|
{ name: "turn", desc: "\u5BF9\u8BDD\u8F6E\u6B21\uFF08first | continue\uFF09" },
|
|
292404
|
-
{ name: "async", desc: "\
|
|
292785
|
+
{ name: "async", desc: "\u4E0B\u5355\u5373\u8FD4\uFF1B\u968F\u540E\u7528 design status --wait --pull \u963B\u585E\u7B49\u7ED3\u679C" },
|
|
292405
292786
|
{ name: "system", desc: "\u7CFB\u7EDF\u63D0\u793A" }
|
|
292406
292787
|
],
|
|
292407
292788
|
examples: ['oasis design chat artifact:design:xyz --message "\u628A\u6309\u94AE\u6539\u6210\u84DD\u8272" --turn continue']
|
|
292408
292789
|
},
|
|
292409
292790
|
"design status": {
|
|
292410
292791
|
group: "\u8BBE\u8BA1\u7A3F",
|
|
292411
|
-
usage: "oasis design status <artifactId> [--pull]",
|
|
292412
|
-
description: "\u67E5\u753B\u677F\u73B0\u72B6\uFF08\u6062\u590D\u4F18\u5148\uFF09\u3002\u88AB\u6D3E\u53D1\u5148\u8DD1\u5B83\u2014\u2014\u5F15\u64CE\u5728\u8DD1\u5C31\u522B\u8D77\u65B0\u8F6E\u3002",
|
|
292792
|
+
usage: "oasis design status <artifactId> [--pull] [--wait [--wait-timeout <\u5206\u949F>]]",
|
|
292793
|
+
description: "\u67E5\u753B\u677F\u73B0\u72B6\uFF08\u6062\u590D\u4F18\u5148\uFF09\u3002\u88AB\u6D3E\u53D1\u5148\u8DD1\u5B83\u2014\u2014\u5F15\u64CE\u5728\u8DD1\u5C31\u522B\u8D77\u65B0\u8F6E\u3002--wait\uFF1A\u677F\u4E0A\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u5C31\u963B\u585E\u7B49\u5230\u5168\u90E8\u7ED3\u675F\uFF08\u4E0D\u7BA1\u662F\u8C01\u8D77\u7684\uFF09\uFF0C\u518D\u6253\u5370\u7ED3\u679C\uFF1B\u8D85\u65F6\u975E\u96F6\u9000\u51FA\u3002",
|
|
292413
292794
|
positional: [
|
|
292414
292795
|
{ name: "<artifactId>", required: true, desc: "\u4EA7\u7269 id" }
|
|
292415
292796
|
],
|
|
292416
292797
|
flags: [
|
|
292417
|
-
{ name: "pull", desc: "\u62C9\u53D6\u6700\u65B0\u753B\u677F\u5185\u5BB9\u5230\u672C\u5730" }
|
|
292798
|
+
{ name: "pull", desc: "\u62C9\u53D6\u6700\u65B0\u753B\u677F\u5185\u5BB9\u5230\u672C\u5730\uFF08\u5E26 --wait \u65F6\uFF1A\u7B49\u5B8C\u4E14\u6700\u8FD1\u4E00\u8F6E\u6210\u529F\u624D\u62C9\uFF09" },
|
|
292799
|
+
{ name: "wait", desc: "\u677F\u4E0A\u6709\u5728\u8DD1\u7684\u8F6E\u6B21\u5C31\u963B\u585E\u7B49\u5B83\u4EEC\u7ED3\u675F\uFF08\u540C gh pr checks --watch\uFF09", boolean: true },
|
|
292800
|
+
{ name: "wait-timeout", desc: "--wait \u6700\u591A\u7B49\u51E0\u5206\u949F\uFF08\u9ED8\u8BA4 100\uFF09" },
|
|
292801
|
+
{ name: "wait-interval", desc: "--wait \u8F6E\u8BE2\u95F4\u9694\u79D2\u6570\uFF08\u9ED8\u8BA4 20\uFF09" }
|
|
292418
292802
|
],
|
|
292419
|
-
examples: ["oasis design status artifact:design:xyz --pull"]
|
|
292803
|
+
examples: ["oasis design status artifact:design:xyz --wait --pull", "oasis design status artifact:design:xyz --pull"]
|
|
292420
292804
|
},
|
|
292421
292805
|
design: {
|
|
292422
292806
|
group: "\u8BBE\u8BA1\u7A3F",
|
|
292423
292807
|
usage: "oasis design <chat|status> <artifactId> ...",
|
|
292424
292808
|
description: "\u8BBE\u8BA1\u4EA7\u7269\u76F8\u5173\u64CD\u4F5C\u3002\u8FDE\u54EA\u4E2A open-design\uFF1A\u5458\u5DE5\u5F00\u4E86 open-design \u8FDE\u63A5\u5668\u5C31\u8FDE\u5B83\u767B\u8BB0\u7684\u5730\u5740\u5E76\u5E26\u4EE4\u724C\uFF08\u4EFB\u610F\u8282\u70B9\u53EF\u7528\uFF09\uFF0C\u5426\u5219 $OASIS_OPEN_DESIGN_URL\uFF0C\u518D\u5426\u5219\u672C\u673A\u3002",
|
|
292425
292809
|
subCommands: ["design chat", "design status"],
|
|
292426
|
-
examples: ['oasis design chat artifact:design:xyz --message "\u8BBE\u8BA1\u767B\u5F55\u9875" --async']
|
|
292810
|
+
examples: ['oasis design chat artifact:design:xyz --message "\u8BBE\u8BA1\u767B\u5F55\u9875" --async', "oasis design status artifact:design:xyz --wait --pull"]
|
|
292427
292811
|
},
|
|
292428
292812
|
// —— 图机制(§6/§7) ——
|
|
292429
292813
|
annotate: {
|
|
@@ -294035,6 +294419,7 @@ ${buildCommandIndex()}
|
|
|
294035
294419
|
${USAGE_FOOTER}`;
|
|
294036
294420
|
var COMMAND_HELP = buildCommandHelp();
|
|
294037
294421
|
var HISTORICAL_REVIEW_GUIDANCE = "\u672C\u7968\u4E0D\u53C2\u4E0E\u672C\u8F6E quorum\uFF1B\u4F46\u5B83\u6307\u51FA\u7684\u95EE\u9898\u53EF\u80FD\u4ECD\u7136\u5B58\u5728\uFF0C\u9700\u9010\u6761\u5BF9\u7167 diff \u786E\u8BA4";
|
|
294422
|
+
var EMPTY_OK_NOTE_FLAGS = /* @__PURE__ */ new Set(["unresolved", "risks", "gaps", "next"]);
|
|
294038
294423
|
function parseArgs(argv) {
|
|
294039
294424
|
const positional = [];
|
|
294040
294425
|
const flags = /* @__PURE__ */ new Map();
|
|
@@ -294061,6 +294446,10 @@ function parseArgs(argv) {
|
|
|
294061
294446
|
const value2 = argv[i + 1];
|
|
294062
294447
|
const key2 = a.slice(2);
|
|
294063
294448
|
if (value2 === void 0 || value2.startsWith("--")) {
|
|
294449
|
+
if (EMPTY_OK_NOTE_FLAGS.has(key2)) {
|
|
294450
|
+
flags.set(key2, "");
|
|
294451
|
+
continue;
|
|
294452
|
+
}
|
|
294064
294453
|
if (!booleanFlags.has(key2)) throw new Error(`flag ${a} \u9700\u8981\u4E00\u4E2A\u503C`);
|
|
294065
294454
|
flags.set(key2, "true");
|
|
294066
294455
|
} else {
|
|
@@ -294096,6 +294485,15 @@ function needPos(positional, i, usage) {
|
|
|
294096
294485
|
if (v2 === void 0) throw new Error(`\u7528\u6CD5: ${usage}`);
|
|
294097
294486
|
return v2;
|
|
294098
294487
|
}
|
|
294488
|
+
function positiveNumberFlag(flags, name, dflt) {
|
|
294489
|
+
const raw = flags.get(name);
|
|
294490
|
+
if (raw === void 0) return dflt;
|
|
294491
|
+
const n = Number(raw);
|
|
294492
|
+
if (!Number.isFinite(n) || n <= 0) throw new Error(`--${name} \u8981\u4E00\u4E2A\u6B63\u6570\uFF08\u6536\u5230\uFF1A${raw}\uFF09`);
|
|
294493
|
+
return n;
|
|
294494
|
+
}
|
|
294495
|
+
var shortRunKey = (key2) => key2.startsWith("msg:") ? `\u6D88\u606F ${key2.slice(4, 12)}` : `run ${key2.slice(0, 8)}`;
|
|
294496
|
+
var clipReason = (reason) => reason.length > 300 ? `${reason.slice(0, 300)}\u2026` : reason;
|
|
294099
294497
|
function semicolonList(raw, field) {
|
|
294100
294498
|
if (raw === void 0) return {};
|
|
294101
294499
|
const items = raw.split(";").map((x2) => x2.trim()).filter(Boolean);
|
|
@@ -294298,7 +294696,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
294298
294696
|
}
|
|
294299
294697
|
}
|
|
294300
294698
|
}
|
|
294301
|
-
var CLI_VERSION = "2.2.
|
|
294699
|
+
var CLI_VERSION = "2.2.85" ? "2.2.85" : "dev";
|
|
294302
294700
|
function apiHeaders(token, company) {
|
|
294303
294701
|
const headers = {
|
|
294304
294702
|
authorization: `Bearer ${token}`,
|
|
@@ -296068,7 +296466,7 @@ ${res.warning}`);
|
|
|
296068
296466
|
println(`[design] \u753B\u677F ${deriveBoardKey(artifactId)} \u2190 ${artifactId}\uFF1B${isContinue ? "\u7EED\u8F6E" : "\u9996\u8F6E"}\uFF08--async\uFF09\u2192 od \u5F15\u64CE ${odLabel} \u2026`);
|
|
296069
296467
|
const started = await startDesignChatTurn(baseTurnOpts);
|
|
296070
296468
|
println(`[design] \u5DF2\u4E0B\u5355\uFF1Arun ${started.runId.slice(0, 8)}\uFF08board ${started.boardKey}, \u53EF\u89C1 user \u56DE\u5408 ${started.userMessageId.slice(0, 8)}\uFF09\u3002\u5F15\u64CE\u901A\u5E38\u8981 13\u201344 \u5206\u949F\u3002`);
|
|
296071
|
-
println(`[design] \
|
|
296469
|
+
println(`[design] \u4E0B\u4E00\u6B65\u7ACB\u523B\u6267\u884C\uFF1Aoasis design status ${artifactId} --wait --pull\uFF08\u963B\u585E\u7B49\u8FD9\u4E00\u8F6E\u8DD1\u5B8C\u5E76\u62C9\u8D27\uFF0C\u6700\u957F\u7B49 100 \u5206\u949F\uFF09\u3002\u522B\u4E0B\u5355\u540E\u76F4\u63A5\u7ED3\u675F\u4F1A\u8BDD\uFF0C\u4E5F\u522B\u81EA\u5DF1\u9694\u51E0\u5206\u949F\u624B\u52A8 status\u3002`);
|
|
296072
296470
|
break;
|
|
296073
296471
|
}
|
|
296074
296472
|
println(`[design] \u753B\u677F ${deriveBoardKey(artifactId)} \u2190 ${artifactId}\uFF1B${isContinue ? "\u7EED\u8F6E" : "\u9996\u8F6E"}\u5BF9\u8BDD\u9A71\u52A8 od \u5F15\u64CE ${odLabel} \u2026`);
|
|
@@ -296082,46 +296480,82 @@ ${res.warning}`);
|
|
|
296082
296480
|
break;
|
|
296083
296481
|
}
|
|
296084
296482
|
if (sub === "status") {
|
|
296085
|
-
const artifactId = needPos(positional, 1, "oasis design status <artifactId> [--pull]");
|
|
296483
|
+
const artifactId = needPos(positional, 1, "oasis design status <artifactId> [--pull] [--wait]");
|
|
296086
296484
|
const od = resolveOpenDesignEndpoint(flags.get("od-url"));
|
|
296087
296485
|
const odBase = od.base;
|
|
296088
296486
|
const odFetch = withOdToken(fetch, od.token);
|
|
296089
|
-
|
|
296487
|
+
let st;
|
|
296488
|
+
let waitedForRun = false;
|
|
296489
|
+
if (flags.get("wait") === "true") {
|
|
296490
|
+
const timeoutMin = positiveNumberFlag(flags, "wait-timeout", 100);
|
|
296491
|
+
const intervalSec = positiveNumberFlag(flags, "wait-interval", 20);
|
|
296492
|
+
const fmt = (ms) => `${Math.floor(ms / 6e4)} \u5206 ${Math.floor(ms % 6e4 / 1e3)} \u79D2`;
|
|
296493
|
+
const waited = await waitBoardSettled(odBase, odFetch, artifactId, {
|
|
296494
|
+
timeoutMs: timeoutMin * 6e4,
|
|
296495
|
+
intervalMs: intervalSec * 1e3,
|
|
296496
|
+
// 每次轮询打一行撑 liveness;状态没变只打短的一行,别刷屏
|
|
296497
|
+
onPoll: ({ live: live2, elapsedMs, changed, unreadable }) => {
|
|
296498
|
+
if (!changed) return println(`[design] \u2026\u4ECD\u5728\u7B49\uFF08\u5DF2\u7B49 ${fmt(elapsedMs)}\uFF09`);
|
|
296499
|
+
if (live2.length === 0 && unreadable) return println(`[design] \u8FD9\u6B21\u6CA1\u8BFB\u5230\u753B\u677F\u5BF9\u8BDD\u8BB0\u5F55\uFF08od \u6682\u65F6\u4E0D\u901A\uFF1F\uFF09\uFF0C\u63A5\u7740\u7B49\uFF08\u5DF2\u7B49 ${fmt(elapsedMs)}\uFF09`);
|
|
296500
|
+
const runs = live2.map((r) => `${shortRunKey(r.key)} \u72B6\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}`).join("\uFF1B");
|
|
296501
|
+
println(`[design] \u7B49\u753B\u677F\u8FD9\u4E00\u8F6E\u8DD1\u5B8C\uFF1A${runs}\uFF08\u5DF2\u7B49 ${fmt(elapsedMs)}\uFF0C\u4E0A\u9650 ${timeoutMin} \u5206\u949F\uFF09`);
|
|
296502
|
+
}
|
|
296503
|
+
});
|
|
296504
|
+
st = waited.status;
|
|
296505
|
+
waitedForRun = waited.waited;
|
|
296506
|
+
if (!waited.settled) {
|
|
296507
|
+
const runs = waited.live.map((r) => `${shortRunKey(r.key)} \u72B6\u6001=${r.status}`).join("\u3001") || "\u5BF9\u8BDD\u8BB0\u5F55\u8BFB\u4E0D\u5230";
|
|
296508
|
+
println(`[design] \u7B49\u4E86 ${fmt(waited.elapsedMs)}\uFF0C\u753B\u677F\u4E0A\u8FD9\u4E00\u8F6E\u8FD8\u6CA1\u7ED3\u675F\uFF08${runs}\uFF09\u2014\u2014\u5F15\u64CE\u8FD8\u5728\u8DD1\uFF0C\u53EF\u7A0D\u540E\u518D oasis design status ${artifactId} --wait${flags.get("pull") === "true" ? " --pull" : ""}\u3002\u522B\u53E6\u8D77\u65B0\u8F6E\u3002`);
|
|
296509
|
+
process.exitCode = 2;
|
|
296510
|
+
break;
|
|
296511
|
+
}
|
|
296512
|
+
if (waitedForRun) println(`[design] \u753B\u677F\u4E0A\u7684\u8F6E\u6B21\u90FD\u5DF2\u7ED3\u675F\uFF08\u7B49\u4E86 ${fmt(waited.elapsedMs)}\uFF09\u3002`);
|
|
296513
|
+
} else {
|
|
296514
|
+
st = await fetchBoardStatus(odBase, odFetch, artifactId);
|
|
296515
|
+
}
|
|
296090
296516
|
if (!st.boardExists) {
|
|
296091
|
-
println(`[design] \u753B\u677F ${st.boardKey} \u5C1A\u4E0D\u5B58\u5728\u2014\u2014\u8FD8\u6CA1\u8D77\u8FC7\u4EFB\u4F55\u4E00\u8F6E\u3002\u5F00\u5DE5\uFF1Aoasis design chat ${artifactId} --message "<\u8BBE\u8BA1\u9700\u6C42+\u771F\u5B9E\u6570\u636E>" --async`);
|
|
296517
|
+
println(`[design] \u753B\u677F ${st.boardKey} \u5C1A\u4E0D\u5B58\u5728\u2014\u2014\u8FD8\u6CA1\u8D77\u8FC7\u4EFB\u4F55\u4E00\u8F6E\u3002\u5F00\u5DE5\uFF1Aoasis design chat ${artifactId} --message "<\u8BBE\u8BA1\u9700\u6C42+\u771F\u5B9E\u6570\u636E>" --async\uFF0C\u968F\u540E oasis design status ${artifactId} --wait --pull`);
|
|
296092
296518
|
break;
|
|
296093
296519
|
}
|
|
296094
|
-
const live = st
|
|
296520
|
+
const live = liveBoardRuns(st);
|
|
296095
296521
|
if (live.length > 0) {
|
|
296096
|
-
for (const r of live) println(`[design] \u5F15\u64CE\u5728\u8DD1\
|
|
296522
|
+
for (const r of live) println(`[design] \u5F15\u64CE\u5728\u8DD1\uFF1A${shortRunKey(r.key)} \u72B6\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}\u2014\u2014\u522B\u518D\u8D77\u65B0\u8F6E\uFF1B\u7528 oasis design status ${artifactId} --wait --pull \u963B\u585E\u7B49\u5B83\u8DD1\u5B8C\u5E76\u62C9\u8D27\u3002`);
|
|
296097
296523
|
} else if (st.runs.length > 0) {
|
|
296098
296524
|
for (const r of st.runs.slice(0, 3)) {
|
|
296099
296525
|
println(`[design] \u8FD1\u671F run\uFF1A${r.runId.slice(0, 8)} \u7EC8\u6001=${r.status}${r.agentId ? ` \u5F15\u64CE=${r.agentId}` : ""}`);
|
|
296100
|
-
if (r.status === "failed" && r.error) {
|
|
296101
|
-
|
|
296102
|
-
|
|
296103
|
-
|
|
296526
|
+
if (r.status === "failed" && r.error) println(`[design] \u5931\u8D25\u539F\u56E0\uFF08od \u539F\u6587\uFF09\uFF1A${clipReason(r.error)}`);
|
|
296527
|
+
}
|
|
296528
|
+
} else if ((st.turns ?? []).length > 0) {
|
|
296529
|
+
for (const t of (st.turns ?? []).slice(0, 3)) {
|
|
296530
|
+
println(`[design] \u8FD1\u671F run\uFF08\u5BF9\u8BDD\u8BB0\u5F55\uFF09\uFF1A${(t.runId ?? t.messageId ?? "?").slice(0, 8)} \u7EC8\u6001=${t.status}${t.agentId ? ` \u5F15\u64CE=${t.agentId}` : ""}`);
|
|
296531
|
+
if (t.status !== "succeeded" && t.error) println(`[design] \u5931\u8D25\u539F\u56E0\uFF08od \u539F\u6587\uFF09\uFF1A${clipReason(t.error)}`);
|
|
296104
296532
|
}
|
|
296105
296533
|
} else {
|
|
296106
296534
|
println(`[design] \u65E0\u5728\u4E16 run \u8BB0\u5F55\uFF08od \u91CD\u542F\u540E\u4E3A\u7A7A\uFF0C\u5C5E\u6B63\u5E38\uFF09\u2014\u2014\u770B\u4E0B\u9762\u677F\u4E0A\u4EA7\u7269\u5373\u6301\u4E45\u771F\u76F8\u3002`);
|
|
296107
296535
|
}
|
|
296536
|
+
const last = latestEndedRun(st);
|
|
296537
|
+
const lastFailed = waitedForRun && last !== void 0 && last.status !== "succeeded";
|
|
296538
|
+
if (lastFailed) {
|
|
296539
|
+
println(`[design] \u521A\u7ED3\u675F\u7684\u8FD9\u4E00\u8F6E\u6CA1\u8DD1\u6210\uFF08\u7EC8\u6001=${last.status}${last.agentId ? ` \u5F15\u64CE=${last.agentId}` : ""}\uFF09${last.error ? `\uFF1A${clipReason(last.error)}` : "\uFF0Cod \u6CA1\u8BB0\u539F\u56E0"}\u3002`);
|
|
296540
|
+
println(`[design] \u50CF\u989D\u5EA6/\u9650\u6D41/\u5F15\u64CE\u6545\u969C \u2192 \u6362\u5F15\u64CE\u91CD\u4E0B\uFF1Aoasis design chat ${artifactId} --turn continue --agent <\u53E6\u4E00\u4E2A\u5F15\u64CE> --message "<\u2026>" --async\uFF1B\u50CF\u9700\u6C42/\u6570\u636E\u4E0D\u6E05 \u2192 \u8865\u6E05\u695A\u540E\u91CD\u4E0B\uFF1B\u4E0B\u5B8C\u7167\u65E7 oasis design status ${artifactId} --wait --pull\u3002`);
|
|
296541
|
+
}
|
|
296108
296542
|
if (st.artifacts.length === 0) {
|
|
296109
|
-
println(`[design] \u677F\u4E0A\u8FD8\u6CA1\u6709\u4EA4\u4ED8\u7269\u3002${live.length > 0 ?
|
|
296543
|
+
println(`[design] \u677F\u4E0A\u8FD8\u6CA1\u6709\u4EA4\u4ED8\u7269\u3002${live.length > 0 ? `\u7B49\u5F15\u64CE\u8DD1\u5B8C\uFF1Aoasis design status ${artifactId} --wait --pull` : `\u8D77\u4E00\u8F6E\uFF1Aoasis design chat ${artifactId} --message "<\u2026>" --async\uFF0C\u968F\u540E oasis design status ${artifactId} --wait --pull`}`);
|
|
296110
296544
|
break;
|
|
296111
296545
|
}
|
|
296112
296546
|
println(`[design] \u677F\u4E0A\u4EA4\u4ED8\u7269\uFF08\u6301\u4E45\uFF0C\u65B0\u2192\u65E7\uFF09\uFF1A`);
|
|
296113
296547
|
for (const a of st.artifacts) println(` - ${a.path}\uFF08${a.kind ?? "?"}\uFF09status=${a.status ?? "?"}${a.mtime ? ` \xB7 ${new Date(a.mtime).toISOString()}` : ""}`);
|
|
296114
|
-
if (flags.get("pull") === "true") {
|
|
296548
|
+
if (flags.get("pull") === "true" && !lastFailed) {
|
|
296115
296549
|
const odPublic = (flags.get("od-public-url") ?? process.env["OASIS_OPEN_DESIGN_PUBLIC_URL"] ?? "https://design.open-friday.com").replace(/\/$/, "");
|
|
296116
|
-
const { dir: dir2, entry } = await harvestBoard(odBase, odFetch, odPublic, os13.tmpdir(), st.boardKey,
|
|
296550
|
+
const { dir: dir2, entry } = await harvestBoard(odBase, odFetch, odPublic, os13.tmpdir(), st.boardKey, snapshotSourceRunId(st) ?? "status-pull");
|
|
296117
296551
|
println(`[design] \u5DF2\u62C9\u5230\u672C\u5730\uFF1A${dir2}\uFF08\u5165\u53E3 ${entry}\uFF09`);
|
|
296118
296552
|
println(`[design] \u8BFB\u5B8C\u6EE1\u610F\u5373\u4EA4\u7A3F\uFF1Aoasis propose ${artifactId} --from-dir ${dir2} --reason "<\u8FD9\u7248\u505A\u4E86\u4EC0\u4E48>"`);
|
|
296119
|
-
} else {
|
|
296553
|
+
} else if (!lastFailed) {
|
|
296120
296554
|
println(`[design] \u53D6\u8D27\uFF1Aoasis design status ${artifactId} --pull\uFF08\u62C9\u5230\u672C\u5730\u76EE\u5F55\u8BFB\uFF0C\u8BFB\u5B8C propose --from-dir \u4EA4\u7A3F\uFF09`);
|
|
296121
296555
|
}
|
|
296122
296556
|
break;
|
|
296123
296557
|
}
|
|
296124
|
-
throw new Error("\u7528\u6CD5\uFF1Aoasis design chat <artifactId> --message <t> [--turn first|continue] [--async]\uFF1Boasis design status <artifactId> [--pull]");
|
|
296558
|
+
throw new Error("\u7528\u6CD5\uFF1Aoasis design chat <artifactId> --message <t> [--turn first|continue] [--async]\uFF1Boasis design status <artifactId> [--pull] [--wait [--wait-timeout <\u5206\u949F>]]");
|
|
296125
296559
|
}
|
|
296126
296560
|
case "merge": {
|
|
296127
296561
|
const artifactId = needPos(positional, 0, "oasis merge <artifactId> [revisionId]");
|
|
@@ -296165,6 +296599,10 @@ ${res.warning}`);
|
|
|
296165
296599
|
note: flags.get("note")
|
|
296166
296600
|
});
|
|
296167
296601
|
println(message);
|
|
296602
|
+
const ignoredNotes = [...EMPTY_OK_NOTE_FLAGS].filter((k2) => flags.has(k2)).map((k2) => `--${k2}`);
|
|
296603
|
+
if (ignoredNotes.length > 0) {
|
|
296604
|
+
println(`\u26A0 ${ignoredNotes.join("\u3001")} \u6CA1\u6709\u88AB\u8BB0\u5F55\uFF1Aoasis conclude \u53EA\u6536 --note\u3002\u8FD9\u51E0\u9879\u8981\u5199\u5728 oasis propose \u4E0A\uFF0C\u4E0B\u6B21\u4EA4\u4ED8\u65F6\u4E00\u8D77\u5E26\u4E0A\u3002`);
|
|
296605
|
+
}
|
|
296168
296606
|
break;
|
|
296169
296607
|
}
|
|
296170
296608
|
case "review": {
|
|
@@ -298214,7 +298652,7 @@ function shimScript() {
|
|
|
298214
298652
|
}
|
|
298215
298653
|
|
|
298216
298654
|
// src/index.ts
|
|
298217
|
-
var PKG_VERSION = true ? "2.2.
|
|
298655
|
+
var PKG_VERSION = true ? "2.2.85" : "dev";
|
|
298218
298656
|
var LOCAL_BIN = localBin();
|
|
298219
298657
|
var NPM_PREFIX = npmPrefix();
|
|
298220
298658
|
var INSTANCE = DEFAULT_INSTANCE;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oasis_test_v2",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.85",
|
|
4
4
|
"description": "Oasis node daemon + CLI — background daemon, auto-start, full server CLI",
|
|
5
5
|
"bin": {
|
|
6
6
|
"oasis": "./dist/index.js"
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
"node": ">=20"
|
|
27
27
|
},
|
|
28
28
|
"oasisRelease": {
|
|
29
|
-
"sourceHead": "
|
|
29
|
+
"sourceHead": "760b80b59c0caa8c7469a804b84360f5ecf3a71a"
|
|
30
30
|
}
|
|
31
31
|
}
|