@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.
Files changed (50) hide show
  1. package/package.json +4 -4
  2. package/src/cli/config-cli.ts +1 -1
  3. package/src/config/settings-schema.ts +19 -27
  4. package/src/config/settings.ts +3 -4
  5. package/src/extensibility/custom-tools/types.ts +0 -12
  6. package/src/extensibility/extensions/index.ts +0 -5
  7. package/src/extensibility/extensions/runner.ts +6 -26
  8. package/src/extensibility/extensions/types.ts +1 -77
  9. package/src/extensibility/hooks/runner.ts +5 -24
  10. package/src/extensibility/hooks/types.ts +1 -77
  11. package/src/index.ts +2 -13
  12. package/src/modes/components/footer.ts +4 -11
  13. package/src/modes/components/index.ts +0 -1
  14. package/src/modes/components/status-line/segments.ts +1 -2
  15. package/src/modes/components/status-line/types.ts +0 -1
  16. package/src/modes/components/status-line.ts +0 -6
  17. package/src/modes/components/tree-selector.ts +0 -8
  18. package/src/modes/controllers/command-controller.ts +2 -98
  19. package/src/modes/controllers/event-controller.ts +46 -52
  20. package/src/modes/controllers/extension-ui-controller.ts +0 -42
  21. package/src/modes/controllers/input-controller.ts +0 -23
  22. package/src/modes/controllers/selector-controller.ts +0 -5
  23. package/src/modes/interactive-mode.ts +3 -24
  24. package/src/modes/print-mode.ts +0 -16
  25. package/src/modes/rpc/rpc-client.ts +0 -16
  26. package/src/modes/rpc/rpc-mode.ts +0 -32
  27. package/src/modes/rpc/rpc-types.ts +0 -9
  28. package/src/modes/types.ts +1 -13
  29. package/src/modes/utils/ui-helpers.ts +2 -118
  30. package/src/sdk.ts +0 -15
  31. package/src/session/agent-session.ts +89 -650
  32. package/src/session/compaction/branch-summarization.ts +5 -13
  33. package/src/session/compaction/index.ts +0 -1
  34. package/src/session/compaction/utils.ts +94 -2
  35. package/src/session/messages.ts +0 -37
  36. package/src/session/retry-utils.ts +1 -1
  37. package/src/session/session-manager.ts +8 -108
  38. package/src/session/session-types.ts +4 -25
  39. package/src/session/stats.ts +2 -39
  40. package/src/slash-commands/builtin-registry.ts +0 -11
  41. package/src/task/executor.ts +0 -8
  42. package/examples/hooks/custom-compaction.ts +0 -116
  43. package/src/modes/components/compaction-summary-message.ts +0 -59
  44. package/src/prompts/compaction/compaction-short-summary.md +0 -9
  45. package/src/prompts/compaction/compaction-summary-context.md +0 -5
  46. package/src/prompts/compaction/compaction-summary.md +0 -41
  47. package/src/prompts/compaction/compaction-turn-prefix.md +0 -17
  48. package/src/prompts/compaction/compaction-update-summary.md +0 -45
  49. package/src/session/compaction/compaction.ts +0 -864
  50. 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.