oasis_test_v2 2.2.3 → 2.2.5
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 +210 -27
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1497,13 +1497,13 @@ var init_delegation_prompts = __esm({
|
|
|
1497
1497
|
"",
|
|
1498
1498
|
"### \u7528\u6237\u53C8\u8BF4\u4E86\u4E00\u53E5\uFF1A\u5148\u5224\u662F\u4E0D\u662F\u540C\u4E00\u4EF6\u4E8B",
|
|
1499
1499
|
"",
|
|
1500
|
-
'- **\u540C\u4E00\u4EF6\u4E8B**\uFF08\u6539\u7EC6\u8282\u3001\u8865\u8981\u6C42\u3001\u50AC\u8FDB\u5EA6\uFF09\u2192 `oasis delegate --
|
|
1500
|
+
'- **\u540C\u4E00\u4EF6\u4E8B**\uFF08\u6539\u7EC6\u8282\u3001\u8865\u8981\u6C42\u3001\u50AC\u8FDB\u5EA6\uFF09\u2192 `oasis delegate --follow-up <\u77ED\u540D|\u4E13\u5BB6\u540D> --text "<\u7528\u6237\u539F\u8BDD + \u5FC5\u8981\u80CC\u666F>"`',
|
|
1501
1501
|
"- **\u53E6\u4E00\u4EF6\u4E8B**\uFF08\u6362\u4E86\u4EA4\u4ED8\u7269\u3001\u6362\u4E86\u76EE\u6807\uFF09\u2192 \u91CD\u65B0 `--to` \u6D3E\u4E00\u6B21\uFF0C**\u522B\u585E\u8FDB\u65E7\u7684\u90A3\u4E2A**",
|
|
1502
1502
|
"",
|
|
1503
1503
|
"\u5224\u636E\u662F\u300C\u4EA7\u51FA\u7684\u8FD8\u662F\u4E0D\u662F\u90A3\u4E00\u4EF6\u4E1C\u897F\u300D\uFF0C\u4E0D\u662F\u300C\u804A\u7684\u662F\u4E0D\u662F\u540C\u4E00\u4E2A\u8BDD\u9898\u300D\u3002\u585E\u9519\u4E86\uFF0C\u90A3\u6761\u5B50\u5BF9\u8BDD\u4F1A\u4E00\u76F4\u6EDA\u4E0B\u53BB\uFF0C",
|
|
1504
1504
|
"\u6700\u540E\u8FDE\u4E13\u5BB6\u81EA\u5DF1\u90FD\u8BF4\u4E0D\u6E05\u73B0\u5728\u8981\u4EA4\u4EC0\u4E48\u3002",
|
|
1505
1505
|
"",
|
|
1506
|
-
"\u53D1\u8D77\u65F6\u53EF\u4EE5 `--as <\u77ED\u540D>` \u8D77\u4E2A\u540D\uFF0C\u4E4B\u540E\u7528\u5B83\u6765 `--
|
|
1506
|
+
"\u53D1\u8D77\u65F6\u53EF\u4EE5 `--as <\u77ED\u540D>` \u8D77\u4E2A\u540D\uFF0C\u4E4B\u540E\u7528\u5B83\u6765 `--follow-up`\u3002**\u7528\u547D\u4EE4\u8FD4\u56DE\u7684\u90A3\u4E2A\u540D\u5B57**\u2014\u2014\u649E\u540D\u65F6\u7CFB\u7EDF\u4F1A\u52A0\u540E\u7F00\u3002",
|
|
1507
1507
|
"",
|
|
1508
1508
|
"**\u8F6C\u8FBE\u65F6\u6807\u4E00\u53E5\u6027\u8D28**\uFF0C\u4E13\u5BB6\u636E\u6B64\u51B3\u5B9A\u624B\u4E0A\u90A3\u6BB5\u8981\u4E0D\u8981\u4F5C\u5E9F\uFF1A",
|
|
1509
1509
|
"",
|
|
@@ -24008,6 +24008,13 @@ function applyModelOverrides(base, overrides) {
|
|
|
24008
24008
|
}
|
|
24009
24009
|
return kept;
|
|
24010
24010
|
}
|
|
24011
|
+
function clearModelDiscoveryCache(runtime, executablePath) {
|
|
24012
|
+
if (!runtime) {
|
|
24013
|
+
modelCache.clear();
|
|
24014
|
+
return;
|
|
24015
|
+
}
|
|
24016
|
+
modelCache.delete(discoveryCacheKey(runtime, executablePath));
|
|
24017
|
+
}
|
|
24011
24018
|
function discoveryCacheKey(runtime, executablePath) {
|
|
24012
24019
|
return `${runtime}:${executablePath ?? ""}`;
|
|
24013
24020
|
}
|
|
@@ -24032,8 +24039,11 @@ async function withFallback(runtime, executablePath, discover, fallback) {
|
|
|
24032
24039
|
}
|
|
24033
24040
|
function claudeStaticModels() {
|
|
24034
24041
|
return [
|
|
24035
|
-
{ id: "claude-opus-
|
|
24042
|
+
{ id: "claude-opus-5", label: "Claude Opus 5", provider: "Anthropic" },
|
|
24043
|
+
{ id: "claude-fable-5-1", label: "Claude Fable 5.1", provider: "Anthropic" },
|
|
24044
|
+
{ id: "claude-fable-5", label: "Claude Fable 5", provider: "Anthropic" },
|
|
24036
24045
|
{ id: "claude-opus-4-8", label: "Claude Opus 4.8", provider: "Anthropic" },
|
|
24046
|
+
{ id: "claude-opus-4-7", label: "Claude Opus 4.7", provider: "Anthropic" },
|
|
24037
24047
|
{ id: "claude-opus-4-6", label: "Claude Opus 4.6", provider: "Anthropic" },
|
|
24038
24048
|
{ id: "claude-sonnet-5", label: "Claude Sonnet 5", provider: "Anthropic" },
|
|
24039
24049
|
{ id: "claude-sonnet-4-6", label: "Claude Sonnet 4.6", provider: "Anthropic" },
|
|
@@ -24043,14 +24053,12 @@ function claudeStaticModels() {
|
|
|
24043
24053
|
}
|
|
24044
24054
|
function codexStaticModels() {
|
|
24045
24055
|
return [
|
|
24046
|
-
{ id: "gpt-
|
|
24047
|
-
{ id: "gpt-5.
|
|
24048
|
-
{ id: "gpt-5.
|
|
24049
|
-
{ id: "gpt-5.
|
|
24050
|
-
{ id: "gpt-5.
|
|
24051
|
-
{ id: "gpt-5", label: "GPT-5", provider: "OpenAI" }
|
|
24052
|
-
{ id: "o3", label: "o3", provider: "OpenAI" },
|
|
24053
|
-
{ id: "o3-mini", label: "o3-mini", provider: "OpenAI" }
|
|
24056
|
+
{ id: "gpt-6-astra", label: "GPT-6-Astra", provider: "OpenAI", default: true },
|
|
24057
|
+
{ id: "gpt-5.6-sol", label: "GPT-5.6-Sol", provider: "OpenAI" },
|
|
24058
|
+
{ id: "gpt-5.6-terra", label: "GPT-5.6-Terra", provider: "OpenAI" },
|
|
24059
|
+
{ id: "gpt-5.6-luna", label: "GPT-5.6-Luna", provider: "OpenAI" },
|
|
24060
|
+
{ id: "gpt-5.5", label: "GPT-5.5", provider: "OpenAI" },
|
|
24061
|
+
{ id: "gpt-5.2", label: "GPT-5.2", provider: "OpenAI" }
|
|
24054
24062
|
];
|
|
24055
24063
|
}
|
|
24056
24064
|
function geminiStaticModels() {
|
|
@@ -218483,6 +218491,31 @@ ${input.description}
|
|
|
218483
218491
|
listActorConnectorConnections(actorId) {
|
|
218484
218492
|
return this.opts.store.listActorConnectorConnections(actorId);
|
|
218485
218493
|
}
|
|
218494
|
+
/**
|
|
218495
|
+
* 移除某员工与某连接器的连接(组织页连接器详情的「移除连接」,2026-09-09 原型 1600:5765)。
|
|
218496
|
+
*
|
|
218497
|
+
* 删两样东西,缺一不可:
|
|
218498
|
+
* ① 这名员工**自己**那份连接器凭据(`scope=personal` 且 `connectorId` 命中的变量行)——
|
|
218499
|
+
* 不删的话,「移除」之后 `actorConnected` 里还有它,卡片照样在,读作「删不掉」;
|
|
218500
|
+
* ② 「员工×连接器」的连接记录——不删的话 `effective` 里还有它(enabled=false),
|
|
218501
|
+
* 卡片变成一张「已停用」的僵尸卡,而人要的是它消失。
|
|
218502
|
+
*
|
|
218503
|
+
* **不碰组织那条 connector 行**(决策 0080 修订五的同一条理由):组织级连接是别人配的资产,
|
|
218504
|
+
* 一名员工点「移除连接」不该把全组织的连接拆掉。组织级的断开在「管理 > 连接器」。
|
|
218505
|
+
* 于是:组织已连接时,移除个人连接后这名员工会**回落到组织默认**——卡片仍在,但身份那一行
|
|
218506
|
+
* 变回组织账号。这是对的,不是没删干净。
|
|
218507
|
+
*
|
|
218508
|
+
* 幂等:没有个人凭据、没有记录时照样返回成功(`variablesDeleted: 0`)——重复点、并发点都不该报错。
|
|
218509
|
+
*/
|
|
218510
|
+
async removeActorConnector(actorId, connectorId) {
|
|
218511
|
+
const rows = await this.opts.store.listVariables(actorId);
|
|
218512
|
+
const mine = rows.filter(
|
|
218513
|
+
(v2) => v2.scope === "personal" && v2.actorId === actorId && v2.connectorId === connectorId
|
|
218514
|
+
);
|
|
218515
|
+
for (const v2 of mine) await this.opts.store.deleteVariable(v2.key, actorId);
|
|
218516
|
+
await this.opts.store.deleteActorConnectorConnection(actorId, connectorId);
|
|
218517
|
+
return { removed: true, variablesDeleted: mine.length };
|
|
218518
|
+
}
|
|
218486
218519
|
/**
|
|
218487
218520
|
* 员工连接器面板所需状态:连接记录 + 组织级已连接集合 + 该员工已授权(有个人 connector 变量)集合。
|
|
218488
218521
|
* 前端据此算每个 connector 的 hasRecord / 有效 enabled / connected(actor 或 global)。
|
|
@@ -219282,15 +219315,28 @@ var init_model_pricing = __esm({
|
|
|
219282
219315
|
"gpt-4.1-nano": usd(0.1, 0.4, 0.025),
|
|
219283
219316
|
"gpt-4.1-nano-2025-04-14": usd(0.1, 0.4, 0.025),
|
|
219284
219317
|
"o4-mini": usd(1.1, 4.4, 0.275),
|
|
219318
|
+
// o3 / o3-mini 在 codex 静态目录里可选,却一直不在价目快照里(费用记 0)。
|
|
219319
|
+
// 这两行按 OpenAI 公开价填,不是智增增快照里的行;供应商价目表同步到时以 DB 为准。
|
|
219320
|
+
"o3": usd(2, 8),
|
|
219321
|
+
"o3-mini": usd(1.1, 4.4),
|
|
219322
|
+
"claude-fable-5-1": usd(10, 50),
|
|
219285
219323
|
"claude-fable-5": usd(10, 50),
|
|
219324
|
+
"claude-mythos-5-1": usd(10, 50),
|
|
219286
219325
|
"claude-mythos-5": usd(10, 50),
|
|
219326
|
+
// claude-opus-5 是 Claude Code 当代默认款,却一直不在这张快照里:查不到价 → 费用记 0
|
|
219327
|
+
// (与 2026-09-04 那次 `claude-opus-5[1m]` 记 0 同一类坑)。按 Opus 档 $5/$25 补上。
|
|
219328
|
+
"claude-opus-5": usd(5, 25),
|
|
219287
219329
|
"claude-opus-4-8": usd(5, 25),
|
|
219288
219330
|
"claude-opus-4-7": usd(5, 25),
|
|
219289
219331
|
"claude-sonnet-5": usd(2, 10),
|
|
219290
219332
|
"claude-sonnet-4-6": usd(3, 15),
|
|
219291
219333
|
"claude-opus-4-6": usd(5, 25),
|
|
219292
219334
|
"claude-opus-4-5-20251101": usd(5, 25),
|
|
219335
|
+
"claude-opus-4-5": usd(5, 25),
|
|
219293
219336
|
"claude-sonnet-4-5-20250929": usd(3, 15),
|
|
219337
|
+
// 短名同样要有:前缀比对是「表里的键是模型名的前缀」,带日期的那行匹配不上不带日期的短名。
|
|
219338
|
+
// claude-sonnet-4-5 从 2026-07-04 起就在目录里可选,却一直查不到价(费用记 0),本次一并补。
|
|
219339
|
+
"claude-sonnet-4-5": usd(3, 15),
|
|
219294
219340
|
"claude-opus-4-1-20250805": usd(15, 75),
|
|
219295
219341
|
"claude-opus-4-20250514": usd(15, 75),
|
|
219296
219342
|
"claude-sonnet-4-20250514": usd(3, 15),
|
|
@@ -219299,6 +219345,14 @@ var init_model_pricing = __esm({
|
|
|
219299
219345
|
"claude-3-5-sonnet-20240620": usd(3, 15),
|
|
219300
219346
|
"claude-3-sonnet-20240229": usd(3, 15),
|
|
219301
219347
|
"claude-haiku-4-5-20251001": usd(1, 5),
|
|
219348
|
+
// codebuddy 目录用点号写法(claude-sonnet-4.6),与上面的连字符写法是同一批模型,
|
|
219349
|
+
// 但字符串对不上就查不到价 → 记 0。同价另起别名行。
|
|
219350
|
+
"claude-sonnet-4.6": usd(3, 15),
|
|
219351
|
+
"claude-opus-4.7": usd(5, 25),
|
|
219352
|
+
"gemini-3.1-pro": usd(2, 12),
|
|
219353
|
+
"gemini-3-pro-preview": usd(2, 12),
|
|
219354
|
+
// Claude Code 回报的可能是不带日期的短名,短名匹配不上带日期的那行(前缀比对是「表里的键是模型名的前缀」)。
|
|
219355
|
+
"claude-haiku-4-5": usd(1, 5),
|
|
219302
219356
|
"gemini-3.5-flash": usd(1.5, 9),
|
|
219303
219357
|
"gemini-3.1-pro-preview": usd(2, 12),
|
|
219304
219358
|
"gemini-3.1-pro-preview-customtools": usd(2, 12),
|
|
@@ -220432,6 +220486,11 @@ function actorsDomain(opts) {
|
|
|
220432
220486
|
const conn = await service.setActorConnectorEnabled(req.params.id, req.params.connectorId, b2.enabled);
|
|
220433
220487
|
return { status: 200, body: conn };
|
|
220434
220488
|
});
|
|
220489
|
+
router.delete("/api/actors/:id/connectors/:connectorId", async (req) => {
|
|
220490
|
+
const { service } = await resolveCtx(req.auth.companyId);
|
|
220491
|
+
const r = await service.removeActorConnector(req.params.id, req.params.connectorId);
|
|
220492
|
+
return { status: 200, body: r };
|
|
220493
|
+
});
|
|
220435
220494
|
const requireVariableManager = (req) => {
|
|
220436
220495
|
if (!isHumanActor(req.auth.actor)) {
|
|
220437
220496
|
throw new ApiError(
|
|
@@ -224723,11 +224782,13 @@ async function resolveRuntimeModels(deps, runtimeId) {
|
|
|
224723
224782
|
const rt = (await deps.nodeStore.listRuntimes()).find((r) => r.id === runtimeId);
|
|
224724
224783
|
if (!rt) return [];
|
|
224725
224784
|
try {
|
|
224726
|
-
const
|
|
224727
|
-
|
|
224785
|
+
const reported = deps.nodeReportedModels?.(rt.nodeId, rt.kind);
|
|
224786
|
+
const [discovered, overrides] = await Promise.all([
|
|
224787
|
+
// 节点报过就不必再在控制面上白 spawn 一次(跨机时那次 spawn 注定 ENOENT)。
|
|
224788
|
+
reported && reported.length > 0 ? Promise.resolve(reported) : listModels(rt.kind, rt.binary),
|
|
224728
224789
|
deps.registry.listRuntimeModelOverrides(runtimeId)
|
|
224729
224790
|
]);
|
|
224730
|
-
return applyModelOverrides(
|
|
224791
|
+
return applyModelOverrides(discovered, overrides);
|
|
224731
224792
|
} catch {
|
|
224732
224793
|
const overrides = await deps.registry.listRuntimeModelOverrides(runtimeId).catch(() => []);
|
|
224733
224794
|
return applyModelOverrides([], overrides);
|
|
@@ -225119,6 +225180,21 @@ function nodesDomain(deps) {
|
|
|
225119
225180
|
if (!rt) return { status: 404, body: { error: "runtime not found" } };
|
|
225120
225181
|
return { status: 200, body: { items: await resolveRuntimeModels(deps, runtimeId) } };
|
|
225121
225182
|
});
|
|
225183
|
+
router.post("/api/runtimes/:runtimeId/models/refresh", async (req) => {
|
|
225184
|
+
const runtimeId = req.params["runtimeId"];
|
|
225185
|
+
if (!runtimeId) return { status: 400, body: { error: "missing runtimeId" } };
|
|
225186
|
+
const rt = (await deps.nodeStore.listRuntimes()).find((r) => r.id === runtimeId);
|
|
225187
|
+
if (!rt) return { status: 404, body: { error: "runtime not found" } };
|
|
225188
|
+
const outcome = deps.refreshNodeModels ? await deps.refreshNodeModels(rt.nodeId) : { ok: false, reason: "\u672C\u90E8\u7F72\u6CA1\u6709\u8282\u70B9\u7F51\u5173\uFF0C\u62FF\u4E0D\u5230\u8FD9\u53F0\u673A\u5668\u4E0A\u7684\u771F\u5B9E\u6E05\u5355" };
|
|
225189
|
+
return {
|
|
225190
|
+
status: 200,
|
|
225191
|
+
body: {
|
|
225192
|
+
items: await resolveRuntimeModels(deps, runtimeId),
|
|
225193
|
+
refreshed: outcome.ok,
|
|
225194
|
+
...outcome.reason ? { reason: outcome.reason } : {}
|
|
225195
|
+
}
|
|
225196
|
+
};
|
|
225197
|
+
});
|
|
225122
225198
|
router.get("/api/runtimes/:runtimeId/model-overrides", async (req) => {
|
|
225123
225199
|
const runtimeId = req.params["runtimeId"];
|
|
225124
225200
|
if (!runtimeId) return { status: 400, body: { error: "missing runtimeId" } };
|
|
@@ -256820,6 +256896,41 @@ async function startServe(opts) {
|
|
|
256820
256896
|
let nodeTokens = createNodeTokenStore(path29.join(opts.dir, "node-tokens.json"));
|
|
256821
256897
|
const enrollTokens = createEnrollTokenStore(30 * 60 * 1e3, path29.join(opts.dir, "enroll-tokens.json"));
|
|
256822
256898
|
let nodeStore = await FileNodeStore.open(path29.join(opts.dir, "nodes.json"));
|
|
256899
|
+
const nodeReportedModelsStore = /* @__PURE__ */ new Map();
|
|
256900
|
+
const modelRefreshWaiters = /* @__PURE__ */ new Map();
|
|
256901
|
+
const modelRefreshInFlight = /* @__PURE__ */ new Map();
|
|
256902
|
+
const modelRefreshLastAt = /* @__PURE__ */ new Map();
|
|
256903
|
+
const MODELS_STALE_MS = 5 * 6e4;
|
|
256904
|
+
const MODELS_BG_REFRESH_MIN_GAP_MS = 6e4;
|
|
256905
|
+
const MODELS_REFRESH_TIMEOUT_MS = 45e3;
|
|
256906
|
+
const refreshNodeModels = (nodeId) => {
|
|
256907
|
+
const running = modelRefreshInFlight.get(nodeId);
|
|
256908
|
+
if (running) return running;
|
|
256909
|
+
if (!hub) return Promise.resolve({ ok: false, reason: "\u672C\u8FDB\u7A0B\u6CA1\u6709\u8282\u70B9\u7F51\u5173" });
|
|
256910
|
+
const online = hub.connectedDaemons().some((d) => d.daemonId === nodeId);
|
|
256911
|
+
if (!online) return Promise.resolve({ ok: false, reason: "\u8282\u70B9\u5F53\u524D\u4E0D\u5728\u7EBF\uFF0C\u7528\u7684\u662F\u5B83\u4E0A\u6B21\u62A5\u7684\u6E05\u5355" });
|
|
256912
|
+
const requestId = (0, import_node_crypto75.randomUUID)();
|
|
256913
|
+
const task = new Promise((resolve10) => {
|
|
256914
|
+
const timer = setTimeout(() => {
|
|
256915
|
+
modelRefreshWaiters.delete(requestId);
|
|
256916
|
+
resolve10({ ok: false, reason: "\u8282\u70B9\u6CA1\u5728 45 \u79D2\u5185\u56DE\u8BDD\uFF08\u53EF\u80FD\u662F\u65E7\u7248\u8282\u70B9\uFF0C\u6216\u8FD9\u53F0\u673A\u5668\u4E0A\u7684 CLI \u63A2\u6D4B\u8D85\u65F6\uFF09" });
|
|
256917
|
+
}, MODELS_REFRESH_TIMEOUT_MS);
|
|
256918
|
+
modelRefreshWaiters.set(requestId, { resolve: () => resolve10({ ok: true }), timer });
|
|
256919
|
+
hub.dispatch(nodeId, { type: "list_models", requestId });
|
|
256920
|
+
}).finally(() => {
|
|
256921
|
+
modelRefreshInFlight.delete(nodeId);
|
|
256922
|
+
modelRefreshLastAt.set(nodeId, Date.now());
|
|
256923
|
+
});
|
|
256924
|
+
modelRefreshInFlight.set(nodeId, task);
|
|
256925
|
+
return task;
|
|
256926
|
+
};
|
|
256927
|
+
const nodeReportedModels = (nodeId, runtimeKind) => {
|
|
256928
|
+
const entry = nodeReportedModelsStore.get(nodeId);
|
|
256929
|
+
const stale = !entry || Date.now() - entry.fetchedAt > MODELS_STALE_MS;
|
|
256930
|
+
const gapOk = Date.now() - (modelRefreshLastAt.get(nodeId) ?? 0) > MODELS_BG_REFRESH_MIN_GAP_MS;
|
|
256931
|
+
if (stale && gapOk) void refreshNodeModels(nodeId).catch(() => ({ ok: false }));
|
|
256932
|
+
return entry?.byKind.get(runtimeKind);
|
|
256933
|
+
};
|
|
256823
256934
|
const registryAuditFile = path29.join(opts.dir, "registry-audit.ndjson");
|
|
256824
256935
|
const registryListeners = /* @__PURE__ */ new Set();
|
|
256825
256936
|
const registryAudit = (record8) => {
|
|
@@ -256949,7 +257060,7 @@ async function startServe(opts) {
|
|
|
256949
257060
|
listBindingModelIds: async (nodeId, runtimeKind) => {
|
|
256950
257061
|
const rt = (await nodeStore.listRuntimes(nodeId)).find((r) => r.kind === runtimeKind);
|
|
256951
257062
|
if (!rt) return [];
|
|
256952
|
-
return (await resolveRuntimeModels({ nodeStore, registry: registryStore }, rt.id)).map((m2) => m2.id);
|
|
257063
|
+
return (await resolveRuntimeModels({ nodeStore, registry: registryStore, nodeReportedModels }, rt.id)).map((m2) => m2.id);
|
|
256953
257064
|
}
|
|
256954
257065
|
});
|
|
256955
257066
|
assistantsService = new AssistantsService({
|
|
@@ -258487,7 +258598,7 @@ async function startServe(opts) {
|
|
|
258487
258598
|
registry: registryStore,
|
|
258488
258599
|
// 会话级模型覆盖的候选清单:与 `GET /api/runtimes/:id/models` **同一份**实现
|
|
258489
258600
|
// (resolveRuntimeModels = discovery + 管理员 override),避免「下拉选得到、发出去被拒」。
|
|
258490
|
-
listRuntimeModelIds: async (runtimeId) => (await resolveRuntimeModels({ nodeStore, registry: registryStore }, runtimeId)).map((m2) => m2.id),
|
|
258601
|
+
listRuntimeModelIds: async (runtimeId) => (await resolveRuntimeModels({ nodeStore, registry: registryStore, nodeReportedModels }, runtimeId)).map((m2) => m2.id),
|
|
258491
258602
|
// 诊断 ab94f202 Fix A:add-revision --role 写入口校验用「可分配岗位」集合(岗位目录 AND assignable)。
|
|
258492
258603
|
// 与 GET /api/roles 的 assignable 派生同式(domains/roles/index.ts):system=true / 已弃用一律不可分配。
|
|
258493
258604
|
resolveAssignableRoles: async () => new Set(
|
|
@@ -258624,6 +258735,8 @@ async function startServe(opts) {
|
|
|
258624
258735
|
nodeHealth,
|
|
258625
258736
|
activeRunCountOf,
|
|
258626
258737
|
activeRunsOf,
|
|
258738
|
+
nodeReportedModels,
|
|
258739
|
+
refreshNodeModels,
|
|
258627
258740
|
fetchLatestNpmDaemonVersion
|
|
258628
258741
|
}),
|
|
258629
258742
|
collabDomain({
|
|
@@ -259933,6 +260046,24 @@ async function startServe(opts) {
|
|
|
259933
260046
|
});
|
|
259934
260047
|
return chatLiveSessions.has(jobKey) ? "live" : "unknown";
|
|
259935
260048
|
});
|
|
260049
|
+
hub.addMessageListener((daemonId, msg) => {
|
|
260050
|
+
if (msg.type !== "runtime_models") return;
|
|
260051
|
+
const prev = nodeReportedModelsStore.get(daemonId);
|
|
260052
|
+
const byKind = prev?.byKind ?? /* @__PURE__ */ new Map();
|
|
260053
|
+
for (const entry of msg.models) {
|
|
260054
|
+
if (entry.models.length > 0) byKind.set(entry.kind, entry.models);
|
|
260055
|
+
}
|
|
260056
|
+
nodeReportedModelsStore.set(daemonId, { byKind, fetchedAt: Date.now() });
|
|
260057
|
+
if (msg.requestId) {
|
|
260058
|
+
const waiter = modelRefreshWaiters.get(msg.requestId);
|
|
260059
|
+
if (waiter) {
|
|
260060
|
+
clearTimeout(waiter.timer);
|
|
260061
|
+
modelRefreshWaiters.delete(msg.requestId);
|
|
260062
|
+
waiter.resolve();
|
|
260063
|
+
}
|
|
260064
|
+
}
|
|
260065
|
+
console.log(`[models] \u8282\u70B9 ${daemonId} \u4E0A\u62A5\u5019\u9009\u6A21\u578B\uFF1A${msg.models.map((m2) => `${m2.kind}=${m2.models.length}`).join(" ") || "\uFF08\u4E00\u6761\u90FD\u6CA1\u63A2\u5230\uFF09"}`);
|
|
260066
|
+
});
|
|
259936
260067
|
hub.addMessageListener((daemonId, msg) => {
|
|
259937
260068
|
if (msg.type !== "gc_query_artifacts") return;
|
|
259938
260069
|
void (async () => {
|
|
@@ -263036,6 +263167,7 @@ var OUTBOX_MAX = 500;
|
|
|
263036
263167
|
var PENDING_STREAM_MAX = 2e3;
|
|
263037
263168
|
var AUTH_REJECT_BACKOFF_MAX_MS = 15 * 6e4;
|
|
263038
263169
|
var AUTH_REJECT_GIVE_UP_AFTER = 3;
|
|
263170
|
+
var MODEL_REPORT_COOLDOWN_MS = 10 * 6e4;
|
|
263039
263171
|
var AUTH_REJECT_RE = /Unexpected server response:\s*(401|403)/;
|
|
263040
263172
|
var DRAIN_TIMEOUT_MS = 15e3;
|
|
263041
263173
|
var DRAIN_POLL_MS = 50;
|
|
@@ -263129,6 +263261,12 @@ var DaemonWsClient = class {
|
|
|
263129
263261
|
authRejectStreak = 0;
|
|
263130
263262
|
/** 本次连接尝试是否因握手 401/403 失败——error 事件里置、close 事件里消费。 */
|
|
263131
263263
|
lastErrorWasAuthReject = false;
|
|
263264
|
+
/** 模型上报的轮次号:重连会再拉一轮,用它作废上一轮的迟到结果(否则旧结果可能盖住新结果)。 */
|
|
263265
|
+
modelReportGeneration = 0;
|
|
263266
|
+
/** 上一次**探测成功**的时刻;节点频繁掉线重连时靠它避免每分钟把十几个 CLI 重起一遍。 */
|
|
263267
|
+
lastModelReportAt = 0;
|
|
263268
|
+
/** 缓存上一轮结果:冷却期内重连直接重发这份,服务端重启后也能立刻拿到清单。 */
|
|
263269
|
+
lastModelReport = [];
|
|
263132
263270
|
authRejectGiveUpAfter;
|
|
263133
263271
|
/** 放弃时的动作;默认干净退出(exit 0),测试注入以免打死测试进程。 */
|
|
263134
263272
|
onAuthGiveUp;
|
|
@@ -263237,6 +263375,7 @@ var DaemonWsClient = class {
|
|
|
263237
263375
|
this.flushPendingStream();
|
|
263238
263376
|
this.resendOutbox();
|
|
263239
263377
|
this.reportRuntimes = false;
|
|
263378
|
+
void this.reportRuntimeModels();
|
|
263240
263379
|
this.pingTimer = setInterval(() => {
|
|
263241
263380
|
this.send({ type: "pong" });
|
|
263242
263381
|
if (Date.now() - this.lastReceivedAt > this.silenceTimeoutMs) {
|
|
@@ -263403,6 +263542,10 @@ var DaemonWsClient = class {
|
|
|
263403
263542
|
this.send({ type: "workdir_read_result", requestId: msg.requestId, result });
|
|
263404
263543
|
break;
|
|
263405
263544
|
}
|
|
263545
|
+
case "list_models": {
|
|
263546
|
+
void this.reportRuntimeModels({ force: true, requestId: msg.requestId });
|
|
263547
|
+
break;
|
|
263548
|
+
}
|
|
263406
263549
|
case "update": {
|
|
263407
263550
|
this.pendingUpdatePkg = msg.pkg;
|
|
263408
263551
|
if (!this.onUpdate) {
|
|
@@ -263520,6 +263663,42 @@ var DaemonWsClient = class {
|
|
|
263520
263663
|
this.onUpdate?.(this.pendingUpdatePkg);
|
|
263521
263664
|
}
|
|
263522
263665
|
}
|
|
263666
|
+
/**
|
|
263667
|
+
* 拉一遍本机各 runtime 的候选模型清单并上报(`runtime_models` 帧)。
|
|
263668
|
+
*
|
|
263669
|
+
* 串行而不是并发:ACP 家族每探一个都要真起一个 CLI 进程(hermes 40s、oasis-agent 30s 的超时),
|
|
263670
|
+
* 十几个一起起会把节点的内存和文件句柄按住。`listModels` 自带 60 秒缓存,重连时基本是空跑。
|
|
263671
|
+
* 任何一个 runtime 抛错都只丢它自己那一条,不影响其余。全空就不发帧——让服务端走老路,
|
|
263672
|
+
* 而不是用一份空清单把它原本能给出的静态目录盖掉。
|
|
263673
|
+
*/
|
|
263674
|
+
async reportRuntimeModels(opts = {}) {
|
|
263675
|
+
const generation = ++this.modelReportGeneration;
|
|
263676
|
+
const reply = (models) => this.send({ type: "runtime_models", models, ...opts.requestId ? { requestId: opts.requestId } : {} });
|
|
263677
|
+
if (!opts.force && this.lastModelReport.length > 0 && Date.now() - this.lastModelReportAt < MODEL_REPORT_COOLDOWN_MS) {
|
|
263678
|
+
reply(this.lastModelReport);
|
|
263679
|
+
return;
|
|
263680
|
+
}
|
|
263681
|
+
const out = [];
|
|
263682
|
+
for (const rt of this.runtimes) {
|
|
263683
|
+
if (generation !== this.modelReportGeneration) return;
|
|
263684
|
+
try {
|
|
263685
|
+
const kind = rt.kind;
|
|
263686
|
+
if (opts.force) clearModelDiscoveryCache(kind, rt.binary);
|
|
263687
|
+
const models = await listModels(kind, rt.binary);
|
|
263688
|
+
if (models.length > 0) out.push({ kind: rt.kind, models });
|
|
263689
|
+
} catch {
|
|
263690
|
+
}
|
|
263691
|
+
}
|
|
263692
|
+
if (generation !== this.modelReportGeneration) return;
|
|
263693
|
+
if (out.length === 0) {
|
|
263694
|
+
if (opts.requestId) reply([]);
|
|
263695
|
+
return;
|
|
263696
|
+
}
|
|
263697
|
+
this.lastModelReport = out;
|
|
263698
|
+
this.lastModelReportAt = Date.now();
|
|
263699
|
+
reply(out);
|
|
263700
|
+
log2("[node-cli]", `\u5DF2\u4E0A\u62A5\u5019\u9009\u6A21\u578B\uFF1A${out.map((r) => `${r.kind}=${r.models.length}`).join(" ")}`);
|
|
263701
|
+
}
|
|
263523
263702
|
buildMeta() {
|
|
263524
263703
|
const activeSessions = this.sessions.activeSessions();
|
|
263525
263704
|
return {
|
|
@@ -264092,15 +264271,19 @@ var COMMAND_DECLS = {
|
|
|
264092
264271
|
},
|
|
264093
264272
|
delegate: {
|
|
264094
264273
|
group: "\u59D4\u6D3E\u4E13\u5BB6",
|
|
264095
|
-
usage: 'oasis delegate --to <role|actorId> --task "<\u4EFB\u52A1\u4E66>" [--as <\u77ED\u540D>] [--file <\u8DEF\u5F84>]... [--json true]\n oasis delegate --
|
|
264274
|
+
usage: 'oasis delegate --to <role|actorId> --task "<\u4EFB\u52A1\u4E66>" [--as <\u77ED\u540D>] [--file <\u8DEF\u5F84>]... [--json true]\n oasis delegate --follow-up <\u5F15\u7528> --text "<...>" [--file <\u8DEF\u5F84>]...\n oasis delegate --status <\u5F15\u7528> [--json true]\n oasis delegate --list [--all] [--json true]',
|
|
264096
264275
|
description: "\u628A\u4E00\u4EF6\u4E8B\u4EA4\u7ED9\u7EC4\u7EC7\u91CC\u5BF9\u53E3\u7684\u4E13\u5BB6\u53BB\u505A\uFF08\u5F02\u6B65\uFF09\u3002\u547D\u4EE4\u7ACB\u5373\u8FD4\u56DE\uFF0C\u4E13\u5BB6\u5E72\u5B8C\u4E86\u7ED3\u679C\u81EA\u5DF1\u56DE\u5230\u8FD9\u6761\u5BF9\u8BDD\u2014\u2014**\u4E0D\u8981\u5728\u8FD9\u91CC\u7B49**\u3002",
|
|
264097
264276
|
flags: [
|
|
264098
264277
|
{ name: "to", desc: "\u6D3E\u7ED9\u8C01\uFF1A\u5C97\u4F4D\u540D\u6216 actorId\uFF08\u5C97\u4F4D 0 \u4EBA\u5728\u5C97 / \u7ED1\u5B9A\u4E0D\u53EF\u7528\u4F1A\u5F53\u573A\u62A5\u9519\uFF0C\u90A3\u65F6\u81EA\u5DF1\u505A\uFF09" },
|
|
264099
264278
|
{ name: "task", desc: "\u4EFB\u52A1\u4E66\u5168\u6587\u2014\u2014\u4E13\u5BB6**\u552F\u4E00**\u7684\u4E0A\u4E0B\u6587\u6765\u6E90\uFF0C\u5199\u5168\uFF1B\u4E0D\u8BBE\u957F\u5EA6\u4E0A\u9650\u3001\u4E0D\u622A\u65AD" },
|
|
264100
|
-
{ name: "as", desc: "\u7ED9\u8FD9\u6B21\u59D4\u6D3E\u8D77\u4E2A\u77ED\u540D\uFF0C\u4E4B\u540E\u7528\u5B83 --
|
|
264279
|
+
{ name: "as", desc: "\u7ED9\u8FD9\u6B21\u59D4\u6D3E\u8D77\u4E2A\u77ED\u540D\uFF0C\u4E4B\u540E\u7528\u5B83 --follow-up\uFF1B\u649E\u540D\u670D\u52A1\u7AEF\u81EA\u52A8\u52A0\u540E\u7F00\uFF0C**\u4EE5\u8F93\u51FA\u91CC\u90A3\u4E2A\u4E3A\u51C6**" },
|
|
264101
264280
|
{ name: "file", desc: "\u4E00\u8D77\u5E26\u8FC7\u53BB\u7684\u6587\u4EF6\uFF08\u4F60\u5DE5\u4F5C\u76EE\u5F55\u4E0B\u7684\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u53EF\u7ED9\u591A\u6B21\uFF1B\u5355\u4E2A \u22642MB\u3001\u4E00\u6B21 \u226420 \u4E2A / 20MB\uFF09" },
|
|
264102
|
-
{ name: "
|
|
264103
|
-
|
|
264281
|
+
{ name: "follow-up", desc: "\u5F80\u5DF2\u6709\u59D4\u6D3E\u91CC\u518D\u8FFD\u95EE/\u8F6C\u8FBE\u4E00\u53E5\uFF1A\u7ED9 label / \u4E13\u5BB6\u540D / delegationId \u524D\u7F00" },
|
|
264282
|
+
// 旧名别名。**登记在这里是必须的**:`command-declarations.test.ts` 的参数对拍要求
|
|
264283
|
+
// 「代码读的 flag」与「登记的 flag」逐条一致,代码里为兼容还在读 `continue`。
|
|
264284
|
+
// 别名为什么必须留、什么时候能删,见 cli.ts 里 delegate 第 ③ 支的注释。
|
|
264285
|
+
{ name: "continue", desc: "\u3010\u65E7\u540D\uFF0C\u5C06\u4E0B\u7EBF\u3011\u7B49\u540C --follow-up\uFF1B\u53EA\u4E3A\u8DE8\u7248\u672C\u517C\u5BB9\u4FDD\u7559\uFF0C\u65B0\u8C03\u7528\u4E00\u5F8B\u5199 --follow-up" },
|
|
264286
|
+
{ name: "text", desc: "\u8FFD\u95EE\u5185\u5BB9\uFF08\u914D --follow-up\uFF09\u3002\u6539\u65B9\u5411\u5C31\u660E\u8BF4\u300C\u6539\u65B9\u5411\u300D\uFF0C\u4E13\u5BB6\u4F1A\u81EA\u5DF1\u5224\u65AD\u8981\u4E0D\u8981\u653E\u5F03\u624B\u4E0A\u90A3\u6BB5\u3002**\u770B\u56DE\u6267**\uFF1A\u63D2\u8FDB\u5728\u8DD1\u7684\u90A3\u4E00\u8F6E / \u8D77\u4E86\u65B0\u7684\u4E00\u8F6E / \u8FD8\u6392\u5728\u961F\u5217\u91CC\u2014\u2014\u6392\u961F\u65F6\u4E13\u5BB6\u8981\u7B49\u672C\u8F6E\u8DD1\u5B8C\u624D\u770B\u89C1\uFF0C\u8BE5\u8DDF\u7528\u6237\u8BF4\u4E00\u58F0" },
|
|
264104
264287
|
{ name: "status", desc: "\u770B\u4E00\u4E2A\u59D4\u6D3E\u7684\u8BE6\u60C5\uFF1A\u5168\u91CF\u5404\u8F6E\u5C0F\u7ED3 + \u4EA7\u7269\u6E05\u5355" },
|
|
264105
264288
|
{ name: "list", desc: "\u5217\u51FA\u8FD9\u6761\u5BF9\u8BDD\u6D3E\u51FA\u53BB\u7684\u6D3B\uFF1B\u9ED8\u8BA4\u53EA\u7ED9\u8FDB\u884C\u4E2D + \u6700\u8FD1 10 \u6761", boolean: true },
|
|
264106
264289
|
{ name: "all", desc: "\u914D --list\uFF1A\u8FDE\u5386\u53F2\u59D4\u6D3E\u4E00\u8D77\u5217", boolean: true },
|
|
@@ -264109,7 +264292,7 @@ var COMMAND_DECLS = {
|
|
|
264109
264292
|
examples: [
|
|
264110
264293
|
'oasis delegate --to \u8BBE\u8BA1\u5E08 --task "\u628A\u767B\u5F55\u9875\u91CD\u753B\u4E00\u7248\uFF1A\u6DF1\u8272\u3001\u5706\u89D2 8px\u3001\u4E3B\u8272 #3B82F6\u3002\u4EA4\u4ED8\u7269\u653E outputs/\u3002" --as \u767B\u5F55\u9875',
|
|
264111
264294
|
'oasis delegate --to \u8BBE\u8BA1\u5E08 --task "\u6309\u8FD9\u5F20\u53C2\u8003\u56FE\u91CD\u753B" --file inputs/attachments/ref.png',
|
|
264112
|
-
'oasis delegate --
|
|
264295
|
+
'oasis delegate --follow-up \u767B\u5F55\u9875 --text "\u7528\u6237\u6539\u65B9\u5411\uFF1A\u4E3B\u8272\u6362\u6210\u7EFF\u8272\uFF08\u624B\u4E0A\u8FD9\u6BB5\u53EF\u80FD\u8981\u4F5C\u5E9F\uFF0C\u4F60\u81EA\u5DF1\u5224\u65AD\uFF09"',
|
|
264113
264296
|
"oasis delegate --list",
|
|
264114
264297
|
"oasis delegate --status \u767B\u5F55\u9875"
|
|
264115
264298
|
]
|
|
@@ -266580,12 +266763,12 @@ ${round.text}`);
|
|
|
266580
266763
|
}
|
|
266581
266764
|
break;
|
|
266582
266765
|
}
|
|
266583
|
-
const
|
|
266584
|
-
if (
|
|
266585
|
-
if (
|
|
266766
|
+
const followUpRef = flags.get("follow-up") ?? flags.get("continue");
|
|
266767
|
+
if (followUpRef !== void 0) {
|
|
266768
|
+
if (followUpRef === "true") throw new Error("--follow-up \u8981\u8DDF\u4E00\u4E2A\u5F15\u7528\uFF1Alabel / \u4E13\u5BB6\u540D / delegationId \u524D\u7F00");
|
|
266586
266769
|
const text5 = flags.get("text");
|
|
266587
|
-
if (!text5) throw new Error('--
|
|
266588
|
-
const target = await resolveRef2(
|
|
266770
|
+
if (!text5) throw new Error('--follow-up \u8981\u914D --text "<\u8981\u8FFD\u95EE\u7684\u8BDD>"');
|
|
266771
|
+
const target = await resolveRef2(followUpRef);
|
|
266589
266772
|
const outcome = await api.post(
|
|
266590
266773
|
`/api/delegations/${encodeURIComponent(target.id)}/messages`,
|
|
266591
266774
|
{ text: text5, ...fileArgs.length ? { files: fileArgs } : {} }
|
|
@@ -269401,7 +269584,7 @@ function shimScript() {
|
|
|
269401
269584
|
}
|
|
269402
269585
|
|
|
269403
269586
|
// src/index.ts
|
|
269404
|
-
var PKG_VERSION = true ? "2.2.
|
|
269587
|
+
var PKG_VERSION = true ? "2.2.5" : "dev";
|
|
269405
269588
|
var LOCAL_BIN = localBin();
|
|
269406
269589
|
var NPM_PREFIX = npmPrefix();
|
|
269407
269590
|
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.5",
|
|
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": "dc5d2f25fcd07f65185c36edb33e17ce96b5f5ae"
|
|
30
30
|
}
|
|
31
31
|
}
|