-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplugin.js
More file actions
66 lines (60 loc) · 2.31 KB
/
Copy pathplugin.js
File metadata and controls
66 lines (60 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* reasoning-pruner — opencode plugin
* npm: @ghilteras/opencode-reasoning-pruner
*
* Structural hygiene of the context window: strips `reasoning` parts from the
* message history BEFORE it is re-sent to the LLM on the next turn, while
* KEEPING the reasoning parts of the last KEEP_TURNS user turn(s) (default 1).
*
* Reasoning is still shown in the TUI (native /thinking toggle) and consumed
* by the model during generation; this plugin acts ONLY on the history, so
* reasoning tokens do not accumulate in the context window.
*
* Approach: model-agnostic structural filtering, zero regex, zero event-stream
* manipulation, zero system-prompt injection.
*
* History: home-grown since 2026-07-14 (homelab-config), replacing the earlier
* thinking-suppressor.ts (regex + event-hook blanking that truncated DeepSeek
* output). Published to npm 2026-08-07.
*/
// @ts-nocheck
const KEEP_TURNS = 1
const log = (m) => { try { console.log(`[reasoning-pruner] ${m}`) } catch {} }
export default async () => {
log(`plugin caricato (model-agnostic, keepTurns=${KEEP_TURNS})`)
return {
"experimental.chat.messages.transform": async (_input, output) => {
try {
const messages = output?.messages
if (!Array.isArray(messages)) return
let lastUser = -1
let userCount = 0
for (let i = messages.length - 1; i >= 0; i--) {
const role = messages[i]?.info?.role ?? messages[i]?.role
if (role === "user") {
userCount++
if (userCount === KEEP_TURNS) { lastUser = i; break }
}
}
if (lastUser < 0) return
let removed = 0
let kept = 0
for (let i = 0; i < messages.length; i++) {
const m = messages[i]
if (!Array.isArray(m?.parts)) continue
if (i >= lastUser) {
kept += m.parts.filter(p => p?.type === "reasoning").length
continue
}
const before = m.parts.length
m.parts = m.parts.filter(p => p && p.type !== "reasoning")
removed += before - m.parts.length
}
if (removed || kept)
log(`pruned ${removed} historical reasoning parts, kept ${kept} in last ${KEEP_TURNS} user turn(s) (${messages.length} msgs)`)
} catch (err) {
log(`transform err: ${String(err)}`)
}
},
}
}