oasis_test_v2 2.2.83 → 2.2.84
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 +222 -46
- 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
|
}
|
|
@@ -8506,14 +8530,46 @@ async function runACPSession(job, cfg) {
|
|
|
8506
8530
|
let runtimeReportedModel;
|
|
8507
8531
|
let requestedModelAccepted;
|
|
8508
8532
|
const reportedModel = () => pickReportedModel({ runtime: [routedModel, runtimeReportedModel], requested: requestedModelAccepted });
|
|
8533
|
+
let turnIndex = 0;
|
|
8534
|
+
let turnStartedMs = Date.now();
|
|
8535
|
+
let freshSession = true;
|
|
8536
|
+
let routedPollInflight = false;
|
|
8509
8537
|
const pollRoutedModel = async () => {
|
|
8510
|
-
if (
|
|
8511
|
-
if (actualModelId(runtimeReportedModel)) return;
|
|
8538
|
+
if (!cfg.readRoutedModel || !capturedSessionId || exited) return false;
|
|
8539
|
+
if (actualModelId(runtimeReportedModel)) return true;
|
|
8540
|
+
if (routedPollInflight) return false;
|
|
8541
|
+
routedPollInflight = true;
|
|
8542
|
+
const turn = turnIndex;
|
|
8512
8543
|
try {
|
|
8513
|
-
|
|
8544
|
+
const found2 = actualModelId(await cfg.readRoutedModel(capturedSessionId, {
|
|
8545
|
+
turnStartedMs,
|
|
8546
|
+
freshSession
|
|
8547
|
+
}));
|
|
8548
|
+
if (!found2 || turn !== turnIndex) return false;
|
|
8549
|
+
if (found2 !== routedModel) {
|
|
8550
|
+
routedModel = found2;
|
|
8551
|
+
emitUsageCheckpoint();
|
|
8552
|
+
}
|
|
8553
|
+
return true;
|
|
8514
8554
|
} catch {
|
|
8555
|
+
return false;
|
|
8556
|
+
} finally {
|
|
8557
|
+
routedPollInflight = false;
|
|
8515
8558
|
}
|
|
8516
|
-
|
|
8559
|
+
};
|
|
8560
|
+
const ROUTED_MODEL_POLL_DELAYS_MS = [0, 150, 400, 900, 2e3];
|
|
8561
|
+
let routedSamplingTurn = -1;
|
|
8562
|
+
const startRoutedModelSampling = () => {
|
|
8563
|
+
if (!cfg.readRoutedModel || routedSamplingTurn === turnIndex) return;
|
|
8564
|
+
routedSamplingTurn = turnIndex;
|
|
8565
|
+
const turn = turnIndex;
|
|
8566
|
+
void (async () => {
|
|
8567
|
+
for (const delay of ROUTED_MODEL_POLL_DELAYS_MS) {
|
|
8568
|
+
if (delay > 0) await new Promise((r) => setTimeout(r, delay));
|
|
8569
|
+
if (exited || turn !== turnIndex) return;
|
|
8570
|
+
if (await pollRoutedModel()) return;
|
|
8571
|
+
}
|
|
8572
|
+
})();
|
|
8517
8573
|
};
|
|
8518
8574
|
const modelForUsage = () => reportedModel()?.model;
|
|
8519
8575
|
const usageCheckpointCbs = [];
|
|
@@ -8639,11 +8695,15 @@ ${note}` : note };
|
|
|
8639
8695
|
},
|
|
8640
8696
|
(text7) => {
|
|
8641
8697
|
confirmAppendBatch();
|
|
8698
|
+
startRoutedModelSampling();
|
|
8642
8699
|
if (cfg.classifyPromptFailure && turnMessage.length < PROMPT_TURN_MESSAGE_MAX) turnMessage += text7;
|
|
8643
8700
|
for (const cb of outputCbs) cb(text7);
|
|
8644
8701
|
},
|
|
8645
8702
|
(e) => {
|
|
8646
|
-
if (["message", "thought", "tool_use", "tool_result"].includes(e.kind))
|
|
8703
|
+
if (["message", "thought", "tool_use", "tool_result"].includes(e.kind)) {
|
|
8704
|
+
confirmAppendBatch();
|
|
8705
|
+
startRoutedModelSampling();
|
|
8706
|
+
}
|
|
8647
8707
|
for (const cb of telemetryCbs) cb(e);
|
|
8648
8708
|
},
|
|
8649
8709
|
// runtime 自己用 stopReason=cancelled 收尾时也保留取消语义;此前误记成 error,
|
|
@@ -8712,6 +8772,7 @@ ${note}` : note };
|
|
|
8712
8772
|
sessionId = job.runtimeSessionId;
|
|
8713
8773
|
ambiguousResume = true;
|
|
8714
8774
|
}
|
|
8775
|
+
if (sessionId) freshSession = false;
|
|
8715
8776
|
} catch {
|
|
8716
8777
|
sessionId = "";
|
|
8717
8778
|
}
|
|
@@ -8725,6 +8786,7 @@ ${note}` : note };
|
|
|
8725
8786
|
sessionId = extractSessionID(sessionRes);
|
|
8726
8787
|
runtimeReportedModel = extractCurrentModelID(sessionRes) ?? runtimeReportedModel;
|
|
8727
8788
|
if (!sessionId) throw new Error("session/new returned no sessionId");
|
|
8789
|
+
freshSession = true;
|
|
8728
8790
|
}
|
|
8729
8791
|
capturedSessionId = sessionId;
|
|
8730
8792
|
if (resolvedModel2) {
|
|
@@ -8761,6 +8823,8 @@ ${task}` : task;
|
|
|
8761
8823
|
const sendPrompt = async (text7) => {
|
|
8762
8824
|
turnMessage = "";
|
|
8763
8825
|
turnStderr = [];
|
|
8826
|
+
turnIndex += 1;
|
|
8827
|
+
turnStartedMs = Date.now();
|
|
8764
8828
|
const p2 = client.request("session/prompt", { sessionId, prompt: [{ type: "text", text: text7 }] });
|
|
8765
8829
|
inflightStopReason = p2.then((r) => extractStopReason(r), () => "");
|
|
8766
8830
|
try {
|
|
@@ -8780,6 +8844,7 @@ ${task}` : task;
|
|
|
8780
8844
|
sessionId = extractSessionID(sessionRes);
|
|
8781
8845
|
runtimeReportedModel = extractCurrentModelID(sessionRes) ?? runtimeReportedModel;
|
|
8782
8846
|
if (!sessionId) throw new Error("session/new returned no sessionId");
|
|
8847
|
+
freshSession = true;
|
|
8783
8848
|
capturedSessionId = sessionId;
|
|
8784
8849
|
emitUsageCheckpoint();
|
|
8785
8850
|
promptResult = await sendPrompt(userText);
|
|
@@ -9548,14 +9613,59 @@ function pickCursorModelName(value2) {
|
|
|
9548
9613
|
};
|
|
9549
9614
|
return visit(value2, 0) ?? fallback;
|
|
9550
9615
|
}
|
|
9551
|
-
function
|
|
9552
|
-
if (typeof cell !== "string"
|
|
9616
|
+
function parseCell(cell) {
|
|
9617
|
+
if (typeof cell !== "string") return void 0;
|
|
9553
9618
|
try {
|
|
9554
|
-
return
|
|
9619
|
+
return JSON.parse(cell);
|
|
9555
9620
|
} catch {
|
|
9556
9621
|
return void 0;
|
|
9557
9622
|
}
|
|
9558
9623
|
}
|
|
9624
|
+
function looksLikeTimeKey(key2) {
|
|
9625
|
+
const tokens2 = key2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);
|
|
9626
|
+
const last = tokens2[tokens2.length - 1];
|
|
9627
|
+
if (!last || !TIME_KEY_TAILS.includes(last)) return false;
|
|
9628
|
+
return last !== "at" || tokens2.length > 1;
|
|
9629
|
+
}
|
|
9630
|
+
function cursorTimeValueMs(value2) {
|
|
9631
|
+
if (typeof value2 === "bigint") return cursorTimeValueMs(Number(value2));
|
|
9632
|
+
if (typeof value2 === "number") {
|
|
9633
|
+
if (!Number.isFinite(value2)) return void 0;
|
|
9634
|
+
if (value2 > 1e15) return Math.floor(value2 / 1e3);
|
|
9635
|
+
if (value2 > 1e12) return value2;
|
|
9636
|
+
if (value2 > 1e9) return value2 * 1e3;
|
|
9637
|
+
return void 0;
|
|
9638
|
+
}
|
|
9639
|
+
if (typeof value2 === "string") {
|
|
9640
|
+
const t = value2.trim();
|
|
9641
|
+
if (!t) return void 0;
|
|
9642
|
+
if (/^\d+$/.test(t)) return cursorTimeValueMs(Number(t));
|
|
9643
|
+
const ms = Date.parse(t);
|
|
9644
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
9645
|
+
}
|
|
9646
|
+
return void 0;
|
|
9647
|
+
}
|
|
9648
|
+
function cursorRowTimeMs(row, parsedCells) {
|
|
9649
|
+
let best;
|
|
9650
|
+
const take = (v2) => {
|
|
9651
|
+
const ms = cursorTimeValueMs(v2);
|
|
9652
|
+
if (ms !== void 0 && (best === void 0 || ms > best)) best = ms;
|
|
9653
|
+
};
|
|
9654
|
+
for (const [key2, value2] of Object.entries(row)) if (looksLikeTimeKey(key2)) take(value2);
|
|
9655
|
+
const visit = (node2, depth) => {
|
|
9656
|
+
if (depth > 8 || node2 === null || typeof node2 !== "object") return;
|
|
9657
|
+
if (Array.isArray(node2)) {
|
|
9658
|
+
for (const item of node2) visit(item, depth + 1);
|
|
9659
|
+
return;
|
|
9660
|
+
}
|
|
9661
|
+
for (const [key2, value2] of Object.entries(node2)) {
|
|
9662
|
+
if (looksLikeTimeKey(key2)) take(value2);
|
|
9663
|
+
visit(value2, depth + 1);
|
|
9664
|
+
}
|
|
9665
|
+
};
|
|
9666
|
+
for (const parsed of parsedCells) visit(parsed, 0);
|
|
9667
|
+
return best;
|
|
9668
|
+
}
|
|
9559
9669
|
async function openReadOnly(file) {
|
|
9560
9670
|
try {
|
|
9561
9671
|
const sqlite = await import("node:sqlite");
|
|
@@ -9564,7 +9674,9 @@ async function openReadOnly(file) {
|
|
|
9564
9674
|
return null;
|
|
9565
9675
|
}
|
|
9566
9676
|
}
|
|
9567
|
-
async function readCursorRoutedModel(sessionId,
|
|
9677
|
+
async function readCursorRoutedModel(sessionId, window3) {
|
|
9678
|
+
const env = window3.env ?? process.env;
|
|
9679
|
+
const earliest = window3.turnStartedMs - TURN_CLOCK_TOLERANCE_MS;
|
|
9568
9680
|
const file = cursorAcpSessionStorePath(sessionId, env);
|
|
9569
9681
|
if (!file) return void 0;
|
|
9570
9682
|
const db = await openReadOnly(file);
|
|
@@ -9580,10 +9692,17 @@ async function readCursorRoutedModel(sessionId, env = process.env) {
|
|
|
9580
9692
|
continue;
|
|
9581
9693
|
}
|
|
9582
9694
|
for (const row of rows) {
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9695
|
+
const cells = Object.values(row);
|
|
9696
|
+
if (!cells.some((cell) => typeof cell === "string" && cell.includes("modelName"))) continue;
|
|
9697
|
+
const parsed = cells.map(parseCell);
|
|
9698
|
+
const model = parsed.map((value2) => value2 === void 0 ? void 0 : pickCursorModelName(value2)).find((name) => !!name);
|
|
9699
|
+
if (!model) continue;
|
|
9700
|
+
const rowMs = cursorRowTimeMs(row, parsed);
|
|
9701
|
+
if (rowMs !== void 0) {
|
|
9702
|
+
if (rowMs >= earliest) return model;
|
|
9703
|
+
continue;
|
|
9586
9704
|
}
|
|
9705
|
+
if (window3.freshSession) return model;
|
|
9587
9706
|
}
|
|
9588
9707
|
}
|
|
9589
9708
|
return void 0;
|
|
@@ -9596,7 +9715,7 @@ async function readCursorRoutedModel(sessionId, env = process.env) {
|
|
|
9596
9715
|
}
|
|
9597
9716
|
}
|
|
9598
9717
|
}
|
|
9599
|
-
var fs10, os6, path12, MAX_TABLES, MAX_ROWS_PER_TABLE;
|
|
9718
|
+
var fs10, os6, path12, MAX_TABLES, MAX_ROWS_PER_TABLE, TURN_CLOCK_TOLERANCE_MS, TIME_KEY_TAILS;
|
|
9600
9719
|
var init_local_store = __esm({
|
|
9601
9720
|
"../adapters/src/cursor/local-store.ts"() {
|
|
9602
9721
|
"use strict";
|
|
@@ -9605,6 +9724,8 @@ var init_local_store = __esm({
|
|
|
9605
9724
|
path12 = __toESM(require("node:path"), 1);
|
|
9606
9725
|
MAX_TABLES = 24;
|
|
9607
9726
|
MAX_ROWS_PER_TABLE = 200;
|
|
9727
|
+
TURN_CLOCK_TOLERANCE_MS = 1e3;
|
|
9728
|
+
TIME_KEY_TAILS = ["at", "ts", "time", "timestamp", "date", "millis", "epoch"];
|
|
9608
9729
|
}
|
|
9609
9730
|
});
|
|
9610
9731
|
|
|
@@ -9652,7 +9773,7 @@ var init_cursor = __esm({
|
|
|
9652
9773
|
// 采集点 4:「自动」档下 cursor 对外只报 `default[]`(不是型号、查不到价,v2 上 385 条记的就是它),
|
|
9653
9774
|
// 而它自己的 `~/.cursor/acp-sessions/<会话号>/store.db` 里逐条回复都带实际路由到的模型。
|
|
9654
9775
|
// 这是 cursor 的内部格式:读不到就退回会话级自报值,绝不报错(见 local-store.ts)。
|
|
9655
|
-
readRoutedModel: (sessionId) => readCursorRoutedModel(sessionId),
|
|
9776
|
+
readRoutedModel: (sessionId, window3) => readCursorRoutedModel(sessionId, window3),
|
|
9656
9777
|
...this.opts.syncSkills ? { syncSkills: this.opts.syncSkills } : {}
|
|
9657
9778
|
});
|
|
9658
9779
|
}
|
|
@@ -140939,16 +141060,32 @@ ${m2.spec.split("\n").map((l) => ` > ${l}`).join("\n")}`);
|
|
|
140939
141060
|
//
|
|
140940
141061
|
// 这些字段不能成为「没做完也能交」的出口:真正未满足交付标准时继续完成,外部阻塞走 oasis gap。
|
|
140941
141062
|
// 四项本身只传递一份已达标成果的非阻塞残余信息,不参与 conclude 判据。
|
|
140942
|
-
|
|
141063
|
+
//
|
|
141064
|
+
// ★ 2026-09-23(语菲,验收用例 H-01):此前只列参数名、没说挂在哪条命令上,agent 常把它们写到
|
|
141065
|
+
// `oasis conclude` 上——conclude 只收 `--note`,其余参数被静默丢掉(v2 上 143 次执行里写过这四项
|
|
141066
|
+
// 16 次,6 次写在 conclude 上、全丢)。所以点名「是 propose 的参数」并给一条**追加式**示例:
|
|
141067
|
+
// 只示范「在那条命令末尾加上什么」,不给整条 propose——design(交稿目录不是 deliverable/)、
|
|
141068
|
+
// 分批续跑(要带 --checkpoint --continue)各有自己的提交命令,照抄一整条会交错目录或漏参数。
|
|
141069
|
+
// 「没有就连参数名也不写」:只写参数名不跟值会被 parseArgs 拒(CLI 侧已对这四项放宽为空值,
|
|
141070
|
+
// 但未升级的节点包仍会拒),提示词也把这条路堵上。
|
|
141071
|
+
//
|
|
141072
|
+
// 集成会话(integrating || queueTaskDue)不出这段:那一档「怎么提交」明令「绝不要用 oasis propose」,
|
|
141073
|
+
// 而 `oasis integrate` 也不收这四项——再教「这是 propose 的参数」只会把它引去 propose,
|
|
141074
|
+
// 队列从 N 变 N+1、随后 conclude 撞 queue not quiescent(本文件「怎么提交」那段注释记的卡死形状)。
|
|
141075
|
+
...args.action === "review" || integrating || queueTaskDue ? [] : [
|
|
140943
141076
|
``,
|
|
140944
141077
|
`### \u4EA4\u4ED8\u65F6\u7684\u975E\u963B\u585E\u4FE1\u606F`,
|
|
140945
|
-
|
|
140946
|
-
|
|
141078
|
+
`\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`,
|
|
141079
|
+
`\`--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`,
|
|
141080
|
+
`\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
141081
|
`- \`--unresolved\`\uFF1A\u4EFB\u52A1\u8303\u56F4\u4E4B\u5916\u7684\u5DF2\u77E5\u95EE\u9898\uFF1B`,
|
|
140948
141082
|
`- \`--risks\`\uFF1A\u6210\u679C\u53EF\u4EA4\u4ED8\uFF0C\u4F46\u4F7F\u7528\u65F6\u9700\u6CE8\u610F\u7684\u6B8B\u4F59\u98CE\u9669\uFF1B`,
|
|
140949
141083
|
`- \`--gaps\`\uFF1A\u4E0D\u5C5E\u4E8E\u672C\u6B21\u5F3A\u5236\u9A8C\u6536\u6761\u4EF6\u7684\u9A8C\u8BC1\u8303\u56F4\u9650\u5236\uFF1B`,
|
|
140950
141084
|
`- \`--next\`\uFF1A\u4E0B\u6E38\u5982\u4F55\u4F7F\u7528\u6210\u679C\uFF0C\u4E0D\u662F\u4F60\u5269\u4F59\u6CA1\u505A\u7684\u5DE5\u4F5C\u3002`,
|
|
140951
|
-
`\
|
|
141085
|
+
`\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>"\``,
|
|
141086
|
+
`\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`
|
|
141087
|
+
],
|
|
141088
|
+
...args.action === "review" ? [] : [
|
|
140952
141089
|
``,
|
|
140953
141090
|
`### \u4F1A\u8BDD\u53EF\u80FD\u88AB\u780D\uFF1A\u4E2D\u9014\u7559\u4E2A\u65AD\u70B9`,
|
|
140954
141091
|
// ★ 2026-08-18:`continuity-checkpoint` 此前在任务书里出现 **0 次**——说明书只在
|
|
@@ -227247,14 +227384,13 @@ function frameTokenTotal(usage) {
|
|
|
227247
227384
|
return (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0) + (usage.cacheReadTokens ?? 0) + (usage.cacheCreationTokens ?? 0);
|
|
227248
227385
|
}
|
|
227249
227386
|
async function backfillRunModel(target, run, model, modelSource, warn) {
|
|
227250
|
-
const
|
|
227251
|
-
|
|
227252
|
-
|
|
227387
|
+
const patch = preferRunModel(
|
|
227388
|
+
{ effectiveModel: run.effectiveModel, modelSource: run.modelSource },
|
|
227389
|
+
{ effectiveModel: model, modelSource: modelSource === "requested" ? "requested" : "runtime" }
|
|
227390
|
+
);
|
|
227391
|
+
if (!patch) return;
|
|
227253
227392
|
try {
|
|
227254
|
-
await target.store.updateRun(target.runId,
|
|
227255
|
-
effectiveModel,
|
|
227256
|
-
modelSource: modelSource === "requested" ? "requested" : "runtime"
|
|
227257
|
-
});
|
|
227393
|
+
await target.store.updateRun(target.runId, patch);
|
|
227258
227394
|
} catch (err) {
|
|
227259
227395
|
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
227396
|
}
|
|
@@ -228020,8 +228156,10 @@ var init_sink = __esm({
|
|
|
228020
228156
|
const isErr = status === "failed" || status === "timeout";
|
|
228021
228157
|
const errorFields = isErr ? { errorCode: update.exit.reason ?? "error", errorMessage: formatExitError(update.exit) } : {};
|
|
228022
228158
|
const exitModel = actualModelId(update.exit.model);
|
|
228023
|
-
const
|
|
228024
|
-
const
|
|
228159
|
+
const observedModel = actualModelId(st.observedModel);
|
|
228160
|
+
const exitIsRequestedOnly = update.exit.modelSource === "requested";
|
|
228161
|
+
const model = (exitIsRequestedOnly ? observedModel ?? exitModel : exitModel ?? observedModel) ?? null;
|
|
228162
|
+
const modelSource = model && model === exitModel && exitIsRequestedOnly && !observedModel ? "requested" : "runtime";
|
|
228025
228163
|
const exitRtId = typeof update.exit.runtimeSessionId === "string" && update.exit.runtimeSessionId.trim() ? update.exit.runtimeSessionId.trim() : void 0;
|
|
228026
228164
|
if (exitRtId) st.baseMetadata = { ...st.baseMetadata, runtimeSessionId: exitRtId };
|
|
228027
228165
|
const exitWorkdir = typeof update.exit.workdirRef === "string" && update.exit.workdirRef.trim() ? update.exit.workdirRef.trim() : void 0;
|
|
@@ -228052,6 +228190,12 @@ var init_sink = __esm({
|
|
|
228052
228190
|
createdAt: update.exit.at
|
|
228053
228191
|
});
|
|
228054
228192
|
}
|
|
228193
|
+
const currentRun = model ? await this.store.getRun(st.runId).catch(() => null) : null;
|
|
228194
|
+
const modelPatch = model ? preferRunModel(
|
|
228195
|
+
{ effectiveModel: currentRun?.effectiveModel, modelSource: currentRun?.modelSource },
|
|
228196
|
+
{ effectiveModel: model, modelSource },
|
|
228197
|
+
"replace"
|
|
228198
|
+
) : null;
|
|
228055
228199
|
const finished = await this.store.updateRun(st.runId, {
|
|
228056
228200
|
status,
|
|
228057
228201
|
endedAt: update.exit.at,
|
|
@@ -228067,7 +228211,7 @@ var init_sink = __esm({
|
|
|
228067
228211
|
// token/成本来自 adapter 解析 stream-json(含 cache);不带则不写、保持 null。
|
|
228068
228212
|
...update.exit.usage ? { usage: update.exit.usage } : {},
|
|
228069
228213
|
// effectiveModel/modelSource 喂用量聚合(聚合键含 model);与 chat/finishRun 路径一致。
|
|
228070
|
-
...
|
|
228214
|
+
...modelPatch ?? {},
|
|
228071
228215
|
// metadata 整列替换:必须带上 baseMetadata(bundleManifest/runtimeSessionId)一起写回。
|
|
228072
228216
|
// model 有则并入(前端 findModelInValue 直接读 metadata.model)。**不能只在有 model 时才写**
|
|
228073
228217
|
// ——否则无 model 的 run(如回捕型 runtime 没报模型)会把 exit 校正过的会话号丢掉。
|
|
@@ -228422,10 +228566,8 @@ function wireRecoveredChatTurn(deps) {
|
|
|
228422
228566
|
live.emit({ type: "done", ...plan.runtimeSessionId ? { sessionId: plan.runtimeSessionId } : {} });
|
|
228423
228567
|
live.finish(failed ? "error" : "done");
|
|
228424
228568
|
deps.unregister();
|
|
228425
|
-
const
|
|
228426
|
-
|
|
228427
|
-
info.runtimeSessionId
|
|
228428
|
-
) : void 0;
|
|
228569
|
+
const currentRun = await trace.getRun(plan.runId).catch(() => null);
|
|
228570
|
+
const nativeSessionMetadata = info.runtimeSessionId && info.runtimeSessionId !== plan.runtimeSessionId ? nativeRuntimeSessionMetadata(currentRun?.metadata, info.runtimeSessionId) : void 0;
|
|
228429
228571
|
enqueueTrace(async () => {
|
|
228430
228572
|
await appender.append([{
|
|
228431
228573
|
eventType: "run.finished",
|
|
@@ -228434,7 +228576,7 @@ function wireRecoveredChatTurn(deps) {
|
|
|
228434
228576
|
startedAt: finishedAt
|
|
228435
228577
|
}]);
|
|
228436
228578
|
await appender.update({
|
|
228437
|
-
...runTerminalPatch(info, plan.startedAt, finishedAt),
|
|
228579
|
+
...runTerminalPatch(info, plan.startedAt, finishedAt, currentRun),
|
|
228438
228580
|
// 运行时自己退干净了,但平台没把输出接全——运行记录不许写「成功」(Bug 0123)。
|
|
228439
228581
|
// 退出帧本身已经是失败时保持它的归因,只补一句缺口说明。
|
|
228440
228582
|
...outputGapRunPatch(droppedFrames, exitIsFailure, info),
|
|
@@ -228658,7 +228800,7 @@ async function reconcileChatExitFrame(deps) {
|
|
|
228658
228800
|
];
|
|
228659
228801
|
await deps.trace.appendEvents(row.runId, seqless.map((e, i) => ({ ...e, seq: baseSeq + i + 1 })));
|
|
228660
228802
|
await deps.trace.updateRun(row.runId, {
|
|
228661
|
-
...runTerminalPatch(info, run.startedAt, finishedAt),
|
|
228803
|
+
...runTerminalPatch(info, run.startedAt, finishedAt, run),
|
|
228662
228804
|
...outputGapRunPatch(droppedFrames, exitIsFailure, info),
|
|
228663
228805
|
// 首轮占位会话号 → runtime 报回的原生号(Bug 0171,判据见本函数上方那一段)。
|
|
228664
228806
|
...nativeSessionMetadata ? { metadata: nativeSessionMetadata } : {}
|
|
@@ -228887,6 +229029,7 @@ var init_chat_recovery = __esm({
|
|
|
228887
229029
|
"use strict";
|
|
228888
229030
|
init_file_restore();
|
|
228889
229031
|
init_continuation3();
|
|
229032
|
+
init_src();
|
|
228890
229033
|
init_chat_parts();
|
|
228891
229034
|
init_sink();
|
|
228892
229035
|
init_usage_ledger();
|
|
@@ -228914,7 +229057,7 @@ var init_chat_recovery = __esm({
|
|
|
228914
229057
|
const existing = formatExitError(info);
|
|
228915
229058
|
return { errorMessage: existing ? `${existing}\uFF1B${gap}` : gap };
|
|
228916
229059
|
};
|
|
228917
|
-
runTerminalPatch = (info, startedAt, endedAt) => ({
|
|
229060
|
+
runTerminalPatch = (info, startedAt, endedAt, current) => ({
|
|
228918
229061
|
status: classifySessionExitStatus(info),
|
|
228919
229062
|
endedAt,
|
|
228920
229063
|
durationMs: Date.parse(endedAt) - Date.parse(startedAt),
|
|
@@ -228927,7 +229070,11 @@ var init_chat_recovery = __esm({
|
|
|
228927
229070
|
// 不能用 null 覆盖,否则恢复轮的 token 会掉进「未知模型」桶。
|
|
228928
229071
|
// 伪型号(`default[]` / `auto`)不是模型名,不写;请求值(`requested`)与实际值分开记来源
|
|
228929
229072
|
// ——重挂路与 chat 主路、派发路三处必须同一判据,否则同一条 run 换条路收尾归属就变了。
|
|
228930
|
-
...
|
|
229073
|
+
...preferRunModel(
|
|
229074
|
+
{ effectiveModel: current?.effectiveModel, modelSource: current?.modelSource },
|
|
229075
|
+
chatExitModelFields(info.model, null, null, info.modelSource),
|
|
229076
|
+
"replace"
|
|
229077
|
+
) ?? {}
|
|
228931
229078
|
});
|
|
228932
229079
|
}
|
|
228933
229080
|
});
|
|
@@ -248171,8 +248318,16 @@ var init_service8 = __esm({
|
|
|
248171
248318
|
errorCode: input.errorCode ?? null,
|
|
248172
248319
|
errorMessage: input.errorMessage ?? null,
|
|
248173
248320
|
usage: input.usage ?? null,
|
|
248174
|
-
|
|
248175
|
-
|
|
248321
|
+
// 模型那两格按取值优先级挑(上游诊断 ④),不是无条件「收尾值优先」:`input` 里可能只剩
|
|
248322
|
+
// 请求值(claude 一条 init 都没吐就退出、ACP `set_model` 被接受但运行时从没回报),
|
|
248323
|
+
// 而 run 行上可能已经由运行中检查点补上了运行时回报的**实际值**——请求值顶掉实际值,
|
|
248324
|
+
// 这一轮就永远记在一个没跑过的型号头上(PR #2213 评审阻断项 1)。同档以收尾值为准
|
|
248325
|
+
// (`replace`):收尾只写一次,且它是这一轮解析链的最终结论。
|
|
248326
|
+
...preferRunModel(
|
|
248327
|
+
{ effectiveModel: run.effectiveModel, modelSource: run.modelSource },
|
|
248328
|
+
{ effectiveModel: input.effectiveModel, modelSource: input.modelSource },
|
|
248329
|
+
"replace"
|
|
248330
|
+
) ?? { effectiveModel: run.effectiveModel ?? null, modelSource: run.modelSource ?? null },
|
|
248176
248331
|
transcriptRef: input.transcriptRef ?? null
|
|
248177
248332
|
};
|
|
248178
248333
|
const updated = await this.store.updateRun(id, patch);
|
|
@@ -286195,7 +286350,13 @@ async function startServe(opts) {
|
|
|
286195
286350
|
metadata: { ...base, dispatchId: handle.id },
|
|
286196
286351
|
// 恢复路径拿不到 dispatchChat 闭包里的 fallback 解析结果,开跑时先写进账本;退出帧若上报
|
|
286197
286352
|
// 更精确 model 仍会覆盖为 runtime 来源。
|
|
286198
|
-
|
|
286353
|
+
// 这是**请求值**(会话选择 / 员工配置 / runtime 默认),按 ④ 排在实际值之下:采集点 1 的
|
|
286354
|
+
// 首帧检查点可能已经先一步把运行时回报的实际值写进这一行(两条路都是异步入队,谁先到不定),
|
|
286355
|
+
// 预写不能把它顶掉。
|
|
286356
|
+
...preferRunModel(
|
|
286357
|
+
{ effectiveModel: run.effectiveModel, modelSource: run.modelSource },
|
|
286358
|
+
{ effectiveModel: chatModel, modelSource: chatModelSource }
|
|
286359
|
+
) ?? {}
|
|
286199
286360
|
});
|
|
286200
286361
|
});
|
|
286201
286362
|
const buffered = [];
|
|
@@ -286267,11 +286428,17 @@ async function startServe(opts) {
|
|
|
286267
286428
|
}]);
|
|
286268
286429
|
const usage = info.usage ?? null;
|
|
286269
286430
|
const modelFields = chatExitModelFields(info.model, chatModel, chatModelSource, info.modelSource);
|
|
286431
|
+
const needsNativeSessionMetadata = !!info.runtimeSessionId && info.runtimeSessionId !== runtimeSessionId;
|
|
286432
|
+
const currentRun = needsNativeSessionMetadata || "effectiveModel" in modelFields ? await (await traceStoreFor(runCompanyId)).getRun(traceRunId).catch(() => null) : null;
|
|
286270
286433
|
let nativeSessionMetadata;
|
|
286271
|
-
if (
|
|
286272
|
-
|
|
286273
|
-
nativeSessionMetadata = nativeRuntimeSessionMetadata(run?.metadata, info.runtimeSessionId);
|
|
286434
|
+
if (needsNativeSessionMetadata) {
|
|
286435
|
+
nativeSessionMetadata = nativeRuntimeSessionMetadata(currentRun?.metadata, info.runtimeSessionId);
|
|
286274
286436
|
}
|
|
286437
|
+
const modelPatch = preferRunModel(
|
|
286438
|
+
{ effectiveModel: currentRun?.effectiveModel, modelSource: currentRun?.modelSource },
|
|
286439
|
+
{ effectiveModel: modelFields.effectiveModel, modelSource: modelFields.modelSource },
|
|
286440
|
+
"replace"
|
|
286441
|
+
) ?? {};
|
|
286275
286442
|
await traceAppender.update({
|
|
286276
286443
|
status: classifySessionExitStatus(info),
|
|
286277
286444
|
endedAt,
|
|
@@ -286281,7 +286448,7 @@ async function startServe(opts) {
|
|
|
286281
286448
|
...!isHealthySessionExit(info) && info.reason !== "cancelled" ? { errorCode: info.reason ?? "error", errorMessage: formatExitError(info) } : {},
|
|
286282
286449
|
transcriptRef: info.transcriptRef ?? null,
|
|
286283
286450
|
usage,
|
|
286284
|
-
...
|
|
286451
|
+
...modelPatch,
|
|
286285
286452
|
...nativeSessionMetadata ? { metadata: nativeSessionMetadata } : {}
|
|
286286
286453
|
});
|
|
286287
286454
|
if (usage) await settleRunUsage(await traceStoreFor(runCompanyId), traceRunId);
|
|
@@ -294035,6 +294202,7 @@ ${buildCommandIndex()}
|
|
|
294035
294202
|
${USAGE_FOOTER}`;
|
|
294036
294203
|
var COMMAND_HELP = buildCommandHelp();
|
|
294037
294204
|
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";
|
|
294205
|
+
var EMPTY_OK_NOTE_FLAGS = /* @__PURE__ */ new Set(["unresolved", "risks", "gaps", "next"]);
|
|
294038
294206
|
function parseArgs(argv) {
|
|
294039
294207
|
const positional = [];
|
|
294040
294208
|
const flags = /* @__PURE__ */ new Map();
|
|
@@ -294061,6 +294229,10 @@ function parseArgs(argv) {
|
|
|
294061
294229
|
const value2 = argv[i + 1];
|
|
294062
294230
|
const key2 = a.slice(2);
|
|
294063
294231
|
if (value2 === void 0 || value2.startsWith("--")) {
|
|
294232
|
+
if (EMPTY_OK_NOTE_FLAGS.has(key2)) {
|
|
294233
|
+
flags.set(key2, "");
|
|
294234
|
+
continue;
|
|
294235
|
+
}
|
|
294064
294236
|
if (!booleanFlags.has(key2)) throw new Error(`flag ${a} \u9700\u8981\u4E00\u4E2A\u503C`);
|
|
294065
294237
|
flags.set(key2, "true");
|
|
294066
294238
|
} else {
|
|
@@ -294298,7 +294470,7 @@ async function waitForCommandAuthorization(base, headers, draftId, fallback) {
|
|
|
294298
294470
|
}
|
|
294299
294471
|
}
|
|
294300
294472
|
}
|
|
294301
|
-
var CLI_VERSION = "2.2.
|
|
294473
|
+
var CLI_VERSION = "2.2.84" ? "2.2.84" : "dev";
|
|
294302
294474
|
function apiHeaders(token, company) {
|
|
294303
294475
|
const headers = {
|
|
294304
294476
|
authorization: `Bearer ${token}`,
|
|
@@ -296165,6 +296337,10 @@ ${res.warning}`);
|
|
|
296165
296337
|
note: flags.get("note")
|
|
296166
296338
|
});
|
|
296167
296339
|
println(message);
|
|
296340
|
+
const ignoredNotes = [...EMPTY_OK_NOTE_FLAGS].filter((k2) => flags.has(k2)).map((k2) => `--${k2}`);
|
|
296341
|
+
if (ignoredNotes.length > 0) {
|
|
296342
|
+
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`);
|
|
296343
|
+
}
|
|
296168
296344
|
break;
|
|
296169
296345
|
}
|
|
296170
296346
|
case "review": {
|
|
@@ -298214,7 +298390,7 @@ function shimScript() {
|
|
|
298214
298390
|
}
|
|
298215
298391
|
|
|
298216
298392
|
// src/index.ts
|
|
298217
|
-
var PKG_VERSION = true ? "2.2.
|
|
298393
|
+
var PKG_VERSION = true ? "2.2.84" : "dev";
|
|
298218
298394
|
var LOCAL_BIN = localBin();
|
|
298219
298395
|
var NPM_PREFIX = npmPrefix();
|
|
298220
298396
|
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.84",
|
|
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": "aa2e3257b82571a32312b457698fdbe5e223d970"
|
|
30
30
|
}
|
|
31
31
|
}
|