thatgfsj-code 3.0.4 → 3.0.6
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/README.md +64 -21
- package/dist/app/index.d.ts +93 -22
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +232 -40
- package/dist/app/index.js.map +1 -1
- package/dist/cmd/index.d.ts +12 -20
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +192 -146
- package/dist/cmd/index.js.map +1 -1
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +5 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +5 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/llm/anthropic.d.ts +1 -1
- package/dist/llm/anthropic.d.ts.map +1 -1
- package/dist/llm/anthropic.js +116 -84
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/gemini.d.ts +27 -3
- package/dist/llm/gemini.d.ts.map +1 -1
- package/dist/llm/gemini.js +196 -73
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/index.d.ts +20 -1
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +66 -6
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/openai.d.ts +5 -1
- package/dist/llm/openai.d.ts.map +1 -1
- package/dist/llm/openai.js +96 -56
- package/dist/llm/openai.js.map +1 -1
- package/dist/mcp/client.d.ts +84 -34
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +291 -126
- package/dist/mcp/client.js.map +1 -1
- package/dist/session/compactor.d.ts +27 -7
- package/dist/session/compactor.d.ts.map +1 -1
- package/dist/session/compactor.js +78 -23
- package/dist/session/compactor.js.map +1 -1
- package/dist/session/index.d.ts +96 -33
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +278 -60
- package/dist/session/index.js.map +1 -1
- package/dist/tools/file.d.ts +10 -2
- package/dist/tools/file.d.ts.map +1 -1
- package/dist/tools/file.js +54 -5
- package/dist/tools/file.js.map +1 -1
- package/dist/tools/git.d.ts +16 -2
- package/dist/tools/git.d.ts.map +1 -1
- package/dist/tools/git.js +61 -18
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/nwt.d.ts.map +1 -1
- package/dist/tools/nwt.js +8 -1
- package/dist/tools/nwt.js.map +1 -1
- package/dist/tools/search.d.ts +8 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +105 -34
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/shell.d.ts +0 -4
- package/dist/tools/shell.d.ts.map +1 -1
- package/dist/tools/shell.js +11 -26
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/types.d.ts +7 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tui/app.d.ts.map +1 -1
- package/dist/tui/app.js +90 -18
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components/ChatMessage.d.ts.map +1 -1
- package/dist/tui/components/ChatMessage.js +9 -2
- package/dist/tui/components/ChatMessage.js.map +1 -1
- package/dist/tui/components/ConfirmPrompt.d.ts +21 -0
- package/dist/tui/components/ConfirmPrompt.d.ts.map +1 -0
- package/dist/tui/components/ConfirmPrompt.js +45 -0
- package/dist/tui/components/ConfirmPrompt.js.map +1 -0
- package/dist/tui/components/Header.d.ts +10 -5
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +13 -5
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/StatusBar.d.ts +7 -0
- package/dist/tui/components/StatusBar.d.ts.map +1 -1
- package/dist/tui/components/StatusBar.js +8 -3
- package/dist/tui/components/StatusBar.js.map +1 -1
- package/dist/tui/components/Thinking.d.ts +5 -0
- package/dist/tui/components/Thinking.d.ts.map +1 -1
- package/dist/tui/components/Thinking.js +24 -2
- package/dist/tui/components/Thinking.js.map +1 -1
- package/dist/tui/components/ToolCall.d.ts +6 -1
- package/dist/tui/components/ToolCall.d.ts.map +1 -1
- package/dist/tui/components/ToolCall.js +50 -22
- package/dist/tui/components/ToolCall.js.map +1 -1
- package/dist/tui/components/UserInput.d.ts +5 -0
- package/dist/tui/components/UserInput.d.ts.map +1 -1
- package/dist/tui/components/UserInput.js +9 -13
- package/dist/tui/components/UserInput.js.map +1 -1
- package/dist/tui/hooks/useChat.d.ts +1 -0
- package/dist/tui/hooks/useChat.d.ts.map +1 -1
- package/dist/tui/hooks/useChat.js +36 -16
- package/dist/tui/hooks/useChat.js.map +1 -1
- package/dist/tui/hooks/useCommands.d.ts +7 -1
- package/dist/tui/hooks/useCommands.d.ts.map +1 -1
- package/dist/tui/hooks/useCommands.js +77 -41
- package/dist/tui/hooks/useCommands.js.map +1 -1
- package/dist/tui/theme.d.ts +34 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +34 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/welcome.d.ts.map +1 -1
- package/dist/tui/welcome.js +9 -7
- package/dist/tui/welcome.js.map +1 -1
- package/dist/types.d.ts +16 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/diff.d.ts +5 -0
- package/dist/utils/diff.d.ts.map +1 -1
- package/dist/utils/diff.js +15 -0
- package/dist/utils/diff.js.map +1 -1
- package/dist/version.d.ts +12 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +29 -0
- package/dist/version.js.map +1 -0
- package/package.json +19 -7
- package/CHANGELOG.md +0 -192
- package/DEVELOPMENT.md +0 -286
- package/ROADMAP.md +0 -91
- package/docs/API_KEY_GUIDE.md +0 -236
- package/docs/FAQ.md +0 -182
- package/install.bat +0 -63
- package/install.ps1 +0 -238
- package/install.sh +0 -113
- package/src/app/index.ts +0 -197
- package/src/cache/fingerprint.ts +0 -101
- package/src/cache/index.ts +0 -21
- package/src/cache/smartModel.ts +0 -133
- package/src/cache/stats.ts +0 -199
- package/src/cache/volatile.ts +0 -47
- package/src/cmd/index.tsx +0 -288
- package/src/config/index.ts +0 -156
- package/src/config/providers.ts +0 -234
- package/src/config/types.ts +0 -71
- package/src/hooks/index.ts +0 -111
- package/src/llm/anthropic.ts +0 -413
- package/src/llm/gemini.ts +0 -169
- package/src/llm/index.ts +0 -303
- package/src/llm/openai.ts +0 -243
- package/src/llm/provider.ts +0 -71
- package/src/mcp/client.ts +0 -330
- package/src/prompts/index.ts +0 -260
- package/src/session/compactor.ts +0 -103
- package/src/session/index.ts +0 -181
- package/src/session/message.ts +0 -42
- package/src/skills/brainstorming.ts +0 -43
- package/src/skills/code-review.ts +0 -45
- package/src/skills/executing-plans.ts +0 -27
- package/src/skills/frontend-design.ts +0 -35
- package/src/skills/git-workflow.ts +0 -36
- package/src/skills/improve-architecture.ts +0 -38
- package/src/skills/index.ts +0 -136
- package/src/skills/neuroweave.ts +0 -47
- package/src/skills/playwright.ts +0 -72
- package/src/skills/prototype.ts +0 -30
- package/src/skills/subagent.ts +0 -28
- package/src/skills/supabase.ts +0 -44
- package/src/skills/systematic-debugging.ts +0 -44
- package/src/skills/tdd.ts +0 -39
- package/src/skills/triage.ts +0 -35
- package/src/skills/verification.ts +0 -31
- package/src/skills/writing-plans.ts +0 -42
- package/src/tools/file.ts +0 -143
- package/src/tools/git.ts +0 -132
- package/src/tools/index.ts +0 -111
- package/src/tools/nwt.ts +0 -598
- package/src/tools/search.ts +0 -263
- package/src/tools/shell.ts +0 -136
- package/src/tools/types.ts +0 -122
- package/src/tui/app.tsx +0 -159
- package/src/tui/components/ChatList.tsx +0 -41
- package/src/tui/components/ChatMessage.tsx +0 -54
- package/src/tui/components/Header.tsx +0 -66
- package/src/tui/components/InitWizard.tsx +0 -247
- package/src/tui/components/Markdown.tsx +0 -35
- package/src/tui/components/ModelSelector.tsx +0 -107
- package/src/tui/components/StatusBar.tsx +0 -30
- package/src/tui/components/Thinking.tsx +0 -17
- package/src/tui/components/ToolCall.tsx +0 -102
- package/src/tui/components/UserInput.tsx +0 -151
- package/src/tui/hooks/useChat.ts +0 -287
- package/src/tui/hooks/useCommands.ts +0 -271
- package/src/tui/index.ts +0 -6
- package/src/tui/welcome.ts +0 -177
- package/src/types.ts +0 -104
- package/src/utils/diff.ts +0 -71
- package/src/utils/project.ts +0 -99
- package/src/utils/stableStringify.ts +0 -47
- package/src/utils/thinking.ts +0 -119
- package/tests/cache/fingerprint.test.ts +0 -75
- package/tests/cache/providerCatalog.test.ts +0 -31
- package/tests/cache/smartModel.test.ts +0 -100
- package/tests/cache/stableStringify.test.ts +0 -43
- package/tests/cache/stats.test.ts +0 -146
- package/tests/cache/volatile.test.ts +0 -75
- package/tests/smoke-pollution.mjs +0 -78
- package/tests/smoke-thinking.mjs +0 -110
- package/tests/smoke-tool-stream.mjs +0 -69
- package/tests/smoke-tool.mjs +0 -117
- package/tsconfig.json +0 -21
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Context Compactor - Progressive compression for conversation history
|
|
3
|
-
* Migrated from old src/core/context-compactor.ts
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* v3.0.5: compression now respects TOOL-CALL ATOMICITY. OpenAI and
|
|
5
|
+
* Anthropic both reject a request where an assistant message carrying
|
|
6
|
+
* tool_calls is not immediately followed by its tool result messages (and
|
|
7
|
+
* vice versa). The previous implementation sliced by raw message count and
|
|
8
|
+
* happily cut right through a call/result pair, producing 400s from that
|
|
9
|
+
* point on. Messages are now grouped first — an assistant message with
|
|
10
|
+
* tool_calls plus all of its following tool messages form one atomic
|
|
11
|
+
* group — and only whole groups are summarized away.
|
|
8
12
|
*/
|
|
9
13
|
import type { ChatMessage } from '../types.js';
|
|
10
14
|
export interface CompactorConfig {
|
|
11
15
|
/** Max messages before compression kicks in */
|
|
12
16
|
maxMessages?: number;
|
|
13
|
-
/**
|
|
17
|
+
/** Approximate message budget to preserve for recent context */
|
|
14
18
|
preserveRecent?: number;
|
|
15
19
|
}
|
|
16
20
|
export interface CompressionResult {
|
|
@@ -18,12 +22,28 @@ export interface CompressionResult {
|
|
|
18
22
|
compactedCount: number;
|
|
19
23
|
removedCount: number;
|
|
20
24
|
}
|
|
25
|
+
/** A group of messages that must be kept together (or dropped together). */
|
|
26
|
+
export interface MessageGroup {
|
|
27
|
+
messages: ChatMessage[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Split non-system messages into atomic groups.
|
|
31
|
+
*
|
|
32
|
+
* Rules:
|
|
33
|
+
* - a `tool` message always joins the group before it (its assistant
|
|
34
|
+
* tool_calls carrier)
|
|
35
|
+
* - an assistant message with tool_calls starts a new group (its results
|
|
36
|
+
* will follow inside the same group)
|
|
37
|
+
* - a user or plain assistant message starts a new group
|
|
38
|
+
*/
|
|
39
|
+
export declare function splitIntoGroups(messages: ChatMessage[]): MessageGroup[];
|
|
21
40
|
export declare class ContextCompactor {
|
|
22
41
|
private maxMessages;
|
|
23
42
|
private preserveRecent;
|
|
24
43
|
constructor(config?: CompactorConfig);
|
|
25
44
|
/**
|
|
26
|
-
* Compact messages if needed
|
|
45
|
+
* Compact messages if needed. Returns the input unchanged when under the
|
|
46
|
+
* limit or when nothing can be removed.
|
|
27
47
|
*/
|
|
28
48
|
compact(messages: ChatMessage[]): {
|
|
29
49
|
compacted: ChatMessage[];
|
|
@@ -41,7 +61,7 @@ export declare class ContextCompactor {
|
|
|
41
61
|
*/
|
|
42
62
|
estimateTokens(messages: ChatMessage[]): number;
|
|
43
63
|
/**
|
|
44
|
-
* Extract topic
|
|
64
|
+
* Extract a short topic list from the middle groups (their user prompts).
|
|
45
65
|
*/
|
|
46
66
|
private extractTopics;
|
|
47
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactor.d.ts","sourceRoot":"","sources":["../../src/session/compactor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"compactor.d.ts","sourceRoot":"","sources":["../../src/session/compactor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,YAAY,EAAE,CAkBvE;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAS;gBAEnB,MAAM,GAAE,eAAoB;IAKxC;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;QAAE,SAAS,EAAE,WAAW,EAAE,CAAC;QAAC,MAAM,EAAE,iBAAiB,CAAA;KAAE;IAyDzF;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;QAAE,SAAS,EAAE,WAAW,EAAE,CAAC;QAAC,MAAM,EAAE,iBAAiB,CAAA;KAAE;IAI7F;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM;IAM/C;;OAEG;IACH,OAAO,CAAC,aAAa;CAYtB"}
|
|
@@ -1,11 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Context Compactor - Progressive compression for conversation history
|
|
3
|
-
* Migrated from old src/core/context-compactor.ts
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* v3.0.5: compression now respects TOOL-CALL ATOMICITY. OpenAI and
|
|
5
|
+
* Anthropic both reject a request where an assistant message carrying
|
|
6
|
+
* tool_calls is not immediately followed by its tool result messages (and
|
|
7
|
+
* vice versa). The previous implementation sliced by raw message count and
|
|
8
|
+
* happily cut right through a call/result pair, producing 400s from that
|
|
9
|
+
* point on. Messages are now grouped first — an assistant message with
|
|
10
|
+
* tool_calls plus all of its following tool messages form one atomic
|
|
11
|
+
* group — and only whole groups are summarized away.
|
|
8
12
|
*/
|
|
13
|
+
/**
|
|
14
|
+
* Split non-system messages into atomic groups.
|
|
15
|
+
*
|
|
16
|
+
* Rules:
|
|
17
|
+
* - a `tool` message always joins the group before it (its assistant
|
|
18
|
+
* tool_calls carrier)
|
|
19
|
+
* - an assistant message with tool_calls starts a new group (its results
|
|
20
|
+
* will follow inside the same group)
|
|
21
|
+
* - a user or plain assistant message starts a new group
|
|
22
|
+
*/
|
|
23
|
+
export function splitIntoGroups(messages) {
|
|
24
|
+
const groups = [];
|
|
25
|
+
for (const m of messages) {
|
|
26
|
+
if (m.role === 'tool') {
|
|
27
|
+
if (groups.length > 0) {
|
|
28
|
+
groups[groups.length - 1].messages.push(m);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Orphaned tool result (malformed history) — keep it isolated so we
|
|
32
|
+
// don't attach it to an unrelated pair.
|
|
33
|
+
groups.push({ messages: [m] });
|
|
34
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
groups.push({ messages: [m] });
|
|
38
|
+
}
|
|
39
|
+
return groups;
|
|
40
|
+
}
|
|
9
41
|
export class ContextCompactor {
|
|
10
42
|
maxMessages;
|
|
11
43
|
preserveRecent;
|
|
@@ -14,7 +46,8 @@ export class ContextCompactor {
|
|
|
14
46
|
this.preserveRecent = config.preserveRecent ?? 10;
|
|
15
47
|
}
|
|
16
48
|
/**
|
|
17
|
-
* Compact messages if needed
|
|
49
|
+
* Compact messages if needed. Returns the input unchanged when under the
|
|
50
|
+
* limit or when nothing can be removed.
|
|
18
51
|
*/
|
|
19
52
|
compact(messages) {
|
|
20
53
|
if (messages.length <= this.maxMessages) {
|
|
@@ -23,25 +56,40 @@ export class ContextCompactor {
|
|
|
23
56
|
result: { originalCount: messages.length, compactedCount: messages.length, removedCount: 0 },
|
|
24
57
|
};
|
|
25
58
|
}
|
|
26
|
-
const
|
|
59
|
+
const systemMsgs = messages.filter(m => m.role === 'system');
|
|
27
60
|
const others = messages.filter(m => m.role !== 'system');
|
|
28
|
-
|
|
61
|
+
const groups = splitIntoGroups(others);
|
|
62
|
+
if (groups.length <= 1) {
|
|
63
|
+
// Nothing compressible — a single group must stay atomic.
|
|
64
|
+
return {
|
|
65
|
+
compacted: messages,
|
|
66
|
+
result: { originalCount: messages.length, compactedCount: messages.length, removedCount: 0 },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Pick trailing groups whose combined size fits the recent budget
|
|
70
|
+
// (always keep at least one group).
|
|
71
|
+
const recent = [];
|
|
72
|
+
let recentSize = 0;
|
|
73
|
+
for (let i = groups.length - 1; i >= 0; i--) {
|
|
74
|
+
const size = groups[i].messages.length;
|
|
75
|
+
if (recentSize + size > this.preserveRecent && recent.length > 0)
|
|
76
|
+
break;
|
|
77
|
+
recent.unshift(groups[i]);
|
|
78
|
+
recentSize += size;
|
|
79
|
+
}
|
|
80
|
+
const middle = groups.slice(0, groups.length - recent.length);
|
|
81
|
+
if (middle.length === 0) {
|
|
29
82
|
return {
|
|
30
83
|
compacted: messages,
|
|
31
84
|
result: { originalCount: messages.length, compactedCount: messages.length, removedCount: 0 },
|
|
32
85
|
};
|
|
33
86
|
}
|
|
34
|
-
// Keep recent N turns
|
|
35
|
-
const recent = others.slice(-this.preserveRecent);
|
|
36
|
-
// Summarize the middle portion
|
|
37
|
-
const middle = others.slice(0, -this.preserveRecent);
|
|
38
87
|
const summary = {
|
|
39
88
|
role: 'system',
|
|
40
|
-
content: `[Earlier conversation summary: ${middle.length} messages covering ${this.extractTopics(middle)}]`,
|
|
89
|
+
content: `[Earlier conversation summary: ${middle.reduce((n, g) => n + g.messages.length, 0)} messages covering ${this.extractTopics(middle)}]`,
|
|
41
90
|
};
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
: [summary, ...recent];
|
|
91
|
+
const recentMsgs = recent.flatMap(g => g.messages);
|
|
92
|
+
const compacted = [...systemMsgs, summary, ...recentMsgs];
|
|
45
93
|
return {
|
|
46
94
|
compacted,
|
|
47
95
|
result: {
|
|
@@ -61,17 +109,24 @@ export class ContextCompactor {
|
|
|
61
109
|
* Estimate token count (rough: ~4 chars per token)
|
|
62
110
|
*/
|
|
63
111
|
estimateTokens(messages) {
|
|
64
|
-
|
|
112
|
+
const size = (m) => (typeof m.content === 'string' ? m.content.length : JSON.stringify(m.content).length);
|
|
113
|
+
return messages.reduce((sum, m) => sum + Math.ceil(size(m) / 4) + 10, 0);
|
|
65
114
|
}
|
|
66
115
|
/**
|
|
67
|
-
* Extract topic
|
|
116
|
+
* Extract a short topic list from the middle groups (their user prompts).
|
|
68
117
|
*/
|
|
69
|
-
extractTopics(
|
|
70
|
-
const topics =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
118
|
+
extractTopics(groups) {
|
|
119
|
+
const topics = [];
|
|
120
|
+
for (const g of groups) {
|
|
121
|
+
for (const m of g.messages) {
|
|
122
|
+
if (m.role === 'user' && typeof m.content === 'string') {
|
|
123
|
+
topics.push(m.content.slice(0, 60).replace(/\s+/g, ' '));
|
|
124
|
+
if (topics.length >= 5)
|
|
125
|
+
return topics.join(' | ');
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return topics.join(' | ') || 'various topics';
|
|
75
130
|
}
|
|
76
131
|
}
|
|
77
132
|
//# sourceMappingURL=compactor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactor.js","sourceRoot":"","sources":["../../src/session/compactor.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"compactor.js","sourceRoot":"","sources":["../../src/session/compactor.ts"],"names":[],"mappings":"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"}
|
package/dist/session/index.d.ts
CHANGED
|
@@ -1,63 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Session Manager - Manages conversation history with auto-compaction
|
|
3
|
+
*
|
|
4
|
+
* v3.0.5 additions:
|
|
5
|
+
* - Disk persistence: every completed round can be persisted to
|
|
6
|
+
* ~/.thatgfsj/sessions/<id>.json, and /resume restores a previous
|
|
7
|
+
* session. Files are validated on load (dangling tool_calls are
|
|
8
|
+
* stripped) so a restored history can never produce a provider 400.
|
|
9
|
+
* - reset(): starts a fresh conversation while KEEPING the system prompt
|
|
10
|
+
* (the old clear() dropped it, leaving every later request unprompted).
|
|
11
|
+
* - autoCompact: when history exceeds maxMessages it is compacted once
|
|
12
|
+
* (atomic tool groups, see compactor.ts) instead of being silently
|
|
13
|
+
* truncated every round. The TUI is notified via onAutoCompact.
|
|
3
14
|
*/
|
|
4
15
|
import type { ChatMessage } from '../types.js';
|
|
16
|
+
export interface SessionFile {
|
|
17
|
+
version: 1;
|
|
18
|
+
id: string;
|
|
19
|
+
createdAt: string;
|
|
20
|
+
updatedAt: string;
|
|
21
|
+
provider?: string;
|
|
22
|
+
model?: string;
|
|
23
|
+
messages: ChatMessage[];
|
|
24
|
+
}
|
|
25
|
+
export interface SessionSummary {
|
|
26
|
+
id: string;
|
|
27
|
+
updatedAt: Date;
|
|
28
|
+
messageCount: number;
|
|
29
|
+
/** First user message, trimmed — the human-readable "what was this about". */
|
|
30
|
+
preview: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function sessionsDir(): string;
|
|
33
|
+
/**
|
|
34
|
+
* v3.0.5: shared load-time sanitizer. A restored history must never carry a
|
|
35
|
+
* tool_calls block without its results, or the next provider request 400s:
|
|
36
|
+
* - drop orphaned 'tool' messages (no preceding assistant tool_calls)
|
|
37
|
+
* - strip tool_calls from an assistant message whose results were lost
|
|
38
|
+
*/
|
|
39
|
+
export declare function sanitizeLoadedMessages(messages: ChatMessage[]): ChatMessage[];
|
|
5
40
|
export declare class SessionManager {
|
|
6
41
|
private messages;
|
|
7
42
|
private sessionId;
|
|
8
43
|
private createdAt;
|
|
9
44
|
private compactor;
|
|
10
45
|
private maxMessages;
|
|
11
|
-
/** v2.2.4: counter for messages dropped by the pollution filter. */
|
|
12
46
|
private droppedCount;
|
|
47
|
+
/** Whether history was compacted and the new-context toast not yet surfaced. */
|
|
48
|
+
private lastCompaction;
|
|
49
|
+
/** Extra metadata recorded in the session file. */
|
|
50
|
+
meta?: {
|
|
51
|
+
provider?: string;
|
|
52
|
+
model?: string;
|
|
53
|
+
};
|
|
13
54
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* the TUI to suggest the user call /new (start a fresh session) so that
|
|
17
|
-
* the upstream prompt cache keeps a stable prefix. NWT auto-logs every
|
|
18
|
-
* meaningful event, so no history is lost — it just moves out of the
|
|
19
|
-
* live cache window.
|
|
55
|
+
* Called after history exceeded maxMessages and was compacted once.
|
|
56
|
+
* The TUI surfaces a toast; nobody is required to act.
|
|
20
57
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
58
|
+
onAutoCompact?: (info: {
|
|
59
|
+
before: number;
|
|
60
|
+
after: number;
|
|
24
61
|
}) => void;
|
|
25
62
|
constructor(maxMessages?: number, options?: {
|
|
26
|
-
|
|
63
|
+
onAutoCompact?: SessionManager['onAutoCompact'];
|
|
27
64
|
});
|
|
28
65
|
addMessage(role: ChatMessage['role'], content: string, extras?: Partial<ChatMessage>): void;
|
|
29
66
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* truncation/abort pollution pattern. Use this for assistant
|
|
33
|
-
* messages whose stream might have been aborted.
|
|
67
|
+
* Same as addMessage but returns false (and skips the push) if the message
|
|
68
|
+
* content matches a known truncation/abort pollution pattern.
|
|
34
69
|
*/
|
|
35
70
|
addMessageSafe(role: ChatMessage['role'], content: string, extras?: Partial<ChatMessage>): boolean;
|
|
36
|
-
/**
|
|
71
|
+
/** Total messages dropped by addMessageSafe since session start. */
|
|
37
72
|
getDroppedCount(): number;
|
|
38
73
|
getMessages(): ChatMessage[];
|
|
39
74
|
getMessageCount(): number;
|
|
75
|
+
/**
|
|
76
|
+
* v3.0.5: fresh conversation that KEEPS the system prompt. The previous
|
|
77
|
+
* clear() removed it, so every later request ran without the identity /
|
|
78
|
+
* tool / skills instructions until the process restarted.
|
|
79
|
+
*/
|
|
80
|
+
reset(): void;
|
|
81
|
+
/**
|
|
82
|
+
* v3.0.5: replace in-memory history (used by /resume). Input is sanitized
|
|
83
|
+
* so a malformed file can not poison the next request.
|
|
84
|
+
*/
|
|
85
|
+
restore(messages: ChatMessage[], meta?: {
|
|
86
|
+
id?: string;
|
|
87
|
+
createdAt?: string;
|
|
88
|
+
provider?: string;
|
|
89
|
+
model?: string;
|
|
90
|
+
}): void;
|
|
40
91
|
clear(): void;
|
|
41
92
|
/**
|
|
42
|
-
* v3.0.
|
|
43
|
-
* the
|
|
44
|
-
*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* every meaningful event, so the user does not lose context — it just
|
|
53
|
-
* moves out of the live cache window. If the user wants a longer
|
|
54
|
-
* session, they can bump maxMessages in `~/.thatgfsj/config.json`.
|
|
55
|
-
*
|
|
56
|
-
* The original "fake compact" logic (insert `[Earlier conversation...]`
|
|
57
|
-
* summary) is preserved as `truncate()` for callers that explicitly
|
|
58
|
-
* want to compact (e.g. /new command hard-reset).
|
|
93
|
+
* v3.0.5: replace the (first) system prompt in place — used when tools or
|
|
94
|
+
* the permission mode change and the prompt must be rebuilt without
|
|
95
|
+
* resetting the conversation.
|
|
96
|
+
*/
|
|
97
|
+
replaceSystemMessage(content: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* Compact when over the limit — once per crossing, atomic groups (v3.0.5).
|
|
100
|
+
* The previous design only suggested /new and never touched history, which
|
|
101
|
+
* let sessions grow unbounded (and the /compact path silently rewrote
|
|
102
|
+
* history every round). Now: compact at the threshold, notify once.
|
|
59
103
|
*/
|
|
60
104
|
private autoCompact;
|
|
105
|
+
/** v3.0.5: explicit compaction (the /compact command). */
|
|
106
|
+
compactNow(): {
|
|
107
|
+
before: number;
|
|
108
|
+
after: number;
|
|
109
|
+
} | null;
|
|
61
110
|
truncate(maxMessages?: number): void;
|
|
62
111
|
getId(): string;
|
|
63
112
|
getInfo(): {
|
|
@@ -65,6 +114,20 @@ export declare class SessionManager {
|
|
|
65
114
|
messageCount: number;
|
|
66
115
|
createdAt: Date;
|
|
67
116
|
};
|
|
117
|
+
/**
|
|
118
|
+
* Write the current history to ~/.thatgfsj/sessions/<id>.json and prune
|
|
119
|
+
* old sessions. Fire-and-forget friendly: errors are swallowed by the
|
|
120
|
+
* caller — a full disk must never kill a chat round.
|
|
121
|
+
*/
|
|
122
|
+
persist(): void;
|
|
123
|
+
/**
|
|
124
|
+
* Restore a previously persisted session into THIS manager (in place).
|
|
125
|
+
*/
|
|
126
|
+
loadFrom(file: SessionFile): void;
|
|
127
|
+
/** List the most recent persisted sessions, newest first. */
|
|
128
|
+
static list(limit?: number): SessionSummary[];
|
|
129
|
+
/** Load a persisted session file by id (or filename). */
|
|
130
|
+
static load(id: string): SessionFile | null;
|
|
68
131
|
}
|
|
69
132
|
export { ContextCompactor } from './compactor.js';
|
|
70
133
|
export type { CompactorConfig, CompressionResult } from './compactor.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"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"}
|