lume-dsh-plugin 0.6.0 → 0.6.2

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/lib/index.js CHANGED
@@ -18,7 +18,7 @@ import { defineDomain, domainTable } from "@deepseek-ai/dsh-storage-domain";
18
18
  import { BlockAssembler, createUserMessage, ReasoningEffortId } from "@deepseek-ai/dsh-llm";
19
19
  import { defineTool } from "@deepseek-ai/dsh-tools";
20
20
  import z from "@deepseek-ai/schemastery";
21
- import { buildPersonaSection } from "./host/injection.js";
21
+ import { buildPersonaContractSection, buildPersonaRuntimeSection } from "./host/injection.js";
22
22
  import { loadPersonalities, NONE_PERSONA } from "./host/personalities.js";
23
23
  import { createLumeRpcHandler } from "./host/rpc.js";
24
24
  import { FilePersonaStore, migrateLegacyState, PersonaStore } from "./host/store.js";
@@ -27,6 +27,7 @@ import { PersonaRegistry } from "./host/registry.js";
27
27
  import { buildCorrectionPrompt, buildExtractionPrompt, extractNaming, isCoolingDown, isDuplicateFact, mergeNewFacts, parseCorrectionRule, parseFacts, resolveAuxRoute, shouldCaptureCorpus, shouldConsider, shouldConsiderCorrection } from "./host/extraction.js";
28
28
  import { DistillJobRunner, DISTILL_ALGORITHM_VERSION, runDistill } from "./host/distill.js";
29
29
  import { jaccard } from "./core/retrieval.js";
30
+ import { fnv1a32 } from "./core/sampling.js";
30
31
  import { detectLeak } from "./core/leak-detector.js";
31
32
  import { messageText } from "./core/text.js";
32
33
  import { composeBoundary } from "./host/boundary.js";
@@ -34,8 +35,9 @@ import { SessionRuntimeStore } from "./host/session-runtime.js";
34
35
  import { isCompactionCheckpoint } from "./host/compaction.js";
35
36
  import { LUME_REFLECTION_SPEC, ReflectionStore, buildReflectionPrompt, parseReflectionScore } from "./host/reflection.js";
36
37
  import { appendLumeLog } from "./host/diag.js";
37
- import { advancePhase, buildAlignmentCorrection, buildCompactionNotice, buildInteractionDirective, buildLongSessionGuard, buildSessionAnchor, buildTaskPhaseDirective, buildToolFailureNotice, classifyInteraction, isUserAuthored, taskPhaseForMode } from "./host/protocol.js";
38
- import { REASONING_MODEL_RE, TASK_SIGNAL_RE, selectThinkingProtocol } from "./host/thinking.js";
38
+ import { advancePhase, buildAlignmentCorrection, buildCasualDirective, buildCompactionNotice, buildInteractionDirective, buildLongSessionGuard, buildSessionAnchor, buildTaskPhaseDirective, buildToolFailureNotice, classifyInteraction, isUserAuthored, taskPhaseForMode } from "./host/protocol.js";
39
+ import { buildDocumentDirective, probeDocumentCapabilities } from "./host/documents.js";
40
+ import { REASONING_MODEL_RE, TASK_SIGNAL_RE, selectStableThinkingProtocol } from "./host/thinking.js";
39
41
  /** schemastery → domainTable 形参的桥接(与 identity.ts 同款)。 */
40
42
  const recordSchema = zodLike;
41
43
  /** 会话人设选择的持久层(键 = sessionId)。 */
@@ -55,16 +57,38 @@ const LLM_DUMP_PATH = process.env.DSH_HOME
55
57
  const LUME_PERSONA_SECTION = "lume:persona";
56
58
  const LUME_THINKING_SECTION = "lume:thinking";
57
59
  const LUME_THINKING_ORDER = 1;
