@bd7pil/reeve 0.1.8 → 0.1.10
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/default-fallback.json +2 -2
- package/package.json +1 -1
- package/provision.json +2 -2
- package/src/index.js +38 -1
- package/src/stats.js +12 -0
package/default-fallback.json
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
},
|
|
16
16
|
"providers": {
|
|
17
17
|
"opencode": { "base_url": "https://opencode.ai/inference/openai/v1", "path": "/chat/completions", "key": "public", "lane": "passthrough", "models": ["*"] },
|
|
18
|
-
"openrouter": { "base_url": "https://openrouter.ai/api/v1", "auth": ["openrouter"], "models": [] },
|
|
19
|
-
"nvidia": { "base_url": "https://integrate.api.nvidia.com/v1", "auth": ["nvidia"], "models": [] },
|
|
18
|
+
"openrouter": { "base_url": "https://openrouter.ai/api/v1", "path": "/chat/completions", "auth": ["openrouter"], "models": [] },
|
|
19
|
+
"nvidia": { "base_url": "https://integrate.api.nvidia.com/v1", "path": "/chat/completions", "auth": ["nvidia"], "models": [] },
|
|
20
20
|
"zhipuai-coding-plan": { "base_url": "https://open.bigmodel.cn", "path": "/api/coding/paas/v4/chat/completions", "auth": ["zhipuai-coding-plan"] },
|
|
21
21
|
"xxyapi-deepseek": { "base_url": "https://www.xxyapi.com", "auth": ["xxyapi-deepseek"] },
|
|
22
22
|
"lmuai": { "base_url": "https://api.lmuai.com", "auth": ["lmuai", "lmuai-glm"] },
|
package/package.json
CHANGED
package/provision.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
3
|
"name": "reeve",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.10",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"//": "REEVE 在 ocrc 实例里的装配说明。**没有二进制工件** —— 代理层是插件内的 GATE(纯 JS),不需要任何本地服务(Bifrost 时代已结束)。",
|
|
7
7
|
"host": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
]
|
|
16
16
|
},
|
|
17
17
|
"enginePlugin": {
|
|
18
|
-
"spec": "@bd7pil/reeve@0.1.
|
|
18
|
+
"spec": "@bd7pil/reeve@0.1.10",
|
|
19
19
|
"kind": "package",
|
|
20
20
|
"entry": "~/.ocrc/components/reeve/node_modules/@bd7pil/reeve",
|
|
21
21
|
"requiresPeer": []
|
package/src/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import { SUBAGENT_ROSTER, withRoster } from './roster.js'
|
|
|
36
36
|
import { probeGate, startGate } from './gate/gate.js'
|
|
37
37
|
import { defaultFallbackConfigPath } from './gate/config.js'
|
|
38
38
|
import { REEVE_TIERS, BUILTINS_TO_HIDE, mergeTierModels, pickDefaultAgent, readEndpoint, resolveGateEndpoint } from './models.js'
|
|
39
|
-
import { STATS_DEFAULTS, aggregateGateRows, aggregateLedger, buildStats, fetchGateFree, fetchGateModels, mergeModelCandidates, readLedgerTail } from './stats.js'
|
|
39
|
+
import { STATS_DEFAULTS, aggregateGateRows, aggregateLedger, buildStats, fetchGateFree, fetchGateModels, fetchGateVersion, mergeModelCandidates, readLedgerTail } from './stats.js'
|
|
40
40
|
import { loadAgents, loadSkills } from './register.js'
|
|
41
41
|
import { ensureProviderBlock, reeveProviderBlock } from './config-write.js'
|
|
42
42
|
|
|
@@ -285,6 +285,42 @@ export default {
|
|
|
285
285
|
statsTimer.unref?.()
|
|
286
286
|
logger.debug(`[reeve] 性能统计:每 ${Math.round(statsIntervalMs / 1000)}s 刷一次(台账尾 ${statsLimit} 行 / ${Math.round(statsWindowMs / 3600000)}h 窗口)`)
|
|
287
287
|
}
|
|
288
|
+
|
|
289
|
+
// GATE 运行态独立刷新(2s):面板的"已生效"要看到 chain_targets/policy/free 真的变了。
|
|
290
|
+
// 统计是 60s 一轮(含台账聚合),拿它当"热更已完成"的信号会让面板在 30s 超时后误报"没生效"
|
|
291
|
+
// ——真宿主保存测试抓到的:GATE 已经换链,快照还停在 60s 前。这里只读进程内 snapshot / 环回
|
|
292
|
+
// /gate/version(都很便宜),且**只在签名变化时**刷快照,稳定时不写盘。
|
|
293
|
+
let gateStateTimer = null
|
|
294
|
+
const gateSignature = () =>
|
|
295
|
+
JSON.stringify({
|
|
296
|
+
port: gateState?.port ?? null,
|
|
297
|
+
error: gateState?.error ?? null,
|
|
298
|
+
chains: gateState?.chains ?? null,
|
|
299
|
+
ct: gateState?.chain_targets ?? null,
|
|
300
|
+
policy: gateState?.policy ?? null,
|
|
301
|
+
free: gateState?.free ?? null,
|
|
302
|
+
})
|
|
303
|
+
let lastGateSig = gateSignature()
|
|
304
|
+
const refreshGateState = async () => {
|
|
305
|
+
let next = null
|
|
306
|
+
if (gateHandle) next = gateHandle.snapshot()
|
|
307
|
+
else if (gateState?.port) {
|
|
308
|
+
const { doc } = await fetchGateVersion({ port: gateState.port, host: gateState.host ?? '127.0.0.1' })
|
|
309
|
+
if (doc?.name === 'reeve-gate') next = { ...doc, reused: true }
|
|
310
|
+
}
|
|
311
|
+
if (!next) return
|
|
312
|
+
gateState = next
|
|
313
|
+
const sig = gateSignature()
|
|
314
|
+
if (sig !== lastGateSig) {
|
|
315
|
+
lastGateSig = sig
|
|
316
|
+
snapshotFlush()
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (gateHandle || gateState?.port) {
|
|
321
|
+
gateStateTimer = setInterval(() => void refreshGateState(), 2000)
|
|
322
|
+
gateStateTimer.unref?.()
|
|
323
|
+
}
|
|
288
324
|
const supervisor = new Supervisor({
|
|
289
325
|
ledger,
|
|
290
326
|
logger,
|
|
@@ -565,6 +601,7 @@ export default {
|
|
|
565
601
|
abort.abort()
|
|
566
602
|
supervisor.stopAll()
|
|
567
603
|
if (statsTimer) clearInterval(statsTimer)
|
|
604
|
+
if (gateStateTimer) clearInterval(gateStateTimer)
|
|
568
605
|
if (snapshot) {
|
|
569
606
|
snapshot.cancel()
|
|
570
607
|
void snapshot.flush().catch(() => {})
|
package/src/stats.js
CHANGED
|
@@ -314,6 +314,18 @@ export async function fetchGateFree({ port, host = '127.0.0.1', fetchImpl = fetc
|
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
+
/** GATE 的运行态(/gate/version):开关快照轮询用。读不到返回 {doc:null,error},不抛。 */
|
|
318
|
+
export async function fetchGateVersion({ port, host = '127.0.0.1', fetchImpl = fetch, timeoutMs = STATS_DEFAULTS.timeoutMs } = {}) {
|
|
319
|
+
try {
|
|
320
|
+
const res = await fetchImpl(`http://${host}:${port}/gate/version`, { signal: AbortSignal.timeout(timeoutMs) })
|
|
321
|
+
if (res.status !== 200) return { doc: null, error: `HTTP ${res.status}` }
|
|
322
|
+
const doc = await res.json()
|
|
323
|
+
return { doc: doc && typeof doc === 'object' ? doc : null, error: null }
|
|
324
|
+
} catch (err) {
|
|
325
|
+
return { doc: null, error: String(err?.message ?? err).slice(0, 140) }
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
317
329
|
/** GATE 自己的模型目录(`provider/model` ∪ 链名)—— 面板选择器的候选来源之一。 */
|
|
318
330
|
export async function fetchGateModels({ port, host = '127.0.0.1', fetchImpl = fetch, timeoutMs = STATS_DEFAULTS.timeoutMs } = {}) {
|
|
319
331
|
try {
|