DeepSHPlugins
mosaic-memory-compress 專案預覽
GITHUB / COMMUNITY PROJECT

mosaic-memory-compress

記憶與知識TypeScriptMIT

為 DeepSeek Harness 提供基於自然遺忘曲線的就地對話壓縮:近期對話逐字保留、中期結構化脫水(零 LLM 成本)、久遠對話摺疊為有界摘要對——有限記憶預算上的無限對話。

3 StarsTuringCorp-net 更新時間 2026-09-06
訪問 GitHub 倉庫
mosaic-memory-compress 專案預覽

專案介紹

中文

為 DeepSeek Harness 提供基於自然遺忘曲線的就地對話壓縮:近期對話逐字保留、中期結構化脫水(零 LLM 成本)、久遠對話摺疊為有界摘要對——有限記憶預算上的無限對話。

English

Forgetting-curve in-place dialogue compression for DeepSeek Harness: recent turns stay verbatim, middle turns are structurally dehydrated (zero-LLM), ancient turns fold into a bounded summary pair — unbounded conversations on a bounded memory budget.

專案資訊與收錄訊號

快照 2026-09-11
作者 / 組織
TuringCorp-net
倉庫
TuringCorp-net/mosaic-memory-compress
GitHub Stars
3
Forks
1
開發語言
TypeScript
許可證
MIT
最近推送
2026-09-06
Manifest
資料中檢測到宣告

公開倉庫不自動等於可商用;許可證與當前相容性以原專案文件為準。Manifest 和資料評分不構成安裝安全認證。

資料評分

66/ 100
維護活躍
97
文件與實用資訊
100
生態關注度
25
安裝便捷訊號
100
專案宣告訊號
100

近 5 天仍在更新;README 含完整安裝與使用說明;關注度尚低(3)。

評分來自已有資料快照的五維模型,僅作瀏覽參考,不是實際使用評測或安全檢測結論。

安裝與使用

所有專案資料與許可均以對應 GitHub 倉庫為準。

dsh plugin --profile web add github:TuringCorp-net/mosaic-memory-compress

複製命令不會自動執行。請先閱讀倉庫文件,確認環境要求與許可證。

專案截圖

倉庫 README

GitHub 原文

已儲存的倉庫文件快照;文件抓取時間未記錄,可能與上方目錄介紹處於不同版本。安裝前請核對當前倉庫說明。

儲存庫檔案保留原文,指令與授權文字不作自動改寫。

MosaicMemoryCompress

Supports DeepSeek Harness Awesome DSH Plugin

A generic, pluggable stateless dialogue compression algorithm — works with any LLM agent framework, and ships a ready-to-use adapter module for DeepSeek Harness (DSH).

License: MIT TypeScript Supports DSH GitHub stars npm

LLM conversations grow linearly. MosaicMemoryCompress keeps them bounded — automatically, invisibly, and without the user ever knowing what a "Session" is.

How It Works

Your message array (R rounds, oldest → newest):

Round 1 ────→ Round (R-30)   │ Heavy zone → ALL → 2 msgs
Round (R-29) → Round (R-10)  │ Light zone → structural truncation, count unchanged
Round (R-9) ────→ Round R    │ Raw zone  → keep as-is

Steady state: constant message count — 2 + heavyStart × (messages per round), e.g. 62 messages (31 user rounds) for pure two-message rounds, whether at round 60 or round 15,000 (higher, but still constant, when tool-call rounds add messages). The compression ratio approaches 100%.

Philosophy: Alive Memory, Not a Handover Brief

The industry-standard answer to unbounded conversations is threshold summarization: when the window fills up, summarize everything into one brief and hand it to a fresh model. The conversation looks like it continues. But structurally it is *amnesia followed by reading a diary*:

  • A switch moment. Memory breaks, then is rebuilt from a single summary call.
  • Indiscriminate loss. The freshest instructions are paraphrased too — the

exact part that must stay vivid. In a controlled A/B experiment the brief paraphrased the user's latest instruction and silently dropped an action item ("write the key points into MEMORY").

  • Invisible loss. The next model cannot know what the brief omitted, so it

