oasis_test 0.1.110 → 0.1.111
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 +159 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -171332,6 +171332,79 @@ var init_orphan_sweep = __esm({
|
|
|
171332
171332
|
}
|
|
171333
171333
|
});
|
|
171334
171334
|
|
|
171335
|
+
// ../server/src/zero-output-breaker.ts
|
|
171336
|
+
async function scanZeroOutputBreaker(deps) {
|
|
171337
|
+
const tripped = [];
|
|
171338
|
+
const skipped = [];
|
|
171339
|
+
const countEnabled = deps.threshold > 0;
|
|
171340
|
+
const costEnabled = (deps.costThresholdMicros ?? 0) > 0;
|
|
171341
|
+
if (!countEnabled && !costEnabled) return { tripped, skipped };
|
|
171342
|
+
const sinceIso = new Date(deps.now - deps.windowMs).toISOString();
|
|
171343
|
+
const runs = await deps.listRecentZeroOutputRuns(sinceIso);
|
|
171344
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
171345
|
+
for (const r of runs) {
|
|
171346
|
+
if (r.artifactId === null) continue;
|
|
171347
|
+
if (!deps.actions.has(r.action ?? "")) continue;
|
|
171348
|
+
const startedMs = Date.parse(r.startedAt);
|
|
171349
|
+
if (!Number.isFinite(startedMs)) continue;
|
|
171350
|
+
const b2 = buckets.get(r.artifactId);
|
|
171351
|
+
if (!b2) {
|
|
171352
|
+
buckets.set(r.artifactId, {
|
|
171353
|
+
count: 1,
|
|
171354
|
+
costUsdMicros: r.costUsdMicros ?? 0,
|
|
171355
|
+
latestRunId: r.id,
|
|
171356
|
+
latestStartedMs: startedMs
|
|
171357
|
+
});
|
|
171358
|
+
} else {
|
|
171359
|
+
b2.count += 1;
|
|
171360
|
+
b2.costUsdMicros += r.costUsdMicros ?? 0;
|
|
171361
|
+
if (startedMs >= b2.latestStartedMs) {
|
|
171362
|
+
b2.latestStartedMs = startedMs;
|
|
171363
|
+
b2.latestRunId = r.id;
|
|
171364
|
+
}
|
|
171365
|
+
}
|
|
171366
|
+
}
|
|
171367
|
+
for (const [artifactId, b2] of buckets) {
|
|
171368
|
+
const hitCount = countEnabled && b2.count >= deps.threshold;
|
|
171369
|
+
const hitCost = costEnabled && b2.costUsdMicros >= (deps.costThresholdMicros ?? 0);
|
|
171370
|
+
if (!hitCount && !hitCost) continue;
|
|
171371
|
+
if (deps.isHeld(artifactId) || deps.hasOpenEscalation?.(artifactId)) {
|
|
171372
|
+
skipped.push(artifactId);
|
|
171373
|
+
continue;
|
|
171374
|
+
}
|
|
171375
|
+
const closingRemark = await deps.closingRemarkOf(b2.latestRunId).catch(() => null);
|
|
171376
|
+
await deps.trip({
|
|
171377
|
+
artifactId,
|
|
171378
|
+
count: b2.count,
|
|
171379
|
+
costUsdMicros: b2.costUsdMicros,
|
|
171380
|
+
windowMs: deps.windowMs,
|
|
171381
|
+
latestRunId: b2.latestRunId,
|
|
171382
|
+
closingRemark
|
|
171383
|
+
});
|
|
171384
|
+
tripped.push(artifactId);
|
|
171385
|
+
deps.log?.(
|
|
171386
|
+
`[zero-output-breaker] ${artifactId}\uFF1A\u6700\u8FD1 ${Math.round(deps.windowMs / 6e4)} \u5206\u949F\u5185\u7D2F\u8BA1 ${b2.count} \u6B21\u96F6\u4EA7\u51FA\uFF08\u7EA6 $${(b2.costUsdMicros / 1e6).toFixed(1)}\uFF09\u2192 hold + \u6295\u9012\u6536\u4EF6\u7BB1`
|
|
171387
|
+
);
|
|
171388
|
+
}
|
|
171389
|
+
return { tripped, skipped };
|
|
171390
|
+
}
|
|
171391
|
+
function formatZeroOutputNotice(t) {
|
|
171392
|
+
const usd2 = (t.costUsdMicros / 1e6).toFixed(1);
|
|
171393
|
+
const mins = Math.round(t.windowMs / 6e4);
|
|
171394
|
+
const remark = t.closingRemark && t.closingRemark.trim() ? `
|
|
171395
|
+
|
|
171396
|
+
\u6700\u8FD1\u4E00\u6B21\u8FD0\u884C\u7684\u6536\u5C3E\u53D1\u8A00\uFF08\u5F80\u5F80\u76F4\u63A5\u5199\u7740\u5361\u5728\u54EA\uFF09\uFF1A
|
|
171397
|
+
${t.closingRemark.trim()}` : "";
|
|
171398
|
+
return `\u8FD9\u4E2A\u4EA7\u7269\u5728\u6700\u8FD1 ${mins} \u5206\u949F\u5185\u88AB\u53CD\u590D\u53EB\u9192\u3001\u7D2F\u8BA1\u6709 ${t.count} \u6B21\u8FD0\u884C**\u4EC0\u4E48\u90FD\u6CA1\u4EA4\u51FA\u6765**\uFF08\u8FD9\u4E9B\u7A7A\u8DD1\u7D2F\u8BA1\u82B1\u8D39\u7EA6 $${usd2}\uFF09\uFF0C\u5DF2\u81EA\u52A8\u6682\u505C\u6D3E\u53D1\u4EE5\u6B62\u635F\u3002
|
|
171399
|
+
|
|
171400
|
+
\u8FD9\u4E0D\u662F\u5728\u5224\u67D0\u4E00\u6B21\u8FD0\u884C\u5931\u8D25\u2014\u2014\u662F\u540C\u4E00\u4E2A\u4EA7\u7269\u5728\u8FD9\u6BB5\u65F6\u95F4\u91CC\u53CD\u590D\u96F6\u4EA7\u51FA\u3002\u65E0\u8BBA\u6BCF\u4E00\u6B21\u9000\u51FA\u591A\u4E48\u300C\u6B63\u5E38\u300D\uFF0C\u53CD\u590D\u5230\u8FD9\u4E2A\u6B21\u6570\u901A\u5E38\u610F\u5473\u7740\u5B83\u5361\u5728\u4E00\u4E2A\u53CD\u590D\u91CD\u8BD5\u4E5F\u8FC7\u4E0D\u53BB\u7684\u574E\u4E0A\uFF08\u7F3A\u51ED\u636E\u3001\u4E0A\u6E38\u670D\u52A1\u8FDE\u4E0D\u4E0A\u3001\u6216\u649E\u4E0A\u4E86\u522B\u7684\u6B7B\u5FAA\u73AF\uFF09\u3002\u8BF7\u770B\u4E00\u773C\u6839\u56E0\uFF1B\u5904\u7406\u5B8C\u7528 \`oasis release\` \u6062\u590D\u6D3E\u53D1\u3002` + remark;
|
|
171401
|
+
}
|
|
171402
|
+
var init_zero_output_breaker = __esm({
|
|
171403
|
+
"../server/src/zero-output-breaker.ts"() {
|
|
171404
|
+
"use strict";
|
|
171405
|
+
}
|
|
171406
|
+
});
|
|
171407
|
+
|
|
171335
171408
|
// ../server/src/session-exit-outcome.ts
|
|
171336
171409
|
function isHealthySessionExit(info) {
|
|
171337
171410
|
return info.code === 0 && (info.reason === void 0 || info.reason === "clean");
|
|
@@ -188101,6 +188174,7 @@ var init_src9 = __esm({
|
|
|
188101
188174
|
init_roles_seed();
|
|
188102
188175
|
init_liveness();
|
|
188103
188176
|
init_orphan_sweep();
|
|
188177
|
+
init_zero_output_breaker();
|
|
188104
188178
|
init_dispatch_exit_reconcile();
|
|
188105
188179
|
init_session_exit_outcome();
|
|
188106
188180
|
init_api_activity();
|
|
@@ -197829,6 +197903,7 @@ ${st.detail}
|
|
|
197829
197903
|
let coordTimer;
|
|
197830
197904
|
let livenessTimer;
|
|
197831
197905
|
let orphanSweepTimer;
|
|
197906
|
+
let zeroOutputBreakerTimer;
|
|
197832
197907
|
if (opts.dispatch) {
|
|
197833
197908
|
const coordinator = new CoordinatorWorker({
|
|
197834
197909
|
kernel,
|
|
@@ -198018,6 +198093,80 @@ ${st.detail}
|
|
|
198018
198093
|
}).catch((err) => console.error(`[orphan-sweep] tick \u5931\u8D25: ${String(err)}`));
|
|
198019
198094
|
}, orphanIntervalMs);
|
|
198020
198095
|
}
|
|
198096
|
+
const zbFlag = (process.env["OASIS_ZERO_OUTPUT_BREAKER"] ?? "").trim().toLowerCase();
|
|
198097
|
+
const zbDisabledByEnv = ["0", "false", "off"].includes(zbFlag);
|
|
198098
|
+
const envInt = (name) => {
|
|
198099
|
+
const raw = process.env[name];
|
|
198100
|
+
if (raw === void 0 || raw.trim() === "") return void 0;
|
|
198101
|
+
const n = Number(raw.trim());
|
|
198102
|
+
return Number.isFinite(n) && n >= 0 ? n : void 0;
|
|
198103
|
+
};
|
|
198104
|
+
const zbEnabled = opts.zeroOutputBreaker?.enabled ?? !zbDisabledByEnv;
|
|
198105
|
+
const zbIntervalMs = opts.zeroOutputBreaker?.intervalMs ?? 3e4;
|
|
198106
|
+
const zbWindowMs = opts.zeroOutputBreaker?.windowMs ?? (envInt("OASIS_ZERO_OUTPUT_BREAKER_WINDOW_MIN") ?? 30) * 6e4;
|
|
198107
|
+
const zbThreshold = opts.zeroOutputBreaker?.threshold ?? envInt("OASIS_ZERO_OUTPUT_BREAKER_N") ?? 5;
|
|
198108
|
+
const zbCostThresholdMicros = opts.zeroOutputBreaker?.costThresholdMicros ?? (envInt("OASIS_ZERO_OUTPUT_BREAKER_COST_USD") ?? 0) * 1e6;
|
|
198109
|
+
if (zbEnabled && zbIntervalMs > 0 && (zbThreshold > 0 || zbCostThresholdMicros > 0)) {
|
|
198110
|
+
const zbActions = /* @__PURE__ */ new Set(["produce", "review"]);
|
|
198111
|
+
const listRecentZeroOutputRuns = async (sinceIso) => {
|
|
198112
|
+
const page = await traceStore.listRuns({ status: "no-output", from: sinceIso, limit: 1e3 });
|
|
198113
|
+
if (page.nextCursor) console.warn("[zero-output-breaker] no-output run \u8D85 1000 \u6761\u672A\u7FFB\u9875\uFF0C\u672C\u62CD\u53EA\u626B\u9996\u9875");
|
|
198114
|
+
return page.items.map((r) => ({
|
|
198115
|
+
id: r.id,
|
|
198116
|
+
artifactId: r.artifactId,
|
|
198117
|
+
action: r.action,
|
|
198118
|
+
startedAt: r.startedAt,
|
|
198119
|
+
costUsdMicros: r.usage?.costUsdMicros ?? null
|
|
198120
|
+
}));
|
|
198121
|
+
};
|
|
198122
|
+
const latestClosingRemark = async (runId) => {
|
|
198123
|
+
try {
|
|
198124
|
+
let afterSeq = 0;
|
|
198125
|
+
let last = null;
|
|
198126
|
+
let scanned = 0;
|
|
198127
|
+
for (; ; ) {
|
|
198128
|
+
const rows = await traceStore.listEvents(runId, { afterSeq, limit: 500 });
|
|
198129
|
+
if (rows.length === 0) break;
|
|
198130
|
+
for (const e of rows) {
|
|
198131
|
+
if (e.stream !== "model") continue;
|
|
198132
|
+
const payload = e.payload && typeof e.payload === "object" && !Array.isArray(e.payload) ? e.payload : {};
|
|
198133
|
+
const raw = payload["raw"] && typeof payload["raw"] === "object" && !Array.isArray(payload["raw"]) ? payload["raw"] : {};
|
|
198134
|
+
const kind = payload["kind"] ?? raw["kind"];
|
|
198135
|
+
if (kind === "thought") continue;
|
|
198136
|
+
const text = typeof raw["text"] === "string" ? raw["text"] : typeof e.message === "string" ? e.message : null;
|
|
198137
|
+
if (text && text.trim()) last = text;
|
|
198138
|
+
}
|
|
198139
|
+
afterSeq = rows[rows.length - 1].seq;
|
|
198140
|
+
scanned += rows.length;
|
|
198141
|
+
if (rows.length < 500 || scanned >= 5e3) break;
|
|
198142
|
+
}
|
|
198143
|
+
return last ? last.trim().slice(0, 500) : null;
|
|
198144
|
+
} catch {
|
|
198145
|
+
return null;
|
|
198146
|
+
}
|
|
198147
|
+
};
|
|
198148
|
+
zeroOutputBreakerTimer = setInterval(() => {
|
|
198149
|
+
void scanZeroOutputBreaker({
|
|
198150
|
+
now: Date.now(),
|
|
198151
|
+
windowMs: zbWindowMs,
|
|
198152
|
+
threshold: zbThreshold,
|
|
198153
|
+
costThresholdMicros: zbCostThresholdMicros,
|
|
198154
|
+
actions: zbActions,
|
|
198155
|
+
listRecentZeroOutputRuns,
|
|
198156
|
+
isHeld: (artifactId) => isHeld(kernel.model, artifactId),
|
|
198157
|
+
hasOpenEscalation: (artifactId) => unresolvedEscalationsOf(kernel.model, artifactId).length > 0,
|
|
198158
|
+
closingRemarkOf: latestClosingRemark,
|
|
198159
|
+
// 复用 SLA 同一止损出口:escalate(进收件箱)+ hold(source:"sla",挡派发不锁内容)+ 去重。
|
|
198160
|
+
trip: (t) => escalateHold(t.artifactId, formatZeroOutputNotice(t), "\u96F6\u4EA7\u51FA\u4FDD\u9669\u4E1D"),
|
|
198161
|
+
log: (m2) => console.log(m2)
|
|
198162
|
+
}).catch((err) => console.error(`[zero-output-breaker] tick \u5931\u8D25: ${String(err)}`));
|
|
198163
|
+
}, zbIntervalMs);
|
|
198164
|
+
console.log(
|
|
198165
|
+
`[serve] \u96F6\u4EA7\u51FA\u4FDD\u9669\u4E1D\uFF1A\u7A97\u53E3 ${Math.round(zbWindowMs / 6e4)}min\u3001N=${zbThreshold}${zbCostThresholdMicros > 0 ? `\u3001\u82B1\u8D39\u9608\u503C $${(zbCostThresholdMicros / 1e6).toFixed(0)}` : ""}\u3001\u5468\u671F ${Math.round(zbIntervalMs / 1e3)}s`
|
|
198166
|
+
);
|
|
198167
|
+
} else {
|
|
198168
|
+
console.log("[serve] \u96F6\u4EA7\u51FA\u4FDD\u9669\u4E1D\uFF1A\u5DF2\u5173\u95ED");
|
|
198169
|
+
}
|
|
198021
198170
|
}
|
|
198022
198171
|
const automationScheduler = new AutomationScheduler({
|
|
198023
198172
|
store: automationStore,
|
|
@@ -198050,6 +198199,7 @@ ${st.detail}
|
|
|
198050
198199
|
if (coordTimer) clearInterval(coordTimer);
|
|
198051
198200
|
if (livenessTimer) clearInterval(livenessTimer);
|
|
198052
198201
|
if (orphanSweepTimer) clearInterval(orphanSweepTimer);
|
|
198202
|
+
if (zeroOutputBreakerTimer) clearInterval(zeroOutputBreakerTimer);
|
|
198053
198203
|
clearInterval(automationTimer);
|
|
198054
198204
|
if (boardWatchTimer) clearInterval(boardWatchTimer);
|
|
198055
198205
|
clearInterval(serverHeartbeatTimer);
|
|
@@ -198141,13 +198291,14 @@ var KNOWN2 = [
|
|
|
198141
198291
|
{ adapter: "antigravity", binary: "agy" }
|
|
198142
198292
|
];
|
|
198143
198293
|
var NATIVE_APPEND_RUNTIMES = /* @__PURE__ */ new Set(["hermes", "gemini", "kimi", "kiro", "reasonix"]);
|
|
198144
|
-
function
|
|
198294
|
+
function resolveOnPath(binary) {
|
|
198145
198295
|
try {
|
|
198146
198296
|
const cmd = process.platform === "win32" ? "where" : "which";
|
|
198147
|
-
(0, import_node_child_process15.execFileSync)(cmd, [binary], { stdio: "ignore" });
|
|
198148
|
-
|
|
198297
|
+
const out = (0, import_node_child_process15.execFileSync)(cmd, [binary], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
198298
|
+
const first = out.split("\n")[0]?.trim();
|
|
198299
|
+
return first || binary;
|
|
198149
198300
|
} catch {
|
|
198150
|
-
return
|
|
198301
|
+
return void 0;
|
|
198151
198302
|
}
|
|
198152
198303
|
}
|
|
198153
198304
|
function versionOf(binary) {
|
|
@@ -198162,11 +198313,11 @@ function versionOf(binary) {
|
|
|
198162
198313
|
}
|
|
198163
198314
|
}
|
|
198164
198315
|
function detectRuntimes() {
|
|
198165
|
-
return KNOWN2.
|
|
198166
|
-
const version2 = versionOf(e.
|
|
198316
|
+
return KNOWN2.map((e) => ({ ...e, resolved: resolveOnPath(e.binary) })).filter((e) => e.resolved !== void 0).map((e) => {
|
|
198317
|
+
const version2 = versionOf(e.resolved);
|
|
198167
198318
|
return {
|
|
198168
198319
|
kind: e.adapter,
|
|
198169
|
-
binary: e.
|
|
198320
|
+
binary: e.resolved,
|
|
198170
198321
|
...version2 ? { version: version2 } : {},
|
|
198171
198322
|
...NATIVE_APPEND_RUNTIMES.has(e.adapter) ? { supportsAppendInput: true } : {}
|
|
198172
198323
|
};
|
|
@@ -203398,7 +203549,7 @@ function syncRuntimeAssets(candidateRoots, binDir) {
|
|
|
203398
203549
|
}
|
|
203399
203550
|
|
|
203400
203551
|
// src/index.ts
|
|
203401
|
-
var PKG_VERSION = true ? "0.1.
|
|
203552
|
+
var PKG_VERSION = true ? "0.1.111" : "dev";
|
|
203402
203553
|
var OASIS_DIR = path28.join(os11.homedir(), ".oasis");
|
|
203403
203554
|
var CONFIG_FILE = path28.join(OASIS_DIR, "node-config.json");
|
|
203404
203555
|
var PID_FILE = path28.join(OASIS_DIR, "node.pid");
|