Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,51 @@ Post-compression quality evaluation. Runs after each compression to verify summa

---

### `messageFilters`

Message filters strip or deduplicate third-party plugin injections (e.g. oh-my-opencode system reminders, context dumps, task directives) from the visible context **before** ACP processes them. Filtered content never gets a message ref and is never counted toward context usage or compression triggers.

Since v1.14.8, ACP ships five built-in oh-my-opencode (OMO) filters, all enabled by default:

| Filter | Version | Behavior |
|--------|---------|----------|
| `omo-system-reminder` | 1.3.0 | Keeps the last 2 OMO `<system-reminder>` messages; for older ones, strips the `<system-reminder>` blocks and `<!-- OMO_INTERNAL_INITIATOR -->` markers but preserves your actual user content |
| `omo-context` | 1.0.0 | Keeps only the latest OMO `[CONTEXT]` injection; drops earlier duplicates |
| `omo-task-directive` | 1.0.0 | Keeps only the latest OMO `TASK:` / `## TASK` directive; drops earlier ones |
| `omo-todo-continuation` | 1.0.0 | Keeps only the latest OMO TODO CONTINUATION directive; drops earlier ones |
| `omo-mode-injection` | 1.1.0 | Strips leading mode blocks (`<ultrawork-mode>`, `[search-mode]`, …) and preserves user content |

#### `messageFilters.enabled`
- **Type:** `boolean`
- **Default:** `true`
- **Status:** ACTIVE
- **Description:** Master switch. When `false`, no filters run.

#### `messageFilters.filters`
- **Type:** `object` — `Record<filterName, { enabled: boolean; keepLast?: number }>`
- **Default:** all built-in filters enabled
- **Status:** ACTIVE
- **Description:** Per-filter configuration. `enabled` toggles a single filter on/off. `keepLast` (dedup filters only) sets how many of the most recent matching messages to keep — default `1`, except `omo-system-reminder` which defaults to `2`.

Example:

```jsonc
{
"messageFilters": {
"enabled": true,
"filters": {
"omo-system-reminder": { "enabled": true, "keepLast": 2 },
"omo-context": { "enabled": true },
"omo-task-directive": { "enabled": true },
"omo-todo-continuation": { "enabled": true },
"omo-mode-injection": { "enabled": true }
}
}
}
```

---

## Common Config Recipes

### Aggressive compression (maximize context savings)
Expand Down Expand Up @@ -568,6 +613,28 @@ See the [`compress.providers`](#compressproviders) reference for the full overri
}
```

### Tune or disable oh-my-opencode (OMO) injection filters
The five built-in OMO filters are on by default (see [`messageFilters`](#messagefilters)). Keep more recent system-reminders, disable a single filter, or turn the whole subsystem off:
```jsonc
{
"messageFilters": {
"enabled": true,
"filters": {
// keep the last 3 OMO system-reminders instead of 2
"omo-system-reminder": { "enabled": true, "keepLast": 3 },
// disable one filter, keep the rest
"omo-task-directive": { "enabled": false }
}
}
}
```
```jsonc
{
// turn all message filters off
"messageFilters": { "enabled": false }
}
```

### Relocate session state storage

```jsonc
Expand Down
67 changes: 67 additions & 0 deletions CONFIGURATION.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,51 @@ ACP 从最多三层配置文件中读取(后加载的覆盖先加载的):

---

### `messageFilters`

消息过滤器在 ACP 处理之前,从可见上下文中**剥离或去重**第三方插件注入的内容(例如 oh-my-opencode 的 system reminder、上下文转储、任务指令)。被过滤的内容不会获得消息引用(message ref),也不会计入上下文使用量或压缩触发阈值。

自 v1.14.8 起,ACP 内置了 5 个 oh-my-opencode(OMO)过滤器,全部默认启用:

| 过滤器 | 版本 | 行为 |
|--------|------|------|
| `omo-system-reminder` | 1.3.0 | 保留最近 2 条 OMO `<system-reminder>` 消息;更早的会剥离 `<system-reminder>` 块和 `<!-- OMO_INTERNAL_INITIATOR -->` 标记,但**保留你的实际用户内容** |
| `omo-context` | 1.0.0 | 只保留最新的 OMO `[CONTEXT]` 注入;丢弃更早的重复项 |
| `omo-task-directive` | 1.0.0 | 只保留最新的 OMO `TASK:` / `## TASK` 指令;丢弃更早的 |
| `omo-todo-continuation` | 1.0.0 | 只保留最新的 OMO TODO CONTINUATION 指令;丢弃更早的 |
| `omo-mode-injection` | 1.1.0 | 剥离开头的模式块(`<ultrawork-mode>`、`[search-mode]` 等),保留用户内容 |

#### `messageFilters.enabled`
- **类型:** `boolean`
- **默认值:** `true`
- **状态:** ACTIVE
- **说明:** 主开关。设为 `false` 时不运行任何过滤器。

#### `messageFilters.filters`
- **类型:** `object` — `Record<filterName, { enabled: boolean; keepLast?: number }>`
- **默认值:** 所有内置过滤器启用
- **状态:** ACTIVE
- **说明:** 按过滤器配置。`enabled` 单独开关某个过滤器;`keepLast`(仅去重类过滤器)设置保留最近多少条匹配消息——默认 `1`,`omo-system-reminder` 除外(默认 `2`)。

示例:

```jsonc
{
"messageFilters": {
"enabled": true,
"filters": {
"omo-system-reminder": { "enabled": true, "keepLast": 2 },
"omo-context": { "enabled": true },
"omo-task-directive": { "enabled": true },
"omo-todo-continuation": { "enabled": true },
"omo-mode-injection": { "enabled": true }
}
}
}
```

---

## 常用配置模板

### 激进压缩(最大化上下文节省)
Expand Down Expand Up @@ -568,6 +613,28 @@ ACP 从最多三层配置文件中读取(后加载的覆盖先加载的):
}
```

### 调整或禁用 oh-my-opencode(OMO)注入过滤器
5 个内置 OMO 过滤器默认开启(见 [`messageFilters`](#messagefilters))。可以保留更多最近的 system-reminder、单独禁用某个过滤器,或整体关闭:
```jsonc
{
"messageFilters": {
"enabled": true,
"filters": {
// 保留最近 3 条 OMO system-reminder(默认 2 条)
"omo-system-reminder": { "enabled": true, "keepLast": 3 },
// 只禁用一个过滤器,其余保持
"omo-task-directive": { "enabled": false }
}
}
}
```
```jsonc
{
// 关闭所有消息过滤器
"messageFilters": { "enabled": false }
}
```

### 自定义会话状态存储位置

```jsonc
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,21 @@ Each level overrides the previous, so project settings take priority over global
},
},
},
// Message filters — strip/deduplicate third-party plugin injections
// (e.g. oh-my-opencode system reminders) from visible context before
// ACP processes them. Filtered content is never counted toward context
// usage. Five built-in OMO filters are on by default (v1.14.8+);
// per-filter reference and examples: CONFIGURATION.md → messageFilters
"messageFilters": {
"enabled": true,
"filters": {
"omo-system-reminder": { "enabled": true },
"omo-context": { "enabled": true },
"omo-task-directive": { "enabled": true },
"omo-todo-continuation": { "enabled": true },
"omo-mode-injection": { "enabled": true },
},
},
}
```

Expand Down
14 changes: 14 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,20 @@ ACP 使用自己的配置文件,按以下顺序搜索:
},
},
},
// 消息过滤器——在 ACP 处理之前,从可见上下文中剥离/去重第三方插件注入
// (例如 oh-my-opencode 的 system reminder)。被过滤的内容不计入上下文使用量。
// 5 个内置 OMO 过滤器默认开启(v1.14.8+);
// 按过滤器的参考与示例见 CONFIGURATION.zh-CN.md → messageFilters
"messageFilters": {
"enabled": true,
"filters": {
"omo-system-reminder": { "enabled": true },
"omo-context": { "enabled": true },
"omo-task-directive": { "enabled": true },
"omo-todo-continuation": { "enabled": true },
"omo-mode-injection": { "enabled": true },
},
},
}
```