cannot compensate.

MosaicMemoryCompress models the opposite: biological forgetting. A human does not remember round 3 of a 300-round conversation — they keep the lesson, the rules, the relationship. The algorithm reproduces that curve inside one message array:

recent 10 rounds   → verbatim (vivid — what you are actually working on)
rounds 10–40       → structural truncation (reasoning/args/results trimmed, text kept)
rounds 40+         → one heavy pair: identity, environment, permissions, rules

No switch moment, no reset, no length limit. The heavy zone is *semantic memory* (rules that must never be forgotten); the middle is recent episodic memory; the raw zone is the vivid present. Loss is visible: the zone structure tells the model what it no longer knows, so it can fetch detail from shadowed storage on demand.

Threshold summarization (industry)MosaicMemoryCompress
Metaphoramnesia + diarycontinuous vivid memory
Continuityresets on every compactionnever resets
Lossindiscriminate, invisiblegraduated, visible
Recent turnsparaphrased at the worst momentalways verbatim
Purposeportable handover briefunbounded human–AI dialogue

The two philosophies complement each other: a handover brief serves cold starts and long pauses; MosaicMemoryCompress serves *staying in the conversation*. Combined with a durable host-side store (e.g. a MEMORY.md file), human and AI keep talking under the same forgetting curve indefinitely. See docs/design.md §8/§10 for the formal position-is-age model behind this design.

Quick Start

npm install mosaic-memory-compress
import { mosaicMemoryCompress, type MosaicMemoryConfig } from 'mosaic-memory-compress';

const config: MosaicMemoryConfig = {
  lightStart: 10,    // keep 10 most recent rounds raw (vivid)
  lightWindow: 30,   // compress every 30 rounds (aligned with heavy)
  heavyStart: 40,    // rounds before this enter the heavy zone
  heavyWindow: 30,   // heavy fold cadence (30-round interval)
  callLLM: async (systemPrompt, userInput) => {
    // Wire to OpenAI, Anthropic, or any LLM provider
    const res = await openai.chat.completions.create({
      model: 'gpt-4o-mini',
      messages: [
        { role: 'system', content: systemPrompt },
        { role: 'user', content: userInput },
      ],
    });
    return res.choices[0].message.content ?? '';
  },
};

// Call every turn — zero cost below threshold; structural light is millisecond-fast,
// Heavy folds take ~1-2s (one LLM summary call)
const compressed = await mosaicMemoryCompress(messages, config);

Features

  • Stateless & repeatable — no session state; call it every turn, and the output can be fed back in as input
  • Zero-cost below threshold — returns immediately if no compression is due
  • Anti-jitter — compression only at configurable window boundaries
  • LLM-agnostic — bring your own callLLM function for Heavy (OpenAI, Anthropic, local models…); light runs zero-LLM
  • DeepSeek Harness (DSH) adapter — ships with dsh-module/ for seamless integration; the core algorithm stays framework-agnostic
  • Tool-call safe — tool messages don't break round counting
  • Graceful degradation — LLM failures don't block the conversation

API

mosaicMemoryCompress(messages, config)

ParamTypeDescription
messagesMessage[]Full message array. System prompt at [0] is preserved as-is.
configMosaicMemoryConfigCompression config (see below).
ReturnsPromise<Message[]>Compressed message array.

MosaicMemoryConfig

FieldTypeDefaultDescription
lightStartnumber30Most recent N rounds kept raw
lightWindownumber10Anti-jitter: compress every N rounds
heavyStartnumber50Rounds beyond this → Heavy zone
heavyWindownumber10Anti-jitter for heavy compression
callLLM(sys: string, user: string) => Promise<string>*optional*Your LLM call function — Heavy zone only; light is structural truncation. Omit it for light-only usage
onCompress`(event: CompressEvent) => void \Promise`*optional*Hook after each compression; receives the original payload for host-side archiving

DEFAULT_CONFIG

Prefer starting from the exported defaults and overriding only what you need:

import { mosaicMemoryCompress, DEFAULT_CONFIG, type MosaicMemoryConfig } from 'mosaic-memory-compress';

const config: MosaicMemoryConfig = { ...DEFAULT_CONFIG, callLLM: async (sys, user) => { /* ... */ } };

All numeric fields must be positive integers (windows) / non-negative integers (starts), and heavyStart must be greater than lightStart. Invalid configs throw a TypeError.

Message

interface Message {
  role: 'system' | 'user' | 'assistant' | 'tool';
  content: string;
  tool_call_id?: string;
  tool_calls?: { id: string; type: 'function'; function: { name: string; arguments: string } }[];
}

Design

Read the full design document (English) or 中文设计文档.

Architecture Boundaries

MosaicMemoryCompress is intentionally stateless and lossy:

  • Durable storage is the host's responsibility. The library compresses

the message array in place and never persists original payloads. Hosts that need lossless history must archive the raw messages themselves — through their own code, a database, or the host platform's persistence layer (the onCompress callback hands every compressed-away original to the host for archiving).

  • Compression is lossy by design. Like any summarization approach, early

details fade progressively. That is the point: the goal is an unbounded conversation, not lossless archival. If exact retrieval of early turns matters, pair this library with a persistence layer and re-read on demand.

Integration Notes

MosaicMemoryCompress is host-agnostic and works wherever a callLLM function exists. Its primary integration reference is DeepSeek Harness (DSH) (deepseek-ai/deepseek-harness — everything is a plugin), whose task-level compaction / output retention / spill complement this library's message-level compression (roles and order preserved). ### DSH adapter: session allowlist (safety gate)

By default the adapter compresses nothing until you explicitly list session ids — a first-time trial can never touch your other conversations:

# cordis.patch.yml (or the plugin config)
config:
  sessionAllowlist:
    - fb80be2a-99aa-42e1-9de8-2f7017d2c0b6   # only this session is compressed

Use ['*'] to allow every session (the pre-allowlist behavior). Sessions not listed are a zero-cost no-op.

A denylist (sessionDenylist) always wins over the allowlist — it keeps selected sessions out of a fleet-wide rollout, e.g. one reference conversation that should stay unmanaged for diagnosis:

config:
  sessionAllowlist: ['*']              # fleet-wide
  sessionDenylist:                     # except these
    - fb80be2a-99aa-42e1-9de8-2f7017d2c0b6   # reference conversation, never compressed

A ready-to-use DSH plugin backend lives in dsh-module/ (design docs in EN/中文).

Related:

See the Roadmap for upcoming work.

Benchmark

A deterministic simulation (zero LLM cost, reproducible) runs the real algorithm with a rule-based pseudo-LLM. Latest sweep (default parameters):

Context growth: uncompressed vs MosaicMemoryCompress (log scale)

Roundsmsgs inmsgs outtokens intokens outratiofacts kept
1002341209,4514,58051.5%100%
1,0002,31012291,8695,52394.0%100%
5,00011,500120457,4849,91397.8%100%
npm run bench                        # synthetic sweep: 100 / 500 / 1000 / 5000 rounds
npm run bench -- --file chat.json    # analyze your own conversation file

The file mode accepts any JSON array of messages in the library's Message shape and reports the compression ratio:

[{"role": "system", "content": "..."},
 {"role": "user", "content": "..."},
 {"role": "assistant", "content": "..."}]

See benchmark/README.md for the full method, data generation, findings, limitations, and the real-LLM spot check (npm run bench:real — DeepSeek V4 Flash, <$0.01, 5/5 facts retained).

Development

# Run tests (zero LLM cost — uses mock responses)
npm test

# Type-check the whole project
npm run typecheck

# Or directly:
npx tsx tests/index.test.ts

License

MIT — TuringCorp | [email protected]

使用前核對

安裝步驟、相容版本與授權範圍以原專案當前文件為準。Stars 和評分是快照中的導航訊號。

安裝與排錯 · 專案問題反饋

同類專案