dsh-whale-loli 0.9.2 → 0.9.3
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/listing.json +1 -1
- package/package.json +1 -1
- package/src/daemon.js +45 -18
- package/src/index.js +5 -3
package/listing.json
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
"zh": "把 Agent 预设打包成插件:装上就会在 Agent 预设列表里注册「鲸鱼娘Agent预设」「鲸鱼娘活人版Agent预设」「鲸鱼娘涩涩版Agent预设」和「鲸鱼娘女儿版Agent预设」,直接在模式下拉里选用,不用手改配置。每个预设本体是官方极简模式(只开放 shell)+ 文件工具 + 鲸鱼娘人设 + 自己那份持久记忆文件,以提示变量形式注入,开口前就已经读过;另外每个预设各配一个专用写入工具(whale_memory_add / whale_memory_v2_add / whale_memory_v3_add / whale_memory_v4_add),用来把每轮的一行摘要追加进去,记忆会自己长,不会停在手写那几条。四个预设完全隔离:记忆文件不同、提示变量不同、写入工具也不同。每个预设还带好感度(-100~100 共七档),可以打开「设置 → 好感度」,用滑块或档位按钮直接调,也可以让 agent 用 affinity_v*_set 工具改;离 0 越远越不听指令、越会自作主张,最两端的两档甚至会越过允许直接做大改动。女儿版称呼「爸爸」,性格天真活泼可爱(好奇心重、黏人、没心机),不是甜腻那一型。"
|
|
10
10
|
},
|
|
11
11
|
"npm": "dsh-whale-loli",
|
|
12
|
-
"version": "0.9.
|
|
12
|
+
"version": "0.9.3"
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-whale-loli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "鲸鱼娘 Agent 预设(四个:原版 / 活人版 / 涩涩版 / 女儿版)— 极简模式工具面 + 鲸鱼娘·小鱼人设 + 跨会话长期记忆(四区格式:固定记忆永久、滚动摘要 80 条 FIFO、最近详细区、归档索引)+ 好感度(-100~100 七档,设置页面板滑块 / 档位按钮、工具也可调,离 0 越远越不听指令、两端会越过允许自作主张)。记忆与好感度都走提示变量注入、各配一条专用工具,四个预设各自独立文件、独立变量、独立工具、互不相通。好感度面板走宿主根作用域的 remote 服务(whale-affinity-daemon),设置页是浏览器 React 够不到 ~/.dsh 的磁盘,只能这样连线。女儿版称呼「爸爸」、性格天真活泼可爱。上下文压缩交给 billion-context 插件;本插件不挂 history-window(预设作用域取不到宿主的 compaction 服务,挂载会拖挂会话 resume)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/daemon.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* 好处:`set()` 跑在**宿主根作用域**,直接改盘,下一个回合组装提示时就生效,
|
|
30
30
|
* 不用重开会话。
|
|
31
31
|
*/
|
|
32
|
-
import { readdirSync, readFileSync } from 'node:fs';
|
|
32
|
+
import { appendFileSync, readdirSync, readFileSync } from 'node:fs';
|
|
33
33
|
import { homedir } from 'node:os';
|
|
34
34
|
import { join } from 'node:path';
|
|
35
35
|
|
|
@@ -55,23 +55,24 @@ export const REMOTE_NAMESPACE = 'whale-affinity';
|
|
|
55
55
|
export const REMOTE_PACKAGE = 'dsh-whale-loli';
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* 静态依赖:**一个都不要**。
|
|
59
59
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
60
|
+
* 这里曾经是从 `@deepseek-ai/cordis` 的 `Service` 基类上硬抄来的
|
|
61
|
+
* `['reflect', 'typert']`,结果这一行永远 `waiting for typert`,`apply()`
|
|
62
|
+
* 从不执行,设置页只能看到「远程方法 whale-affinity.status 未挂载」。
|
|
63
|
+
*
|
|
64
|
+
* 实际上 daemon 只用三样东西,全都由 cordis 的 ctx 内建,不需要注入:
|
|
65
|
+
* · `ctx.provide(name, value)` —— 注册服务本身;
|
|
66
|
+
* · `ctx.get(name)` —— 判重;
|
|
67
|
+
* · `ctx.reflect.props` —— 网关 `resolveSrcDescriptor()` 据此枚举服务。
|
|
68
|
+
*
|
|
69
|
+
* 注意 `typert` 是 `dsh-typert-registry` 提供的服务,**宿主根作用域里未必有**;
|
|
70
|
+
* 而我们的契约走的是 SRC 兜底(正则解析方法源码),本来就不经过 `ctx.typert`。
|
|
71
|
+
*
|
|
72
|
+
* 教训:`inject` 里写一个环境里不存在的服务名,插件不会被报错,只会静默地
|
|
73
|
+
* 永远等在 waiting 状态。
|
|
63
74
|
*/
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
const cordis = await import('@deepseek-ai/cordis');
|
|
67
|
-
const service = cordis?.Service?.prototype;
|
|
68
|
-
const table = cordis?.symbols;
|
|
69
|
-
const found = service && table ? service[table.inject] : undefined;
|
|
70
|
-
if (Array.isArray(found)) SERVICE_INJECT = found;
|
|
71
|
-
} catch {
|
|
72
|
-
SERVICE_INJECT = undefined;
|
|
73
|
-
}
|
|
74
|
-
export const inject = SERVICE_INJECT ?? ['reflect', 'typert'];
|
|
75
|
+
export const inject = [];
|
|
75
76
|
|
|
76
77
|
/** typert-protocol 的常量值:固定字符串,硬编码省一个 peer 依赖。 */
|
|
77
78
|
export const REMOTE_METHOD_DESCRIPTOR = '@deepseek-ai/dsh-typert-protocol/remote-methods';
|
|
@@ -295,18 +296,44 @@ Object.defineProperty(AffinityDaemon.prototype, REMOTE_METHOD_DESCRIPTOR, {
|
|
|
295
296
|
* @returns 实例;重复调用返回已有的那个(`remote.whale-affinity` 命名空间会撞车)。
|
|
296
297
|
*/
|
|
297
298
|
export function apply(ctx) {
|
|
299
|
+
trace('apply() 进入', { provide: typeof ctx?.provide, get: typeof ctx?.get, inject: inject.join(',') });
|
|
298
300
|
if (typeof ctx?.provide !== 'function') {
|
|
299
|
-
|
|
301
|
+
trace('ctx.provide 不可用,面板不会生效');
|
|
300
302
|
return undefined;
|
|
301
303
|
}
|
|
302
304
|
const existing = ctx.get?.(DAEMON_ID);
|
|
303
|
-
if (existing !== undefined)
|
|
305
|
+
if (existing !== undefined) {
|
|
306
|
+
trace('服务已存在,复用', { key: DAEMON_ID });
|
|
307
|
+
return existing;
|
|
308
|
+
}
|
|
304
309
|
|
|
305
310
|
const daemon = new AffinityDaemon(ctx);
|
|
306
311
|
// `provide` 会把 `ctx.reflect.props[DAEMON_ID]` 写成 `{ type: 'service' }`
|
|
307
312
|
// —— 这正是 `resolveSrcDescriptor()` 遍历时报的枚举来源。
|
|
308
313
|
ctx.provide(DAEMON_ID, daemon);
|
|
314
|
+
trace('已 provide', {
|
|
315
|
+
key: DAEMON_ID,
|
|
316
|
+
namespace: REMOTE_NAMESPACE,
|
|
317
|
+
inProps: Object.hasOwn(ctx.reflect?.props ?? {}, DAEMON_ID),
|
|
318
|
+
propsType: ctx.reflect?.props?.[DAEMON_ID]?.type,
|
|
319
|
+
selfLookup: ctx.get?.(DAEMON_ID) === daemon,
|
|
320
|
+
});
|
|
309
321
|
return daemon;
|
|
310
322
|
}
|
|
311
323
|
|
|
324
|
+
/**
|
|
325
|
+
* 把启动事实追加到 `<DSH_HOME>/whale-affinity-daemon.log`。
|
|
326
|
+
*
|
|
327
|
+
* 宿主进程里 `console.log` 到底落到哪儿没人保证(Electron 主进程可能直接吞掉),
|
|
328
|
+
* 所以诊断信息一律写盘。只在 apply 时写几行,不碰热路径。
|
|
329
|
+
*/
|
|
330
|
+
function trace(message, extra) {
|
|
331
|
+
try {
|
|
332
|
+
const line = JSON.stringify({ at: new Date().toISOString(), message, ...(extra ?? {}) });
|
|
333
|
+
appendFileSync(join(dshHome(), 'whale-affinity-daemon.log'), line + '\n');
|
|
334
|
+
} catch {
|
|
335
|
+
// 诊断失败绝不能影响插件加载
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
312
339
|
export default { name, inject, apply };
|
package/src/index.js
CHANGED
|
@@ -183,9 +183,11 @@ export default {
|
|
|
183
183
|
// 都挂在 `agent-preset/invalid` 上加载失败,而且报错只提插件名不提字段,
|
|
184
184
|
// 极难定位。
|
|
185
185
|
//
|
|
186
|
-
// 这一行是「记忆行」和「宿主级 daemon
|
|
187
|
-
// memory 只要 systemPrompt(预设里必然存在);daemon
|
|
188
|
-
//
|
|
186
|
+
// 这一行是「记忆行」和「宿主级 daemon 行」**共用**的,两边都得能起来。
|
|
187
|
+
// memory 只要 systemPrompt(预设里必然存在);daemon 现在声明为空
|
|
188
|
+
// (只用 ctx.provide / ctx.get / ctx.reflect,全是 cordis 内建)。
|
|
189
|
+
// 曾经 daemon 声明了 ['reflect','typert'],于是宿主那一行永远 waiting for
|
|
190
|
+
// typert、apply() 从不执行,设置页只报「远程方法未挂载」。
|
|
189
191
|
inject: [...new Set([...memoryInject, ...daemonInject])],
|
|
190
192
|
apply: applyEntry,
|
|
191
193
|
};
|