Expand Down
51 changes: 51 additions & 0 deletions devlog/2026-09-09_message-filters-docs/REQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# REQ - Document messageFilters config (EN + ZH)

- Task ID: `2026-09-09_message-filters-docs`
- Home Repo: `opencode-acp`
- Created: 2026-09-09
- Status: InProgress
- Priority: P2
- Owner: ranxianglei
- References: https://github.com/ranxianglei/opencode-acp/issues/369

## 1. Background & Problem Statement

- **Context**: ACP ships 5 built-in oh-my-opencode (OMO) message filters since v1.14.8 (PRs #239, #242, #268, #271), all enabled by default. Issue #369 asked how to safely remove OMO's redundant injected prompts — the answer is "already on by default, configurable via `messageFilters`".
- **Current behavior (symptom)**: The `messageFilters` config surface (master switch, per-filter `enabled`, per-filter `keepLast`) is completely undocumented — not in README.md, README.zh-CN.md, CONFIGURATION.md, or CONFIGURATION.zh-CN.md. A default-on feature is undiscoverable.
- **Expected behavior**: Users can find the `messageFilters` reference and copy-paste examples in both English and Chinese docs.
- **Impact**: Users of ACP + oh-my-opencode cannot discover/tune/disable the filters; support burden on issue tracker.

## 2. Reproduction (if applicable)

Not applicable — documentation gap, verified by grep: `messageFilters` appears in 0 of the 4 doc files.

## 3. Constraints & Non-Goals

- **Constraints**:
- Backward compatibility: docs-only change, no code changes.
- EN and ZH docs must stay in sync (same sections, same examples).
- All documented defaults/behaviors must match the source (`lib/config.ts` defaults, `lib/messages/filter/builtin/*`).
- **Non-Goals** (explicitly out of scope):
- No code changes, no new filters, no schema changes.
- Not fixing the pre-existing `layer1MinRetentionPct` doc inconsistency (README says 1.0, CONFIGURATION.md table says 5.0) — out of scope, noted separately.

## 4. Acceptance Criteria (must be testable)

- **Correctness**:
- [ ] `CONFIGURATION.md` has a `### messageFilters` section with `messageFilters.enabled`, `messageFilters.filters` reference + per-filter table + example
- [ ] `CONFIGURATION.zh-CN.md` has the same section translated
- [ ] `README.md` default-config block includes `messageFilters`
- [ ] `README.zh-CN.md` default-config block includes `messageFilters`
- [ ] At least one "Common Config Recipes" example (EN + ZH) showing tuning/disabling
- [ ] Documented defaults match source (enabled: true, 5 builtin filters, keepLast 2 for omo-system-reminder, 1 for the rest)
- **Performance / Stability**: N/A (docs only)
- **Regression**:
- [ ] `npm run typecheck`, `npm run build`, `npm run test` still pass (no code touched, sanity check)

## 5. Proposed Approach (optional)

- **Affected modules & entry files**:
- `CONFIGURATION.md`, `CONFIGURATION.zh-CN.md` — new `### messageFilters` section after `qualityGate` + recipe in "Common Config Recipes"
- `README.md`, `README.zh-CN.md` — `messageFilters` entry in the Default Configuration block
- **Risks**: None (docs only). Risk of documenting wrong defaults — mitigated by verifying against source before writing.
- **Rollback strategy**: Revert the single commit.
77 changes: 77 additions & 0 deletions devlog/2026-09-09_message-filters-docs/WORKLOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# WORKLOG - Document messageFilters config (EN + ZH)

- Task ID: `2026-09-09_message-filters-docs`
- Home Repo: `opencode-acp`
- Status: Done
- Updated: 2026-09-09 21:05

## 1. Summary

- **What was done** (1–3 sentences): Added the missing `messageFilters` documentation — a full parameter reference section with per-filter table and config examples in CONFIGURATION.md / CONFIGURATION.zh-CN.md, plus a `messageFilters` entry in the default-config blocks of README.md / README.zh-CN.md.
- **Why** (1–3 sentences): Issue #369 showed the default-on OMO message filters are undiscoverable; the owner asked for config examples in both EN and ZH.
- **Behavior / compatibility changes**: No (docs only).
- **Risk level**: Low

## 2. Change Log

### Commits

| Commit | Description |
|--------|-------------|
| `<sha>` | docs: add messageFilters config reference + examples (EN/ZH) |

### Key Files

- `CONFIGURATION.md` — new `### messageFilters` section (enabled, filters, builtin filter table, example) + recipe in Common Config Recipes
- `CONFIGURATION.zh-CN.md` — same, translated
- `README.md` — `messageFilters` entry in Default Configuration block
- `README.zh-CN.md` — same, translated

### Merge conflict resolution (2026-09-09, after v1.16.0 landed on master)

- `origin/master` (v1.15.0 + v1.16.0 storagePath) merged into the branch. Only conflict: both branches appended a new recipe to "Common Config Recipes" right after "Protect sensitive files" in CONFIGURATION.md / CONFIGURATION.zh-CN.md — this PR added the OMO messageFilters recipe, master added the `storagePath` recipe.
- Resolution: keep **both** recipes (OMO filters first, then "Relocate session state storage" / "自定义会话状态存储位置"). No content dropped.
- Re-verified after merge: `npm run typecheck` ✅, `npm run build` ✅, full test suite 1131/1131 pass ✅, `scripts/ci/check-pr.sh` all checks pass ✅.

## 3. Design & Implementation Notes

- **Entry point / key function**: N/A (docs only)
- **Key configuration items**: `messageFilters.enabled` (default `true`), `messageFilters.filters.<name>.enabled`, `messageFilters.filters.<name>.keepLast`
- **Key logic explanation** (if non-trivial): Filters run before `assignMessageRefs` (lib/hooks.ts:237) — filtered content never gets message refs and is never counted toward context usage. `keepLast` is read at lib/messages/filter/apply.ts:115-116 as `Math.max(1, configValue ?? filterDefault ?? 1)`.

## 4. Testing & Verification

### Build & Test Commands

```sh
npm run typecheck
npm run build
node --import tsx --test tests/*.test.ts
```

### Test Coverage

- New/modified test files: none (docs only)
- Test count: 1112 total, 1112 pass, 0 fail (at PR creation); 1131 total, 1131 pass, 0 fail after merging master (v1.15.0/v1.16.0 added storage-path tests)
- Key scenarios verified: documented defaults cross-checked against `lib/config.ts:285-294` and `lib/messages/filter/builtin/*.ts`

### Results

- **PASS/FAIL**: PASS (typecheck, build, full test suite)
- **Key logs/data** (optional): `# pass 1112 / # fail 0`; tsup build success

## 5. Risk Assessment & Rollback

- **Risk points**: documenting wrong defaults (mitigated: verified against source)
- **Rollback method**:
- Revert commit(s): `<sha>`
- Rollback impact: docs revert only
- **Compatibility notes** (data format, config schema): No

## 6. Lessons Learned (optional)

- Default-on features must ship with docs in the same release — #369 shows the discovery gap.

## 7. Follow-ups (optional)

- [ ] Pre-existing inconsistency: `qualityGate.algorithms.rouge-recall-v1.layer1MinRetentionPct` documented as 5.0 in CONFIGURATION.md table but 1.0 in README default block — needs a separate fix.
Loading