58
- /** 人设段与播报段的 order:取 10000+/10100——真正的 system prompt 末尾。
59
- * 宿主的段落布局是:身份声明 -1000(最前,"你是 AI 助手"的来源)、策略 500-900、
60
- * 工具定义 1000-5000、结构化输出 9900。人设若按惯例放 order 2,会被压在头部
61
- * 身份声明与近万 token 工具内容之间——实测模型会无视中段的人设契约、直接以
62
- * "AI 助手"自居。放在最末尾(紧贴对话历史、注意力最强)后,人格合规才成立。 */
60
+ /** 人设契约段(会话恒定)的 order:取 10000——真正的 system prompt 末尾。
61
+ * 宿主的段落布局是:身份声明 -1000(最前,"你是 AI 助手"的来源)、部署 persona 前缀 0、
62
+ * 策略 500-900、工具定义 1000-5000、结构化输出 9900。人设若按惯例放 order 2,会被压在
63
+ * 头部身份声明与近万 token 工具内容之间——实测模型会无视中段的人设契约、直接以
64
+ * "AI 助手"自居。放在最末尾(紧贴对话历史、注意力最强)后,人格合规才成立。
65
+ * 该段在一个会话内必须逐字节恒定:见 LUME_RUNTIME_CONTEXT 的说明。 */
63
66
  const LUME_PERSONA_ORDER = 10000;
64
- const LUME_BOUNDARY_SECTION = "lume:boundary";
67
+ /**
68
+ * 易变注入段(记忆 top-k、风格约定、语料示例、切换播报、路由/阶段/护栏/锚点、
69
+ * 压缩重锚、文档指引)——走宿主 runtime-context 通道,渲染成对话尾部的一条快照消息。
70
+ *
71
+ * 为什么不能留在 system 段:system 串排在消息序列最前面,而前缀缓存只认「从第一个
72
+ * 不同的字节起,之后全部失效」。只要 system 串每步变一次,它后面的工具定义、结构化
73
+ * 输出和**整段对话历史**就全部按全价重算。实测(deepseek-v4-flash,2026-09-11 某会话
74
+ * 282 个请求):cacheRead 恒定 384 token、命中率中位数 0.2%;当日全站命中率 18%。
75
+ * 而宿主内置的 `systemPromptUpdate: "in-history"`(把系统提示词变化以追加方式落在
76
+ * 历史尾部)只在 `deepseek-flash` 一个内置模型条目上声明,v4 系没有——所以这层拆分
77
+ * 是插件侧唯一能拿回缓存的手段。
78
+ *
79
+ * 宿主的 runtime-context 语义正好对症:assemble 时求值、append 到消息尾部,且文案声明
80
+ * "supersedes earlier runtime-context snapshots"(新快照取代旧快照,不堆叠进历史),
81
+ * 因此它每一次变化只花自己那几百 token。
82
+ */
83
+ const LUME_RUNTIME_CONTEXT = "lume:runtime";
84
+ const LUME_RUNTIME_ORDER = 10000;
85
+ /** 人设易变段(记忆 top-k / 风格约定 / 语料示例):同走 runtime-context,排在任务指令之后。 */
86
+ const LUME_PERSONA_RUNTIME_CONTEXT = "lume:persona-runtime";
87
+ const LUME_PERSONA_RUNTIME_ORDER = 10050;
88
+ /** 人设切换播报:独立成段(只在切换窗口内有内容),便于单独观测与测试。 */
89
+ const LUME_BOUNDARY_CONTEXT = "lume:boundary";
65
90
  const LUME_BOUNDARY_ORDER = 10100;
66
- /** 工具失败提示:走 runtime-context 通道(渲染成对话尾部的一条消息),
67
- * 不进 system 串——避免会变的内容每步作废前缀缓存。 */
91
+ /** 工具失败提示:同走 runtime-context 通道,排在易变段之后。 */
68
92
  const LUME_TOOL_NOTICE_CONTEXT = "lume:tool-notice";
69
93
  const LUME_TOOL_NOTICE_ORDER = 10150;
70
94
  const MAX_SESSIONS = 200;
