@nghyane/arcane 0.1.29 → 0.1.30
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/package.json +4 -4
- package/src/cli/config-cli.ts +1 -1
- package/src/config/settings-schema.ts +19 -27
- package/src/config/settings.ts +3 -4
- package/src/extensibility/custom-tools/types.ts +0 -12
- package/src/extensibility/extensions/index.ts +0 -5
- package/src/extensibility/extensions/runner.ts +6 -26
- package/src/extensibility/extensions/types.ts +1 -77
- package/src/extensibility/hooks/runner.ts +5 -24
- package/src/extensibility/hooks/types.ts +1 -77
- package/src/index.ts +2 -13
- package/src/modes/components/footer.ts +4 -11
- package/src/modes/components/index.ts +0 -1
- package/src/modes/components/status-line/segments.ts +1 -2
- package/src/modes/components/status-line/types.ts +0 -1
- package/src/modes/components/status-line.ts +0 -6
- package/src/modes/components/tree-selector.ts +0 -8
- package/src/modes/controllers/command-controller.ts +2 -98
- package/src/modes/controllers/event-controller.ts +46 -52
- package/src/modes/controllers/extension-ui-controller.ts +0 -42
- package/src/modes/controllers/input-controller.ts +0 -23
- package/src/modes/controllers/selector-controller.ts +0 -5
- package/src/modes/interactive-mode.ts +3 -24
- package/src/modes/print-mode.ts +0 -16
- package/src/modes/rpc/rpc-client.ts +0 -16
- package/src/modes/rpc/rpc-mode.ts +0 -32
- package/src/modes/rpc/rpc-types.ts +0 -9
- package/src/modes/types.ts +1 -13
- package/src/modes/utils/ui-helpers.ts +2 -118
- package/src/sdk.ts +0 -15
- package/src/session/agent-session.ts +89 -650
- package/src/session/compaction/branch-summarization.ts +5 -13
- package/src/session/compaction/index.ts +0 -1
- package/src/session/compaction/utils.ts +94 -2
- package/src/session/messages.ts +0 -37
- package/src/session/retry-utils.ts +1 -1
- package/src/session/session-manager.ts +8 -108
- package/src/session/session-types.ts +4 -25
- package/src/session/stats.ts +2 -39
- package/src/slash-commands/builtin-registry.ts +0 -11
- package/src/task/executor.ts +0 -8
- package/examples/hooks/custom-compaction.ts +0 -116
- package/src/modes/components/compaction-summary-message.ts +0 -59
- package/src/prompts/compaction/compaction-short-summary.md +0 -9
- package/src/prompts/compaction/compaction-summary-context.md +0 -5
- package/src/prompts/compaction/compaction-summary.md +0 -41
- package/src/prompts/compaction/compaction-turn-prefix.md +0 -17
- package/src/prompts/compaction/compaction-update-summary.md +0 -45
- package/src/session/compaction/compaction.ts +0 -864
- package/src/session/compaction/pruning.ts +0 -91
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom Compaction Hook
|
|
3
|
-
*
|
|
4
|
-
* Replaces the default compaction behavior with a full summary of the entire context.
|
|
5
|
-
* Instead of keeping the last 20k tokens of conversation turns, this hook:
|
|
6
|
-
* 1. Summarizes ALL messages (messagesToSummarize + turnPrefixMessages)
|
|
7
|
-
* 2. Discards all old turns completely, keeping only the summary
|
|
8
|
-
*
|
|
9
|
-
* This example also demonstrates using a different model (Gemini Flash) for summarization,
|
|
10
|
-
* which can be cheaper/faster than the main conversation model.
|
|
11
|
-
*
|
|
12
|
-
* Usage:
|
|
13
|
-
* arcane --hook examples/hooks/custom-compaction.ts
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import type { HookAPI } from "@nghyane/arcane";
|
|
17
|
-
import { convertToLlm, serializeConversation } from "@nghyane/arcane";
|
|
18
|
-
import { complete, getModel } from "@nghyane/arcane-ai";
|
|
19
|
-
|
|
20
|
-
export default function (pi: HookAPI) {
|
|
21
|
-
pi.on("session_before_compact", async (event, ctx) => {
|
|
22
|
-
ctx.ui.notify("Custom compaction hook triggered", "info");
|
|
23
|
-
|
|
24
|
-
const { preparation, branchEntries: _, signal } = event;
|
|
25
|
-
const { messagesToSummarize, turnPrefixMessages, tokensBefore, firstKeptEntryId, previousSummary } = preparation;
|
|
26
|
-
|
|
27
|
-
// Use Gemini Flash for summarization (cheaper/faster than most conversation models)
|
|
28
|
-
const model = getModel("google", "gemini-2.5-flash");
|
|
29
|
-
if (!model) {
|
|
30
|
-
ctx.ui.notify(`Could not find Gemini Flash model, using default compaction`, "warning");
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Resolve API key for the summarization model
|
|
35
|
-
const apiKey = await ctx.modelRegistry.getApiKey(model);
|
|
36
|
-
if (!apiKey) {
|
|
37
|
-
ctx.ui.notify(`No API key for ${model.provider}, using default compaction`, "warning");
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Combine all messages for full summary
|
|
42
|
-
const allMessages = [...messagesToSummarize, ...turnPrefixMessages];
|
|
43
|
-
|
|
44
|
-
ctx.ui.notify(
|
|
45
|
-
`Custom compaction: summarizing ${allMessages.length} messages (${tokensBefore.toLocaleString()} tokens) with ${
|
|
46
|
-
model.id
|
|
47
|
-
}...`,
|
|
48
|
-
"info",
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// Convert messages to readable text format
|
|
52
|
-
const conversationText = serializeConversation(convertToLlm(allMessages));
|
|
53
|
-
|
|
54
|
-
// Include previous summary context if available
|
|
55
|
-
const previousContext = previousSummary ? `\n\nPrevious session summary for context:\n${previousSummary}` : "";
|
|
56
|
-
|
|
57
|
-
// Build messages that ask for a comprehensive summary
|
|
58
|
-
const summaryMessages = [
|
|
59
|
-
{
|
|
60
|
-
role: "user" as const,
|
|
61
|
-
content: [
|
|
62
|
-
{
|
|
63
|
-
type: "text" as const,
|
|
64
|
-
text: `You are a conversation summarizer. Create a comprehensive summary of this conversation that captures:${previousContext}
|
|
65
|
-
|
|
66
|
-
1. The main goals and objectives discussed
|
|
67
|
-
2. Key decisions made and their rationale
|
|
68
|
-
3. Important code changes, file modifications, or technical details
|
|
69
|
-
4. Current state of any ongoing work
|
|
70
|
-
5. Any blockers, issues, or open questions
|
|
71
|
-
6. Next steps that were planned or suggested
|
|
72
|
-
|
|
73
|
-
Be thorough but concise. The summary will replace the ENTIRE conversation history, so include all information needed to continue the work effectively.
|
|
74
|
-
|
|
75
|
-
Format the summary as structured markdown with clear sections.
|
|
76
|
-
|
|
77
|
-
<conversation>
|
|
78
|
-
${conversationText}
|
|
79
|
-
</conversation>`,
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
timestamp: Date.now(),
|
|
83
|
-
},
|
|
84
|
-
];
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
// Pass signal to honor abort requests (e.g., user cancels compaction)
|
|
88
|
-
const response = await complete(model, { messages: summaryMessages }, { apiKey, maxTokens: 8192, signal });
|
|
89
|
-
|
|
90
|
-
const summary = response.content
|
|
91
|
-
.filter((c): c is { type: "text"; text: string } => c.type === "text")
|
|
92
|
-
.map(c => c.text)
|
|
93
|
-
.join("\n");
|
|
94
|
-
|
|
95
|
-
if (!summary.trim()) {
|
|
96
|
-
if (!signal.aborted) ctx.ui.notify("Compaction summary was empty, using default compaction", "warning");
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Return compaction content - SessionManager adds id/parentId
|
|
101
|
-
// Use firstKeptEntryId from preparation to keep recent messages
|
|
102
|
-
return {
|
|
103
|
-
compaction: {
|
|
104
|
-
summary,
|
|
105
|
-
firstKeptEntryId,
|
|
106
|
-
tokensBefore,
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
} catch (error) {
|
|
110
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
111
|
-
ctx.ui.notify(`Compaction failed: ${message}`, "error");
|
|
112
|
-
// Fall back to default compaction on error
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Container, LeftBorderBox, Markdown, Spacer, Text } from "@nghyane/arcane-tui";
|
|
2
|
-
import type { CompactionSummaryMessage } from "../../session/messages";
|
|
3
|
-
import { getMarkdownTheme, theme } from "../../theme/theme";
|
|
4
|
-
import { formatClickHint } from "../../ui/render-utils";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Component that renders a compaction message with collapsed/expanded state.
|
|
8
|
-
*/
|
|
9
|
-
export class CompactionSummaryMessageComponent extends Container {
|
|
10
|
-
#box: LeftBorderBox;
|
|
11
|
-
#expanded = false;
|
|
12
|
-
|
|
13
|
-
constructor(private readonly message: CompactionSummaryMessage) {
|
|
14
|
-
super();
|
|
15
|
-
this.addChild(new Spacer(1));
|
|
16
|
-
this.#box = new LeftBorderBox(1, 1, s => theme.fg("dim", s));
|
|
17
|
-
this.addChild(this.#box);
|
|
18
|
-
this.#updateDisplay();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
setExpanded(expanded: boolean): void {
|
|
22
|
-
this.#expanded = expanded;
|
|
23
|
-
this.#updateDisplay();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
override invalidate(): void {
|
|
27
|
-
super.invalidate();
|
|
28
|
-
this.#updateDisplay();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
#updateDisplay(): void {
|
|
32
|
-
this.#box.clear();
|
|
33
|
-
|
|
34
|
-
const tokenStr = this.message.tokensBefore.toLocaleString();
|
|
35
|
-
const label = theme.fg("customMessageLabel", theme.bold("[compaction]"));
|
|
36
|
-
this.#box.addChild(new Text(label, 0, 0));
|
|
37
|
-
this.#box.addChild(new Spacer(1));
|
|
38
|
-
|
|
39
|
-
if (this.#expanded) {
|
|
40
|
-
const header = `**Compacted from ${tokenStr} tokens**\n\n`;
|
|
41
|
-
this.#box.addChild(
|
|
42
|
-
new Markdown(header + this.message.summary, 0, 0, getMarkdownTheme(), {
|
|
43
|
-
color: (text: string) => theme.fg("customMessageText", text),
|
|
44
|
-
}),
|
|
45
|
-
);
|
|
46
|
-
} else {
|
|
47
|
-
this.#box.addChild(
|
|
48
|
-
new Text(
|
|
49
|
-
`${theme.fg("customMessageText", `Compacted from ${tokenStr} tokens`)} ${formatClickHint(theme)}`,
|
|
50
|
-
0,
|
|
51
|
-
0,
|
|
52
|
-
),
|
|
53
|
-
);
|
|
54
|
-
if (this.message.shortSummary) {
|
|
55
|
-
this.#box.addChild(new Text(theme.fg("customMessageText", this.message.shortSummary), 0, 1));
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
Summarize what was done in this conversation. Write like a pull request description.
|
|
2
|
-
|
|
3
|
-
Rules:
|
|
4
|
-
- 2-3 sentences max
|
|
5
|
-
- Describe the changes made, not the process
|
|
6
|
-
- Do not mention running tests, builds, or other validation steps
|
|
7
|
-
- Do not explain what the user asked for
|
|
8
|
-
- Write in first person (I added..., I fixed...)
|
|
9
|
-
- Never ask questions
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
Another language model started to solve this problem and produced a summary of its thinking process. You also have access to the state of the tools that were used by that language model. Use this to build on the work that has already been done and avoid duplicating work. Here is the summary produced by the other language model, use the information in this summary to assist with your own analysis:
|
|
2
|
-
|
|
3
|
-
<summary>
|
|
4
|
-
{{summary}}
|
|
5
|
-
</summary>
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
Summarize conversation above into structured context checkpoint handoff summary for another LLM to resume task.
|
|
2
|
-
|
|
3
|
-
IMPORTANT: If conversation ends with unanswered question to user or imperative/request awaiting user response (e.g., "Please run command and paste output"), preserve that exact question/request.
|
|
4
|
-
|
|
5
|
-
Use this format (sections can be omitted if not applicable):
|
|
6
|
-
|
|
7
|
-
## Goal
|
|
8
|
-
[User goals; list multiple if session covers different tasks.]
|
|
9
|
-
|
|
10
|
-
## Constraints & Preferences
|
|
11
|
-
- [Constraints or requirements mentioned]
|
|
12
|
-
|
|
13
|
-
## Progress
|
|
14
|
-
|
|
15
|
-
### Done
|
|
16
|
-
- [x] [Completed tasks/changes]
|
|
17
|
-
|
|
18
|
-
### In Progress
|
|
19
|
-
- [ ] [Current work]
|
|
20
|
-
|
|
21
|
-
### Blocked
|
|
22
|
-
- [Issues preventing progress]
|
|
23
|
-
|
|
24
|
-
### Abandoned Approaches
|
|
25
|
-
- [Approach tried and why it failed/was rejected — prevents re-trying dead ends]
|
|
26
|
-
|
|
27
|
-
## Key Decisions
|
|
28
|
-
- **[Decision]**: [Brief rationale]
|
|
29
|
-
|
|
30
|
-
## Next Steps
|
|
31
|
-
1. [Ordered list of next actions]
|
|
32
|
-
|
|
33
|
-
## Critical Context
|
|
34
|
-
- [Important data, pending questions, references]
|
|
35
|
-
|
|
36
|
-
## Additional Notes
|
|
37
|
-
[Anything else important not covered above]
|
|
38
|
-
|
|
39
|
-
Output only structured summary; no extra text.
|
|
40
|
-
|
|
41
|
-
Prioritize recent context over older context — the last 2-3 turns are most likely to contain the active work state. Preserve exact file paths, function names, error messages, and relevant tool outputs. Include repository state changes (branch, uncommitted changes) if mentioned.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.
|
|
2
|
-
|
|
3
|
-
Summarize the prefix to provide context for the retained suffix:
|
|
4
|
-
|
|
5
|
-
## Original Request
|
|
6
|
-
|
|
7
|
-
[What did the user ask for in this turn?]
|
|
8
|
-
|
|
9
|
-
## Early Progress
|
|
10
|
-
- [Key decisions and work done in the prefix]
|
|
11
|
-
|
|
12
|
-
## Context for Suffix
|
|
13
|
-
- [Information needed to understand the retained recent work]
|
|
14
|
-
|
|
15
|
-
Output only the structured summary. No extra text.
|
|
16
|
-
|
|
17
|
-
Be concise. Preserve exact file paths, function names, error messages, and relevant tool outputs or command results if they appear. Focus on what's needed to understand the kept suffix.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
Incorporate new messages above into existing handoff summary in <previous-summary> tags, used by another LLM to resume task.
|
|
2
|
-
RULES:
|
|
3
|
-
- PRESERVE all information from previous summary
|
|
4
|
-
- ADD new progress, decisions, and context from new messages
|
|
5
|
-
- UPDATE Progress: move items from "In Progress" to "Done" when completed
|
|
6
|
-
- UPDATE "Next Steps" based on what was accomplished
|
|
7
|
-
- PRESERVE exact file paths, function names, and error messages
|
|
8
|
-
- You may remove anything no longer relevant
|
|
9
|
-
|
|
10
|
-
IMPORTANT: If new messages end with unanswered question or request to user, add it to Critical Context (replacing any previous pending question if answered).
|
|
11
|
-
|
|
12
|
-
Use this format (omit sections if not applicable):
|
|
13
|
-
|
|
14
|
-
## Goal
|
|
15
|
-
[Preserve existing goals; add new ones if task expanded]
|
|
16
|
-
|
|
17
|
-
## Constraints & Preferences
|
|
18
|
-
- [Preserve existing; add new ones discovered]
|
|
19
|
-
|
|
20
|
-
## Progress
|
|
21
|
-
|
|
22
|
-
### Done
|
|
23
|
-
- [x] [Include previously done and newly completed items]
|
|
24
|
-
|
|
25
|
-
### In Progress
|
|
26
|
-
- [ ] [Current work—update based on progress]
|
|
27
|
-
|
|
28
|
-
### Blocked
|
|
29
|
-
- [Current blockers—remove if resolved]
|
|
30
|
-
|
|
31
|
-
## Key Decisions
|
|
32
|
-
- **[Decision]**: [Brief rationale] (preserve all previous, add new)
|
|
33
|
-
|
|
34
|
-
## Next Steps
|
|
35
|
-
1. [Update based on current state]
|
|
36
|
-
|
|
37
|
-
## Critical Context
|
|
38
|
-
- [Preserve important context; add new if needed]
|
|
39
|
-
|
|
40
|
-
## Additional Notes
|
|
41
|
-
[Other important info not fitting above]
|
|
42
|
-
|
|
43
|
-
Output only structured summary; no extra text.
|
|
44
|
-
|
|
45
|
-
Keep sections concise. Preserve relevant tool outputs/command results. Include repository state changes (branch, uncommitted changes) if mentioned.
|