cortico-world-humanize 0.2.0 → 0.2.1
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/CHANGELOG.md +13 -0
- package/README.md +4 -2
- package/package.json +2 -2
- package/src/config.ts +10 -0
- package/src/provider-status.ts +47 -0
- package/src/world.ts +65 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
- 新增开关「用「活人感 provider」」(在活人感的基本设置里,默认开)。Coopanion 的模型扩展没有停用开关,所以放在这里:关掉后 provider 原样转发、什么都不做,桌宠改回先调用 `humanize_feel`。不用卸载 provider 也能停用它。
|
|
6
|
+
- World 页新增「活人感 provider」状态灯和两个徽章,一眼看出 provider 有没有生效:
|
|
7
|
+
- **已生效**(绿):写明包着哪个端点;「provider 注入」记着这次启动后把心事塞进请求的次数。
|
|
8
|
+
- **待刷新**:装好了,还差把活人感关掉再打开一次。
|
|
9
|
+
- **待重启**:装了但还没加载,重启 Coopanion 才生效。
|
|
10
|
+
- **版本旧**:装的 provider 和这一版活人感对不上,要升级。
|
|
11
|
+
- **没包住**:当前端点的类型 provider 包不了。
|
|
12
|
+
- **已关闭**:装着,但上面的开关关了。
|
|
13
|
+
- **没装**:provider 是可选的,没装也能用。
|
|
14
|
+
- 没生效时,配置页顶部也写一句原因和该怎么做。
|
|
15
|
+
|
|
3
16
|
## 0.2.0
|
|
4
17
|
|
|
5
18
|
- 搭配「活人感 provider」0.2.0:装上 provider 重启就进入 provider 模式,不用再到「模型」页新建、切换端点。
|
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
| 方式 | 什么时候 | 效果 |
|
|
37
37
|
|---|---|---|
|
|
38
|
-
| **provider 模式** | 装了活人感 provider
|
|
38
|
+
| **provider 模式** | 装了活人感 provider(装上就自动包住你现在用的端点),且基本设置里「用「活人感 provider」」开着(默认开) | provider 在主模型请求发出前等心事,塞进请求再发。一轮就带着心事开口,最推荐 |
|
|
39
39
|
| 先感受再开口(默认) | 没用 provider | 桌宠先调用 `humanize_feel`,工具等副 API 想好再交回去。每次都赶得上,但主模型多一轮 |
|
|
40
40
|
| 抢时间 | 没用 provider,且关掉「先感受再开口」 | 心事作为事件推进去,桌宠已经开口就作废 |
|
|
41
41
|
|
|
@@ -58,7 +58,8 @@
|
|
|
58
58
|
- **配置**:基本设置、副 API、QQ 扩展、其他聊天来源
|
|
59
59
|
- **提示词**:预设库(情境、情绪、小动作、不想听到的说法)、环境提示词、口吻样本、最近 20 轮记录
|
|
60
60
|
- **数据**:清空最近记录和计数
|
|
61
|
-
- 导航栏:副 API
|
|
61
|
+
- 导航栏:副 API、系统前缀、活人感 provider 三个状态灯(悬停看详情),以及几个计数
|
|
62
|
+
- **provider 生没生效**:看「provider」徽章。「已生效」就是在用;「待刷新」「待重启」「版本旧」「没包住」会在配置页顶部写明怎么办。「provider 注入」是这次启动后心事塞进请求的次数,对桌宠说句话它就加一
|
|
62
63
|
|
|
63
64
|
## 系统前缀要刷新的时候
|
|
64
65
|
|
|
@@ -85,6 +86,7 @@ Coopanion 重启后沿用旧的系统前缀。换了模式或者活人感更新
|
|
|
85
86
|
|
|
86
87
|
## 停用和卸载
|
|
87
88
|
|
|
89
|
+
- **只停用 provider**:基本设置里关掉「用「活人感 provider」」,再把活人感关开一次。provider 原样转发,活人感改回「先感受再开口」。Coopanion 的模型扩展本身没有停用开关,所以放在这里。
|
|
88
90
|
- **暂时不用**:World 页关掉「活人感」。Coopanion 会立刻重建系统前缀,环境说明和 `humanize_feel` 工具一起拿掉。
|
|
89
91
|
- **卸载**:在「扩展」页卸掉两个包,然后重启。只有一种情况要先做一步:你用 0.1.0 时在「模型」页新建过「活人感」端点,而且当前端点还是它,那要**先把当前端点切回原来那个**,不然卸掉 provider 后桌宠会说不了话。
|
|
90
92
|
- **清干净**:想连数据一起去掉,删掉上面「数据和隐私」里列的两个文件夹和配置段即可。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortico-world-humanize",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cortico World for Coopanion: before the pet answers, reads the situation, mood and the pet's own memory and hands it a short inner thought, and reminds it when it slips into stock AI sentence patterns",
|
|
6
6
|
"author": "abbabanana",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"locales": {
|
|
24
24
|
"zh": {
|
|
25
25
|
"displayName": "活人感",
|
|
26
|
-
"description": "让桌宠开口前先「想一想」,说话更像个人,少一点 AI 腔。单独装就能用,搭配「活人感 provider」更快。\n\n**它做什么**\n\n- 你对桌宠说话时,先读一下情境、你的心情和桌宠自己的记忆,递给它一句「此刻心里的想法」,再让它开口。\n- 桌宠要是用了「不是……而是……」、先复述你的话这类 AI 固定句式,下次就提醒它换个说法。口癖、语气、长短都不碰。\n\n**两个扩展怎么配合**\n\n- **活人感**(就是本扩展,必装):负责想心事、查句式。单独装就能用。\n- **活人感 provider**(可选,推荐):把心事直接放进发给模型的请求里。不装的话,桌宠每次要先调一次工具读心事再开口,多跑一轮,稍慢一点。\n- 只装 provider、不装本扩展,没有任何作用。\n\n**怎么用**\n\n1. 在扩展页装上本扩展,推荐把「活人感 provider」一起装上。\n2. 重启 Coopanion。\n3. 到 World 页打开「活人感」。\n\n主模型用的是 DeepSeek 的话,什么都不用填。用别家的话,在活人感的「配置 → 副 API」里填地址、模型和 Key。\n\n如果活人感已经开着、之后才装 provider,World 页会提示「系统前缀需要刷新」:把活人感关掉再打开一次就好,聊天记录会保留。\n\n**要知道的**\n\n- 你每说一句话,会多调用一次副 API(默认 DeepSeek,约 1–2 秒,花费很少)。\n- 默认读桌宠、控制台、QQ 私聊和 @桌宠的消息。QQ 群里别人的话会经过副 API 影响心事,介意的话可以在配置里关掉。\n- 只支持中文,目前只在 Windows + DeepSeek 上测过。\n- 不想用了:World 页关掉即可。卸载:扩展页卸掉,重启。"
|
|
26
|
+
"description": "让桌宠开口前先「想一想」,说话更像个人,少一点 AI 腔。单独装就能用,搭配「活人感 provider」更快。\n\n**它做什么**\n\n- 你对桌宠说话时,先读一下情境、你的心情和桌宠自己的记忆,递给它一句「此刻心里的想法」,再让它开口。\n- 桌宠要是用了「不是……而是……」、先复述你的话这类 AI 固定句式,下次就提醒它换个说法。口癖、语气、长短都不碰。\n\n**两个扩展怎么配合**\n\n- **活人感**(就是本扩展,必装):负责想心事、查句式。单独装就能用。\n- **活人感 provider**(可选,推荐):把心事直接放进发给模型的请求里。不装的话,桌宠每次要先调一次工具读心事再开口,多跑一轮,稍慢一点。\n- 只装 provider、不装本扩展,没有任何作用。\n\n**怎么用**\n\n1. 在扩展页装上本扩展,推荐把「活人感 provider」一起装上。\n2. 重启 Coopanion。\n3. 到 World 页打开「活人感」。\n\n主模型用的是 DeepSeek 的话,什么都不用填。用别家的话,在活人感的「配置 → 副 API」里填地址、模型和 Key。\n\n如果活人感已经开着、之后才装 provider,World 页会提示「系统前缀需要刷新」:把活人感关掉再打开一次就好,聊天记录会保留。\n\n**怎么看 provider 生没生效**:World 页「活人感」的「provider」徽章显示「已生效」就是在用;「provider 注入」是心事塞进请求的次数,对桌宠说句话就会加一。没生效时,配置页顶部会写明原因和该怎么做。\n\n**想停用 provider**:不用卸载,在活人感「配置 → 基本设置」里关掉「用「活人感 provider」」,再把活人感关掉打开一次。\n\n**要知道的**\n\n- 你每说一句话,会多调用一次副 API(默认 DeepSeek,约 1–2 秒,花费很少)。\n- 默认读桌宠、控制台、QQ 私聊和 @桌宠的消息。QQ 群里别人的话会经过副 API 影响心事,介意的话可以在配置里关掉。\n- 只支持中文,目前只在 Windows + DeepSeek 上测过。\n- 不想用了:World 页关掉即可。卸载:扩展页卸掉,重启。"
|
|
27
27
|
},
|
|
28
28
|
"en": {
|
|
29
29
|
"displayName": "Humanize",
|
package/src/config.ts
CHANGED
|
@@ -17,6 +17,11 @@ export interface HumanizeConfigSection {
|
|
|
17
17
|
* 关掉则是抢时间模式:引导回来时桌宠还没开口才用得上。
|
|
18
18
|
*/
|
|
19
19
|
wait: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* 用「活人感」provider 把心事直接塞进主模型请求。provider 扩展本身没有开关(Coopanion 不支持
|
|
22
|
+
* 停用 provider 扩展),开关放在这里:关掉后 provider 原样转发,桌宠改回先调用 humanize_feel。
|
|
23
|
+
*/
|
|
24
|
+
useProvider: boolean;
|
|
20
25
|
/** 摸头、戳、换装这类小动作也带一句轻预设(不调副 API)。 */
|
|
21
26
|
light: boolean;
|
|
22
27
|
/** 小动作带轻预设的概率,0–1;动作频繁时别每次都带。 */
|
|
@@ -62,6 +67,7 @@ export const HUMANIZE_DEFAULTS: HumanizeConfigSection = {
|
|
|
62
67
|
enabled: false,
|
|
63
68
|
guide: true,
|
|
64
69
|
wait: true,
|
|
70
|
+
useProvider: true,
|
|
65
71
|
light: true,
|
|
66
72
|
lightChance: 0.5,
|
|
67
73
|
contextTurns: 6,
|
|
@@ -144,6 +150,10 @@ export function configGroups(keyStatus: string, notes: string[] = [], seen: Seen
|
|
|
144
150
|
description: '开着:桌宠收到你的话先等副 API 想好心情再回答,每次都用得上,但回应慢一秒左右。关掉:抢时间,桌宠开口太快时这一轮的引导就作废。改完在下一次会话开始时完全生效。',
|
|
145
151
|
'x-hot': true,
|
|
146
152
|
},
|
|
153
|
+
[`${K}.useProvider`]: {
|
|
154
|
+
type: 'boolean', title: '用「活人感 provider」', 'x-hot': true,
|
|
155
|
+
description: '装了「活人感 provider」才有用(没装时开着也没关系)。开着:心事直接跟着你的话发给模型,桌宠一轮就开口。关掉:provider 原样转发、什么都不做,桌宠改回先调用 humanize_feel。Coopanion 的模型扩展没有停用开关,所以开关放在这里。改完把活人感关掉再打开一次才完全生效。',
|
|
156
|
+
},
|
|
147
157
|
[`${K}.light`]: {
|
|
148
158
|
type: 'boolean', title: '小动作也带轻预设',
|
|
149
159
|
description: '被戳、被摸、被拎起、换装时,从预设库抽一句心情给它。', 'x-hot': true,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 「活人感 provider」此刻是什么状态,给 World 页的状态灯用。
|
|
3
|
+
*
|
|
4
|
+
* provider 加载后会在 globalThis 挂牌子(见 bridge.ts)。没挂牌子时分不清是「没装」「装了还没重启」
|
|
5
|
+
* 还是「装的是对不上的旧版」,所以再去扩展目录看一眼装没装、装的哪一版。
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
const PACKAGE = 'cortico-provider-humanize';
|
|
12
|
+
/** 这一版 World 要求的 provider 最低版本(桥第 3 版)。 */
|
|
13
|
+
export const PROVIDER_MIN = '0.2.0';
|
|
14
|
+
const CACHE_MS = 5_000;
|
|
15
|
+
|
|
16
|
+
const OWN_DIR = fileURLToPath(new URL('..', import.meta.url));
|
|
17
|
+
|
|
18
|
+
let cache: { at: number; botDir: string; version: string | null } | null = null;
|
|
19
|
+
|
|
20
|
+
/** 扩展目录里装着的 provider 版本;没装(或找不到)给 null。 */
|
|
21
|
+
export function installedProviderVersion(botDir: string): string | null {
|
|
22
|
+
if (cache && cache.botDir === botDir && Date.now() - cache.at < CACHE_MS) return cache.version;
|
|
23
|
+
const candidates = [
|
|
24
|
+
// Coopanion:<data>/home/<部署> 和 <data>/extensions/node_modules
|
|
25
|
+
join(dirname(dirname(botDir)), 'extensions', 'node_modules', PACKAGE, 'package.json'),
|
|
26
|
+
// 和本包装在同一个 node_modules 里
|
|
27
|
+
join(OWN_DIR, '..', PACKAGE, 'package.json'),
|
|
28
|
+
];
|
|
29
|
+
let version: string | null = null;
|
|
30
|
+
for (const file of candidates) {
|
|
31
|
+
try {
|
|
32
|
+
if (!existsSync(file)) continue;
|
|
33
|
+
const v = (JSON.parse(readFileSync(file, 'utf8')) as { version?: unknown }).version;
|
|
34
|
+
if (typeof v === 'string') { version = v; break; }
|
|
35
|
+
} catch { /* 读不了就当没找到 */ }
|
|
36
|
+
}
|
|
37
|
+
cache = { at: Date.now(), botDir, version };
|
|
38
|
+
return version;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** a < b(只比主、次、修订号)。 */
|
|
42
|
+
export function older(a: string, b: string): boolean {
|
|
43
|
+
const parse = (v: string) => v.split(/[.+-]/).slice(0, 3).map((n) => Number.parseInt(n, 10) || 0);
|
|
44
|
+
const [x, y] = [parse(a), parse(b)];
|
|
45
|
+
for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] < y[i];
|
|
46
|
+
return false;
|
|
47
|
+
}
|
package/src/world.ts
CHANGED
|
@@ -23,7 +23,8 @@ import type {
|
|
|
23
23
|
} from 'cortico/core/types.ts';
|
|
24
24
|
import { nowIso } from 'cortico/core/util.ts';
|
|
25
25
|
import { analyze, type Line, type Reading } from './analyzer.ts';
|
|
26
|
-
import { BRIDGE_VERSION, installBridge, removeBridge, type HumanizeBridge, type MainContext } from './bridge.ts';
|
|
26
|
+
import { BRIDGE_VERSION, installBridge, providerMarker, removeBridge, type HumanizeBridge, type MainContext } from './bridge.ts';
|
|
27
|
+
import { PROVIDER_MIN, installedProviderVersion, older } from './provider-status.ts';
|
|
27
28
|
import { HUMANIZE_ID, KEY_SECRET, configGroups, type HumanizeConfigSection } from './config.ts';
|
|
28
29
|
import { FALLBACK_EMOTION, PresetStore, emotionsOf, type Presets, type Scene } from './presets.ts';
|
|
29
30
|
import { PersonaStore } from './persona.ts';
|
|
@@ -179,7 +180,8 @@ export class HumanizeWorld implements World {
|
|
|
179
180
|
private readonly bridge: HumanizeBridge = {
|
|
180
181
|
version: BRIDGE_VERSION,
|
|
181
182
|
sync: () => this.tick(),
|
|
182
|
-
|
|
183
|
+
// 关了「用活人感 provider」:不交心事,provider 原样转发
|
|
184
|
+
claim: (cursors, main) => (this.useProvider() ? this.claim(cursors, main) : null),
|
|
183
185
|
touch: () => { this.providerAt = Date.now(); },
|
|
184
186
|
};
|
|
185
187
|
/** 最近一次想好的内心,工具来晚了也能交回去。 */
|
|
@@ -192,7 +194,9 @@ export class HumanizeWorld implements World {
|
|
|
192
194
|
private lastUserAt: number | null = null;
|
|
193
195
|
private readonly recentLines: string[] = [];
|
|
194
196
|
private readonly log: LogEntry[] = [];
|
|
195
|
-
private readonly stats = { api: 0, preset: 0, late: 0, light: 0, apiMs: 0, waited: 0 };
|
|
197
|
+
private readonly stats = { api: 0, preset: 0, late: 0, light: 0, apiMs: 0, waited: 0, injected: 0 };
|
|
198
|
+
/** provider 最近一次把心事塞进请求的时刻(时:分:秒)。 */
|
|
199
|
+
private lastInjectedAt = '';
|
|
196
200
|
private keyNote = '';
|
|
197
201
|
private readonly presets: PresetStore;
|
|
198
202
|
private readonly persona: PersonaStore;
|
|
@@ -227,10 +231,16 @@ export class HumanizeWorld implements World {
|
|
|
227
231
|
* 先看当前端点的配置(拼前缀时 provider 可能还没转发过),读不到再看它最近有没有报到。
|
|
228
232
|
*/
|
|
229
233
|
private providerLive(): boolean {
|
|
234
|
+
if (!this.useProvider()) return false;
|
|
230
235
|
return this.prefixState.providerConfigured()
|
|
231
236
|
|| (this.providerAt !== null && Date.now() - this.providerAt < PROVIDER_LIVE_MS);
|
|
232
237
|
}
|
|
233
238
|
|
|
239
|
+
/** 配置里的「用活人感 provider」;旧配置没有这一项时算开着。 */
|
|
240
|
+
private useProvider(): boolean {
|
|
241
|
+
return this.cfg.useProvider !== false;
|
|
242
|
+
}
|
|
243
|
+
|
|
234
244
|
private mode(): Mode {
|
|
235
245
|
return this.providerLive() ? 'provider' : this.cfg.wait ? 'tool' : 'push';
|
|
236
246
|
}
|
|
@@ -479,6 +489,8 @@ export class HumanizeWorld implements World {
|
|
|
479
489
|
return thinking.promise.then((feeling) => {
|
|
480
490
|
if (!feeling) return null;
|
|
481
491
|
this.stats.waited++;
|
|
492
|
+
this.stats.injected++;
|
|
493
|
+
this.lastInjectedAt = nowIso(this.opts.timezone).slice(11, 19);
|
|
482
494
|
this.count(feeling);
|
|
483
495
|
this.record({ trigger: feeling.via, outcome: feeling.outcome, text: feeling.body, ms: feeling.ms, error: feeling.error, how: `经 provider 注入,主模型晚发了 ${Date.now() - started}ms` });
|
|
484
496
|
return feeling.body;
|
|
@@ -780,6 +792,48 @@ export class HumanizeWorld implements World {
|
|
|
780
792
|
}
|
|
781
793
|
}
|
|
782
794
|
|
|
795
|
+
/**
|
|
796
|
+
* 「活人感 provider」生没生效,给 World 页看:状态灯(悬停看详情)、徽章上的一两个字,
|
|
797
|
+
* 以及没生效时放在配置页顶部的一句说明。
|
|
798
|
+
*/
|
|
799
|
+
private providerStatus(): { lamp: WorldLamp; badge: string; note?: string } {
|
|
800
|
+
const label = '活人感 provider';
|
|
801
|
+
const endpoint = this.prefixState.activeEndpoint() || '(未选)';
|
|
802
|
+
const kind = this.prefixState.activeKind();
|
|
803
|
+
if (providerMarker()) {
|
|
804
|
+
if (!this.useProvider()) {
|
|
805
|
+
const stale = this.staleness();
|
|
806
|
+
const hint = stale && stale.from === 'provider'
|
|
807
|
+
? '已在配置里关掉,还差一步:把活人感关掉再打开一次'
|
|
808
|
+
: '已装好,但在配置里关掉了:provider 原样转发,桌宠先调用 humanize_feel 再开口。想用就打开「用「活人感 provider」」。';
|
|
809
|
+
return { lamp: { label, state: 'offline', hint }, badge: '已关闭' };
|
|
810
|
+
}
|
|
811
|
+
if (!this.prefixState.providerConfigured()) {
|
|
812
|
+
const why = `活人感 provider 已装好,但没包住当前端点「${endpoint}」${kind ? `(类型 ${kind})` : ''},这个端点不会带上活人感,桌宠照旧先调用 humanize_feel。`;
|
|
813
|
+
return { lamp: { label, state: 'error', hint: why }, badge: '没包住', note: why };
|
|
814
|
+
}
|
|
815
|
+
const stale = this.staleness();
|
|
816
|
+
if (stale && stale.to === 'provider' && stale.from !== 'provider') {
|
|
817
|
+
return { lamp: { label, state: 'loading', hint: '已装好,还差一步:把活人感关掉再打开一次' }, badge: '待刷新' };
|
|
818
|
+
}
|
|
819
|
+
const n = this.stats.injected;
|
|
820
|
+
const hint = n
|
|
821
|
+
? `已生效:包着端点「${endpoint}」。这次启动已注入 ${n} 次,最近一次 ${this.lastInjectedAt}。`
|
|
822
|
+
: `已生效:包着端点「${endpoint}」。对桌宠说句话,「provider 注入」就会加一。`;
|
|
823
|
+
return { lamp: { label, state: 'online', hint }, badge: '已生效' };
|
|
824
|
+
}
|
|
825
|
+
const version = installedProviderVersion(this.opts.botDir);
|
|
826
|
+
if (!version) {
|
|
827
|
+
return { lamp: { label, state: 'offline', hint: '没装(可选):装上「活人感 provider」并重启,桌宠每次能少跑一轮。' }, badge: '没装' };
|
|
828
|
+
}
|
|
829
|
+
if (older(version, PROVIDER_MIN)) {
|
|
830
|
+
const why = `装着的活人感 provider 是 ${version},太旧了,和这一版活人感对不上,现在不起作用(不会出错,只是桌宠每次多跑一轮)。到「扩展」页把它升到最新版,然后重启 Coopanion。`;
|
|
831
|
+
return { lamp: { label, state: 'error', hint: why }, badge: '版本旧', note: why };
|
|
832
|
+
}
|
|
833
|
+
const why = `活人感 provider ${version} 已安装,但还没加载:重启一次 Coopanion 才生效。`;
|
|
834
|
+
return { lamp: { label, state: 'error', hint: why }, badge: '待重启', note: why };
|
|
835
|
+
}
|
|
836
|
+
|
|
783
837
|
/** 请桌宠用一两句话转告对方。和 Coopanion 自己告诉桌宠设置变了是同一个路子。 */
|
|
784
838
|
private async notice(text: string): Promise<void> {
|
|
785
839
|
const host = this.host;
|
|
@@ -808,6 +862,8 @@ export class HumanizeWorld implements World {
|
|
|
808
862
|
if (this.cfg.voice && voice.outdated && voice.edited) {
|
|
809
863
|
notes.push('人设改过了,但口吻样本是按旧人设写的(你改过它,所以没有自动重写):想按新人设重写,勾一下下面的「重写口吻样本」。');
|
|
810
864
|
}
|
|
865
|
+
const provider = this.providerStatus();
|
|
866
|
+
if (provider.note) notes.push(provider.note);
|
|
811
867
|
if (this.prefixState.legacyEndpoint()) {
|
|
812
868
|
notes.push(`当前端点「${this.prefixState.activeEndpoint()}」是旧版的「活人感」端点。现在不用它了:装着活人感 provider 时,你原来的端点会自动带上活人感。建议在「模型」页切回原来的端点;以后要卸载 provider,也一定要先切回去,不然桌宠会说不了话。`);
|
|
813
869
|
}
|
|
@@ -871,7 +927,8 @@ export class HumanizeWorld implements World {
|
|
|
871
927
|
stat: () => `${this.log.length} 条`,
|
|
872
928
|
clear: () => {
|
|
873
929
|
this.log.length = 0;
|
|
874
|
-
Object.assign(this.stats, { api: 0, preset: 0, late: 0, light: 0, apiMs: 0, waited: 0 });
|
|
930
|
+
Object.assign(this.stats, { api: 0, preset: 0, late: 0, light: 0, apiMs: 0, waited: 0, injected: 0 });
|
|
931
|
+
this.lastInjectedAt = '';
|
|
875
932
|
this.writeLog();
|
|
876
933
|
return '已清空';
|
|
877
934
|
},
|
|
@@ -881,11 +938,14 @@ export class HumanizeWorld implements World {
|
|
|
881
938
|
const prefixLamp: WorldLamp = stale
|
|
882
939
|
? { label: '系统前缀', state: this.cfg.autoRefresh ? 'loading' : 'error', hint: this.cfg.autoRefresh ? '等桌宠空闲后自动刷新' : '需要刷新:把活人感关掉再打开一次' }
|
|
883
940
|
: { label: '系统前缀', state: 'online', hint: `最新(${MODE_LABEL[this.mode()]})` };
|
|
941
|
+
const provider = this.providerStatus();
|
|
884
942
|
return {
|
|
885
943
|
label: '活人感',
|
|
886
|
-
lamps: [lamp, prefixLamp],
|
|
944
|
+
lamps: [lamp, prefixLamp, provider.lamp],
|
|
887
945
|
badges: [
|
|
888
946
|
{ label: '前缀', value: stale ? '需要刷新' : '最新', tone: stale ? 'off' : 'on' },
|
|
947
|
+
{ label: 'provider', value: provider.badge, tone: provider.lamp.state === 'online' ? 'on' : provider.lamp.state === 'offline' ? 'plain' : 'off' },
|
|
948
|
+
{ label: 'provider 注入', value: this.stats.injected, tone: this.stats.injected ? 'on' : 'plain' },
|
|
889
949
|
{ label: '副 API 引导', value: this.stats.api, tone: 'on' },
|
|
890
950
|
{ label: '预设兜底', value: this.stats.preset, tone: 'plain' },
|
|
891
951
|
{ label: '等内心再开口', value: this.stats.waited, tone: 'plain' },
|