@@ -89,6 +113,14 @@ export function apply(ctx, config = {}) {
89
113
  const distillRouteOverride = { provider: config.distillProvider, model: config.distillModel };
90
114
  const reflectionEnabled = config.reflectionEnabled ?? true;
91
115
  const boundaryTurns = config.switchBoundaryTurns ?? SWITCH_BOUNDARY_TURNS;
116
+ const layeredInjection = config.layeredInjection ?? true;
117
+ /** 宿主是否提供 runtime-context 通道(0.1.5 起的 API)。 */
118
+ const runtimeContextSupported = typeof ctx.systemPrompt?.context === "function";
119
+ /** 是否真的走分层:用户没关掉、且宿主支持。否则易变段并回 system 段(旧行为)。 */
120
+ const layeredOn = layeredInjection && runtimeContextSupported;
121
+ if (layeredInjection && !runtimeContextSupported) {
122
+ ctx.logger?.warn?.("lume: 当前宿主不支持 systemPrompt.context,易变注入段并回系统提示词(前缀缓存收益消失,功能不受影响)");
123
+ }
92
124
  const defaultName = builtins[NONE_PERSONA] ? NONE_PERSONA : null;
93
125
  const legacyStatePath = join(assetsDir, "persona-state.json");
94
126
  // ── 存储就绪:会话选择域(必有)+ 身份域(失败降级为无档案功能)──
@@ -156,7 +188,7 @@ export function apply(ctx, config = {}) {
156
188
  void reflectionReady.then((s) => { reflectionStore = s; });
157
189
  const registry = new PersonaRegistry(builtins, () => identity);
158
190
  ctx.logger?.warn?.(`lume: 已加载(builtins=${Object.keys(builtins).join(",") || "空!"},assets=${assetsDir})`);
159
- ctx.logger?.warn?.(`lume: 版本 0.3.3 — llmRoute 初始化策略:agentDefaultModel → settings → 回退`);
191
+ ctx.logger?.warn?.(`lume: llmRoute 初始化策略:agentDefaultModel → settings → 回退`);
160
192
  // ── 每会话运行时状态(内存,重启即弃,LRU 上限兜底)──
161
193
  const runtime = new SessionRuntimeStore();
162
194
  // ── 模型路由缓存(request/context,会话过程中由 agent-loop 更新)──
@@ -508,6 +540,12 @@ export function apply(ctx, config = {}) {
508
540
  }
509
541
  case "turn/end": {
510
542
  st.turnIndex++;
543
+ // 切换窗口的消耗只发生在轮边界(渲染函数只读状态,不再就地清零):
544
+ // 同一步里 prompt 会被构建多次,若在渲染里消耗窗口,第二次构建就会
545
+ // 丢掉接班招呼——那是「注入随构建次数漂移」,正是本版要消灭的东西。
546
+ st.switchGreetingPending = false;
547
+ if (st.switchTurn !== null && st.turnIndex - st.switchTurn >= boundaryTurns)
548
+ st.switchTurn = null;
511
549
  // 低成本会话内纠偏:只处理明确的错误/失败信号,且要求连续轮次用户请求相同。
512
550
  const failed = /失败|报错|错误|exception|traceback|cannot|unable|permission denied|timed out|找不到|不存在/i.test(st.assistantText);
513
551
  const queryKey = st.userText.trim().replace(/\s+/g, " ").slice(0, 240);
@@ -701,10 +739,37 @@ export function apply(ctx, config = {}) {
701
739
  }
702
740
  return { text: st.intent?.text ?? st.lastQuery ?? "", mode: st.interactionMode };
703
741
  }
704
- function buildSessionText(sid, context) {
705
- if (!currentStore)
706
- return "";
742
+ function computeTurn(sid, context) {
707
743
  const st = runtime.get(sid);
744
+ // 意图取自会话权威历史(resolveIntent),不再读事件缓存里的最新文本:
745
+ // 后者会被注入消息覆盖,且首步可能还带着上一轮的值,导致模式在轮内漂移。
746
+ const { text: query, mode } = resolveIntent(context, st);
747
+ // 协议正文按模型能力冻结(不随 query 切变体):切变体会让系统提示词每轮改写,
748
+ // 代价远超省下的几百 token。见 selectStableThinkingProtocol。
749
+ const thinkingStable = selectStableThinkingProtocol({
750
+ isReasoningModel: typeof llmRoute?.model === "string" && REASONING_MODEL_RE.test(llmRoute.model),
751
+ }).trim();
752
+ // 易变的任务指令:路由、阶段、闲聊声明、长会话护栏、目标锚点、即时对齐、
753
+ // 交付复核、压缩重锚、文档能力指引、失败纠偏、反思提醒——全部每步可变。
754
+ const thinkingRuntime = [
755
+ buildInteractionDirective(mode),
756
+ buildTaskPhaseDirective(st.taskPhase),
757
+ buildCasualDirective(TASK_SIGNAL_RE.test(query)),
758
+ buildLongSessionGuard(st.turnIndex),
759
+ buildSessionAnchor(st.turnIndex, mode, query, st.recentTurns),
760
+ st.alignmentCorrection,
761
+ st.postTurnReview,
762
+ st.compaction ? buildCompactionNotice(st.compaction, st.turnIndex) : null,
763
+ buildDocumentDirective({ query, capabilities: probeDocumentCapabilities(ctx.get("tools"), context?.agent) }),
764
+ st.protocolCorrection,
765
+ reflectionStore?.getFeedback() ?? null,
766
+ ]
767
+ .filter(Boolean)
768
+ .join("\n\n");
769
+ // 会话选择尚未就绪(启动竞态):只出任务协议,人设段留空——与旧实现一致,
770
+ // 也避免把「尚未选择」误记成一次人设切换。
771
+ if (!currentStore)
772
+ return { thinkingStable, thinkingRuntime, personaStable: "", personaData: "", boundary: "" };
708
773
  const selected = currentStore.get(sid);
709
774
  const personaName = selected ?? defaultName;
710
775
  const previous = st.lastInjected;
@@ -725,57 +790,51 @@ export function apply(ctx, config = {}) {
725
790
  const boundaryText = inWindow && st.switchTurn !== null
726
791
  ? composeBoundary({ registry, previous: st.prevPersona, current: personaName, greeting, escalated: st.leakEscalated })
727
792
  : null;
728
- // 播报改由独立的尾部 section 渲染(LUME_BOUNDARY_SECTION),人设段不再内联
729
- st.activeBoundary = boundaryText;
730
- const memories = personaName ? identity?.getMemory(personaName) ?? [] : [];
731
- const styleRules = personaName ? identity?.getStyleRules(personaName) ?? [] : [];
732
- const corpusPins = personaName ? identity?.getCorpusPins(personaName) ?? [] : [];
733
- const { text: query } = resolveIntent(context, st);
734
- // 一轮一算:注入段按查询做 top-k 检索,查询或记忆每步抖动会让整段改写,
735
- // 系统提示词随之在轮内变化(实测一轮产生 28 份),前缀缓存每步作废。
736
- // 指纹覆盖 persona、查询、记忆/风格/语料与注入配置;人设切换、边界窗口、
737
- // 记忆写入都会改变指纹而自动失效。
738
- const last = (list, field) => list.length > 0 ? list[list.length - 1]?.[field] : "";
739
- const key = [
740
- String(personaName),
741
- String(persona?.name ?? ""),
793
+ st.lastInjected = personaName;
794
+ // 恒定段:只依赖「谁在当值 + 契约正文 + 身份名」。检索结果、示例、播报都进易变段。
795
+ const profileName = personaName ? registry.profileNameOf(personaName) : null;
796
+ const personaStable = buildPersonaContractSection({ persona, profileName });
797
+ const personaData = buildPersonaRuntimeSection({
798
+ persona,
799
+ memories: personaName ? identity?.getMemory(personaName) ?? [] : [],
800
+ styleRules: personaName ? identity?.getStyleRules(personaName) ?? [] : [],
801
+ corpusPins: personaName ? identity?.getCorpusPins(personaName) ?? [] : [],
742
802
  query,
743
- String(st.turnIndex),
744
- String(memories.length),
745
- String(last(memories, "text")),
746
- String(styleRules.length),
747
- String(last(styleRules, "rule")),
748
- String(corpusPins.length),
749
- String(last(corpusPins, "assistant")),
750
- String(boundaryText ?? ""),
751
- String(sampleCount),
752
- String(sampleMin),
753
- String(memoryInject),
754
- String(styleInject),
755
- strategy,
756
- ].join("\u0001");
757
- let text = st.personaCache !== null && st.personaCache.key === key ? st.personaCache.text : null;
758
- if (text === null) {
759
- text = buildPersonaSection({
760
- persona,
761
- profileName: personaName ? registry.profileNameOf(personaName) : null,
762
- memories,
763
- styleRules,
764
- corpusPins,
765
- query,
766
- turnIndex: st.turnIndex,
767
- sessionKey: sid,
768
- boundaryText: null,
769
- config: { sampleCount, sampleMin, memoryInject, styleInject, strategy },
770
- });
771
- st.personaCache = { turnIndex: st.turnIndex, key, text };
803
+ turnIndex: st.turnIndex,
804
+ sessionKey: sid,
805
+ // 播报单独成段(lume:boundary),不混进数据段——便于单独观测与测试
806
+ boundaryText: null,
807
+ config: { sampleCount, sampleMin, memoryInject, styleInject, strategy },
808
+ });
809
+ // 现场可观测:恒定段指纹每变一次写一行诊断。健康会话只会留下 1-2 行
810
+ // (首次 + 人设切换);若长会话里反复出现,说明又有东西混进了 system 段。
811
+ const digest = fnv1a32(`${thinkingStable}\u0001${personaStable}`).toString(16);
812
+ if (st.stableDigest !== digest) {
813
+ st.stableDigest = digest;
814
+ appendLumeLog(`[${sid}] 系统段指纹 ${digest}(当值=${String(personaName)},身份=${String(profileName)},通道=${layeredOn ? "runtime-context" : "system(降级)"})`);
772
815
  }
773
- st.lastInjected = personaName;
774
- if (greeting)
775
- st.switchGreetingPending = false;
776
- if (st.switchTurn !== null && st.turnIndex - st.switchTurn >= boundaryTurns)
777
- st.switchTurn = null; // 窗口关闭
778
- return text;
816
+ return { thinkingStable, thinkingRuntime, personaStable, personaData, boundary: boundaryText ?? "" };
817
+ }
818
+ /**
819
+ * system 段取文:恒定段 +(宿主不支持 runtime-context 时)易变段。
820
+ * 降级时并回 system 是刻意的取舍——宁可丢前缀缓存,也不能丢记忆与播报注入。
821
+ */
822
+ function systemSectionText(sid, context, part) {
823
+ const turn = computeTurn(sid, context);
824
+ if (layeredOn)
825
+ return part === "thinking" ? turn.thinkingStable : turn.personaStable;
826
+ const stable = part === "thinking" ? turn.thinkingStable : turn.personaStable;
827
+ const dynamic = part === "thinking"
828
+ ? turn.thinkingRuntime
829
+ : [turn.personaData, turn.boundary].filter(Boolean).join("\n\n");
830
+ return [stable, dynamic].filter(Boolean).join("\n\n");
831
+ }
832
+ /** 易变段取文:任务指令 / 人设数据 / 切换播报三段各自成 context,由宿主按 order 归并成一条尾部快照。 */
833
+ function runtimeContextText(sid, context, part) {
834
+ const turn = computeTurn(sid, context);
835
+ if (part === "thinking")
836
+ return turn.thinkingRuntime;
837
+ return part === "persona" ? turn.personaData : turn.boundary;
779
838
  }
780
839
  // ── RPC 通道 ──
781
840
  const handleEndpoint = createLumeRpcHandler({
@@ -810,52 +869,36 @@ export function apply(ctx, config = {}) {
810
869
  order: personaOrder,
811
870
  text: (context) => {
812
871
  const sid = context.agent?.session?.id ?? context.agent?.id;
813
- return sid ? buildSessionText(String(sid), context) : "";
872
+ return sid ? systemSectionText(String(sid), context, "persona") : "";
814
873
  },
815
874
  }), "lume.persona-section()");
816
- ctx.effect(() => ctx.systemPrompt.section({
817
- name: LUME_BOUNDARY_SECTION,
818
- order: LUME_BOUNDARY_ORDER,
819
- text: (context) => {
820
- const sid = context.agent?.session?.id ?? context.agent?.id;
821
- // section 按 order 升序逐个求值:人设段(10000)先跑状态机,
822
- // 播报段(10100)读到的 activeBoundary 必是本轮最新值。
823
- return sid ? runtime.get(String(sid)).activeBoundary ?? "" : "";
824
- },
825
- }), "lume.boundary-section()");
875
+ // 易变段走 runtime-context 通道:宿主把它渲染成对话尾部的一条快照消息(文案自带
876
+ // "supersedes earlier runtime-context snapshots",新快照取代旧快照,不堆叠进历史),
877
+ // 因此它的每一次变化只花自己那几百 token,不作废前面的任何前缀。
878
+ // 宿主不支持该 API 时 layeredOn=false,易变段已并回 system 段(见 systemSectionText)。
879
+ if (layeredOn) {
880
+ const dynamicContexts = [
881
+ { name: LUME_RUNTIME_CONTEXT, order: LUME_RUNTIME_ORDER, part: "thinking" },
882
+ { name: LUME_PERSONA_RUNTIME_CONTEXT, order: LUME_PERSONA_RUNTIME_ORDER, part: "persona" },
883
+ { name: LUME_BOUNDARY_CONTEXT, order: LUME_BOUNDARY_ORDER, part: "boundary" },
884
+ ];
885
+ for (const entry of dynamicContexts) {
886
+ ctx.effect(() => ctx.systemPrompt.context({
887
+ name: entry.name,
888
+ order: entry.order,
889
+ text: (context) => {
890
+ const sid = context.agent?.session?.id ?? context.agent?.id;
891
+ return sid ? runtimeContextText(String(sid), context, entry.part) : "";
892
+ },
893
+ }), `lume.runtime-context(${entry.name})`);
894
+ }
895
+ }
826
896
  ctx.effect(() => ctx.systemPrompt.section({
827
897
  name: LUME_THINKING_SECTION,
828
898
  order: LUME_THINKING_ORDER,
829
899
  text: (context) => {
830
900
  const sid = context.agent?.session?.id ?? context.agent?.id;
831
- const st = sid ? runtime.get(String(sid)) : null;
832
- // 意图取自会话权威历史(resolveIntent),不再读事件缓存里的最新文本:
833
- // 后者会被注入消息覆盖,且首步可能还带着上一轮的值,导致模式在轮内漂移。
834
- const intent = st !== null && sid ? resolveIntent(context, st) : null;
835
- const query = intent?.text ?? "";
836
- // 已知推理型模型具备计划能力,任务轮只保留变更、验证、归因和复核约束;
837
- // 路由未知时使用完整版,避免误判造成能力退化。
838
- const base = selectThinkingProtocol({
839
- isTask: TASK_SIGNAL_RE.test(query),
840
- isReasoningModel: typeof llmRoute?.model === "string" && REASONING_MODEL_RE.test(llmRoute.model),
841
- });
842
- // 纠偏与反思提醒属于任务协议,跟人设无关——挂在 thinking 段
843
- // 才能在「不使用人设」的纯任务会话里也生效。
844
- const correction = st?.protocolCorrection;
845
- const reflectionHint = reflectionStore?.getFeedback() ?? null;
846
- const mode = intent?.mode ?? "question";
847
- const route = buildInteractionDirective(mode);
848
- const longSession = buildLongSessionGuard(st?.turnIndex ?? 0);
849
- const anchor = buildSessionAnchor(st?.turnIndex ?? 0, mode, query, st?.recentTurns ?? []);
850
- const alignment = st?.alignmentCorrection;
851
- const postTurnReview = st?.postTurnReview;
852
- const phase = buildTaskPhaseDirective(st?.taskPhase ?? "answer");
853
- // 工具失败提示已移到 runtime-context 通道(见 lume.tool-notice-context):
854
- // 它一出现就固定不变,但会变的内容不该待在 system 串里——那会作废前缀缓存。
855
- // 压缩重锚:宿主的 preset 隔离域负责压缩,Lume 只能观察事件;
856
- // 在压缩后一轮提醒「摘要不是完整历史」。
857
- const compactionNotice = st?.compaction ? buildCompactionNotice(st.compaction, st.turnIndex) : null;
858
- return [base, route, phase, longSession, anchor, alignment, postTurnReview, compactionNotice, correction, reflectionHint].filter(Boolean).join("\n\n");
901
+ return sid ? systemSectionText(String(sid), context, "thinking") : "";
859
902
  },
860
903
  }), "lume.thinking-section()");
861
904
  // 工具失败提示走 runtime-context 通道:宿主把它渲染成对话尾部的一条消息,
package/package.json CHANGED
@@ -1,112 +1,117 @@
1
- {
2
- "name": "lume-dsh-plugin",
3
- "description": "微光 (Lume) — DSH Desktop 增强插件:Codex 风格自适应任务执行协议 + 人设系统(聊天记录蒸馏具名角色、长期记忆、风格纠偏自动捕获)",
4
- "version": "0.6.0",
5
- "type": "module",
6
- "main": "lib/index.js",
7
- "exports": {
8
- ".": {
9
- "default": "./lib/index.js"
10
- },
11
- "./client": {
12
- "default": "./lib/client.js"
13
- },
14
- "./package.json": "./package.json"
15
- },
16
- "dsh": {
17
- "bundle": {
18
- "patch": "./cordis.patch.yml"
19
- },
20
- "client": {
21
- "inject": [
22
- "@deepseek-ai/dsh-client-connection",
23
- "@deepseek-ai/dsh-client-locale",
24
- "@deepseek-ai/dsh-client-runtime",
25
- "@deepseek-ai/dsh-client-ui-conversation",
26
- "@deepseek-ai/dsh-client-ui-primitives"
27
- ],
28
- "external": [
29
- "react",
30
- "react/jsx-runtime",
31
- "@deepseek-ai/dsh-client-ui-primitives"
32
- ],
33
- "platform": "web",
34
- "immediately": true
35
- }
36
- },
37
- "license": "MIT",
38
- "repository": {
39
- "type": "git",
40
- "url": "https://github.com/cayan0x/Lume.git"
41
- },
42
- "keywords": [
43
- "dsh-plugin",
44
- "persona",
45
- "personality",
46
- "identity",
47
- "memory"
48
- ],
49
- "engines": {
50
- "node": ">=20"
51
- },
52
- "peerDependencies": {
53
- "@deepseek-ai/cordis": "^4.0.1",
54
- "@deepseek-ai/dsh-client-ui-primitives": "*",
55
- "@deepseek-ai/dsh-llm": "*",
56
- "@deepseek-ai/dsh-storage-domain": "*",
57
- "@deepseek-ai/dsh-tools": "*",
58
- "@deepseek-ai/schemastery": "^3.18.1"
59
- },
60
- "scripts": {
61
- "build": "tsc -p tsconfig.build.json && tsdown",
62
- "bundle": "tsdown",
63
- "watch": "tsdown --watch",
64
- "test": "vitest run"
65
- },
66
- "devDependencies": {
67
- "@deepseek-ai/cordis": "^4.0.1",
68
- "@deepseek-ai/dsh-agent-default-model": "^0.1.0-rc.6",
69
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
70
- "@deepseek-ai/dsh-llm": "^0.0.1-rc.1",
71
- "@deepseek-ai/dsh-scope": "^0.0.1-rc.1",
72
- "@deepseek-ai/dsh-session": "^0.0.1-rc.1",
73
- "@deepseek-ai/dsh-storage": "^0.0.1-rc.1",
74
- "@deepseek-ai/dsh-storage-domain": "^0.0.1-rc.1",
75
- "@deepseek-ai/dsh-storage-json": "^0.0.1-rc.1",
76
- "@deepseek-ai/dsh-timeout": "^0.0.1-rc.1",
77
- "@deepseek-ai/dsh-tools": "^0.0.1-rc.1",
78
- "@deepseek-ai/schemastery": "^3.18.1",
79
- "@types/node": "^22.20.1",
80
- "@types/react": "~18.3.1",
81
- "tsdown": "^0.22.14",
82
- "typescript": "^5.9.3",
83
- "vitest": "^3.2.7"
84
- },
85
- "files": [
86
- "lib",
87
- "cordis.patch.yml",
88
- "assets/personalities.json",
89
- "assets/personalities/*.txt",
90
- "assets/personalities/*.jsonl"
91
- ],
92
- "peerDependenciesMeta": {
93
- "@deepseek-ai/cordis": {
94
- "optional": true
95
- },
96
- "@deepseek-ai/dsh-client-ui-primitives": {
97
- "optional": true
98
- },
99
- "@deepseek-ai/dsh-llm": {
100
- "optional": true
101
- },
102
- "@deepseek-ai/dsh-storage-domain": {
103
- "optional": true
104
- },
105
- "@deepseek-ai/dsh-tools": {
106
- "optional": true
107
- },
108
- "@deepseek-ai/schemastery": {
109
- "optional": true
110
- }
111
- }
112
- }
1
+ {
2
+ "name": "lume-dsh-plugin",
3
+ "description": "微光 (Lume) — DSH Desktop 增强插件:给会话装上工程纪律与真实关系。纪律层约束「如何正确完成任务」——意图路由、阶段门控、真实工具证据、交付前复核、文档能力感知;人设层塑造「以何种风格表达」——从聊天记录、小说、剧本、设定文档蒸馏具名角色,长期记忆与风格随对话演进。约束按需注入,闲聊不额外付 token。",
4
+ "version": "0.6.2",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "exports": {
8
+ ".": {
9
+ "default": "./lib/index.js"
10
+ },
11
+ "./client": {
12
+ "default": "./lib/client.js"
13
+ },
14
+ "./package.json": "./package.json"
15
+ },
16
+ "dsh": {
17
+ "bundle": {
18
+ "patch": "./cordis.patch.yml"
19
+ },
20
+ "client": {
21
+ "inject": [
22
+ "@deepseek-ai/dsh-client-connection",
23
+ "@deepseek-ai/dsh-client-locale",
24
+ "@deepseek-ai/dsh-client-runtime",
25
+ "@deepseek-ai/dsh-client-ui-conversation",
26
+ "@deepseek-ai/dsh-client-ui-primitives"
27
+ ],
28
+ "external": [
29
+ "react",
30
+ "react/jsx-runtime",
31
+ "@deepseek-ai/dsh-client-ui-primitives"
32
+ ],
33
+ "platform": "web",
34
+ "immediately": true
35
+ }
36
+ },
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/cayan0x/Lume.git"
41
+ },
42
+ "keywords": [
43
+ "dsh-plugin",
44
+ "persona",
45
+ "personality",
46
+ "identity",
47
+ "memory",
48
+ "protocol",
49
+ "task-execution",
50
+ "distillation",
51
+ "人设",
52
+ "记忆"
53
+ ],
54
+ "engines": {
55
+ "node": ">=20"
56
+ },
57
+ "peerDependencies": {
58
+ "@deepseek-ai/cordis": "^4.0.1",
59
+ "@deepseek-ai/dsh-client-ui-primitives": "*",
60
+ "@deepseek-ai/dsh-llm": "*",
61
+ "@deepseek-ai/dsh-storage-domain": "*",
62
+ "@deepseek-ai/dsh-tools": "*",
63
+ "@deepseek-ai/schemastery": "^3.18.1"
64
+ },
65
+ "scripts": {
66
+ "build": "tsc -p tsconfig.build.json && tsdown",
67
+ "bundle": "tsdown",
68
+ "watch": "tsdown --watch",
69
+ "test": "vitest run"
70
+ },
71
+ "devDependencies": {
72
+ "@deepseek-ai/cordis": "^4.0.1",
73
+ "@deepseek-ai/dsh-agent-default-model": "^0.1.0-rc.6",
74
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
75
+ "@deepseek-ai/dsh-llm": "^0.0.1-rc.1",
76
+ "@deepseek-ai/dsh-scope": "^0.0.1-rc.1",
77
+ "@deepseek-ai/dsh-session": "^0.0.1-rc.1",
78
+ "@deepseek-ai/dsh-storage": "^0.0.1-rc.1",
79
+ "@deepseek-ai/dsh-storage-domain": "^0.0.1-rc.1",
80
+ "@deepseek-ai/dsh-storage-json": "^0.0.1-rc.1",
81
+ "@deepseek-ai/dsh-timeout": "^0.0.1-rc.1",
82
+ "@deepseek-ai/dsh-tools": "^0.0.1-rc.1",
83
+ "@deepseek-ai/schemastery": "^3.18.1",
84
+ "@types/node": "^22.20.1",
85
+ "@types/react": "~18.3.1",
86
+ "tsdown": "^0.22.14",
87
+ "typescript": "^5.9.3",
88
+ "vitest": "^3.2.7"
89
+ },
90
+ "files": [
91
+ "lib",
92
+ "cordis.patch.yml",
93
+ "assets/personalities.json",
94
+ "assets/personalities/*.txt",
95
+ "assets/personalities/*.jsonl"
96
+ ],
97
+ "peerDependenciesMeta": {
98
+ "@deepseek-ai/cordis": {
99
+ "optional": true
100
+ },
101
+ "@deepseek-ai/dsh-client-ui-primitives": {
102
+ "optional": true
103
+ },
104
+ "@deepseek-ai/dsh-llm": {
105
+ "optional": true
106
+ },
107
+ "@deepseek-ai/dsh-storage-domain": {
108
+ "optional": true
109
+ },
110
+ "@deepseek-ai/dsh-tools": {
111
+ "optional": true
112
+ },
113
+ "@deepseek-ai/schemastery": {
114
+ "optional": true
115
+ }
116
+ }
117
+ }