fixo-cli 1.0.0
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/LICENSE +201 -0
- package/README.md +530 -0
- package/dist/agent/agent-client.d.ts +108 -0
- package/dist/agent/agent-client.d.ts.map +1 -0
- package/dist/agent/agent-client.js +1247 -0
- package/dist/agent/agent-client.js.map +1 -0
- package/dist/agent/agent-pool.d.ts +20 -0
- package/dist/agent/agent-pool.d.ts.map +1 -0
- package/dist/agent/agent-pool.js +217 -0
- package/dist/agent/agent-pool.js.map +1 -0
- package/dist/agent/background-awareness.d.ts +55 -0
- package/dist/agent/background-awareness.d.ts.map +1 -0
- package/dist/agent/background-awareness.js +104 -0
- package/dist/agent/background-awareness.js.map +1 -0
- package/dist/agent/command-parser.d.ts +33 -0
- package/dist/agent/command-parser.d.ts.map +1 -0
- package/dist/agent/command-parser.js +120 -0
- package/dist/agent/command-parser.js.map +1 -0
- package/dist/agent/context-budget.d.ts +91 -0
- package/dist/agent/context-budget.d.ts.map +1 -0
- package/dist/agent/context-budget.js +219 -0
- package/dist/agent/context-budget.js.map +1 -0
- package/dist/agent/conversation.d.ts +190 -0
- package/dist/agent/conversation.d.ts.map +1 -0
- package/dist/agent/conversation.js +547 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/hooks.d.ts +72 -0
- package/dist/agent/hooks.d.ts.map +1 -0
- package/dist/agent/hooks.js +214 -0
- package/dist/agent/hooks.js.map +1 -0
- package/dist/agent/mcp-bridge.d.ts +13 -0
- package/dist/agent/mcp-bridge.d.ts.map +1 -0
- package/dist/agent/mcp-bridge.js +86 -0
- package/dist/agent/mcp-bridge.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +24 -0
- package/dist/agent/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp-client.js +146 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mcp-manager.d.ts +13 -0
- package/dist/agent/mcp-manager.d.ts.map +1 -0
- package/dist/agent/mcp-manager.js +84 -0
- package/dist/agent/mcp-manager.js.map +1 -0
- package/dist/agent/mcp-registry.d.ts +45 -0
- package/dist/agent/mcp-registry.d.ts.map +1 -0
- package/dist/agent/mcp-registry.js +98 -0
- package/dist/agent/mcp-registry.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +14 -0
- package/dist/agent/orchestrator.d.ts.map +1 -0
- package/dist/agent/orchestrator.js +118 -0
- package/dist/agent/orchestrator.js.map +1 -0
- package/dist/agent/parser-adapter.d.ts +120 -0
- package/dist/agent/parser-adapter.d.ts.map +1 -0
- package/dist/agent/parser-adapter.js +265 -0
- package/dist/agent/parser-adapter.js.map +1 -0
- package/dist/agent/parsers/imports.d.ts +11 -0
- package/dist/agent/parsers/imports.d.ts.map +1 -0
- package/dist/agent/parsers/imports.js +94 -0
- package/dist/agent/parsers/imports.js.map +1 -0
- package/dist/agent/parsers/shell.d.ts +23 -0
- package/dist/agent/parsers/shell.d.ts.map +1 -0
- package/dist/agent/parsers/shell.js +200 -0
- package/dist/agent/parsers/shell.js.map +1 -0
- package/dist/agent/parsers/symbols.d.ts +17 -0
- package/dist/agent/parsers/symbols.d.ts.map +1 -0
- package/dist/agent/parsers/symbols.js +103 -0
- package/dist/agent/parsers/symbols.js.map +1 -0
- package/dist/agent/permissions.d.ts +65 -0
- package/dist/agent/permissions.d.ts.map +1 -0
- package/dist/agent/permissions.js +219 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/predictive-gate.d.ts +69 -0
- package/dist/agent/predictive-gate.d.ts.map +1 -0
- package/dist/agent/predictive-gate.js +128 -0
- package/dist/agent/predictive-gate.js.map +1 -0
- package/dist/agent/provider-cooldown.d.ts +144 -0
- package/dist/agent/provider-cooldown.d.ts.map +1 -0
- package/dist/agent/provider-cooldown.js +300 -0
- package/dist/agent/provider-cooldown.js.map +1 -0
- package/dist/agent/providers-manager.d.ts +109 -0
- package/dist/agent/providers-manager.d.ts.map +1 -0
- package/dist/agent/providers-manager.js +464 -0
- package/dist/agent/providers-manager.js.map +1 -0
- package/dist/agent/repo-map.d.ts +6 -0
- package/dist/agent/repo-map.d.ts.map +1 -0
- package/dist/agent/repo-map.js +221 -0
- package/dist/agent/repo-map.js.map +1 -0
- package/dist/agent/retry.d.ts +103 -0
- package/dist/agent/retry.d.ts.map +1 -0
- package/dist/agent/retry.js +276 -0
- package/dist/agent/retry.js.map +1 -0
- package/dist/agent/search/index.d.ts +61 -0
- package/dist/agent/search/index.d.ts.map +1 -0
- package/dist/agent/search/index.js +314 -0
- package/dist/agent/search/index.js.map +1 -0
- package/dist/agent/single-agent.d.ts +76 -0
- package/dist/agent/single-agent.d.ts.map +1 -0
- package/dist/agent/single-agent.js +697 -0
- package/dist/agent/single-agent.js.map +1 -0
- package/dist/agent/skills.d.ts +22 -0
- package/dist/agent/skills.d.ts.map +1 -0
- package/dist/agent/skills.js +139 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/stream-glue.d.ts +85 -0
- package/dist/agent/stream-glue.d.ts.map +1 -0
- package/dist/agent/stream-glue.js +120 -0
- package/dist/agent/stream-glue.js.map +1 -0
- package/dist/agent/subagent.d.ts +72 -0
- package/dist/agent/subagent.d.ts.map +1 -0
- package/dist/agent/subagent.js +193 -0
- package/dist/agent/subagent.js.map +1 -0
- package/dist/agent/telemetry.d.ts +192 -0
- package/dist/agent/telemetry.d.ts.map +1 -0
- package/dist/agent/telemetry.js +400 -0
- package/dist/agent/telemetry.js.map +1 -0
- package/dist/agent/tokenizer.d.ts +42 -0
- package/dist/agent/tokenizer.d.ts.map +1 -0
- package/dist/agent/tokenizer.js +107 -0
- package/dist/agent/tokenizer.js.map +1 -0
- package/dist/agent/tool-executor.d.ts +289 -0
- package/dist/agent/tool-executor.d.ts.map +1 -0
- package/dist/agent/tool-executor.js +2519 -0
- package/dist/agent/tool-executor.js.map +1 -0
- package/dist/agent/web-impl.d.ts +2 -0
- package/dist/agent/web-impl.d.ts.map +1 -0
- package/dist/agent/web-impl.js +34 -0
- package/dist/agent/web-impl.js.map +1 -0
- package/dist/agent/web.d.ts +8 -0
- package/dist/agent/web.d.ts.map +1 -0
- package/dist/agent/web.js +8 -0
- package/dist/agent/web.js.map +1 -0
- package/dist/agent/worker-agent.d.ts +27 -0
- package/dist/agent/worker-agent.d.ts.map +1 -0
- package/dist/agent/worker-agent.js +503 -0
- package/dist/agent/worker-agent.js.map +1 -0
- package/dist/config.d.ts +162 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/context/fixo-md-watcher.d.ts +42 -0
- package/dist/context/fixo-md-watcher.d.ts.map +1 -0
- package/dist/context/fixo-md-watcher.js +126 -0
- package/dist/context/fixo-md-watcher.js.map +1 -0
- package/dist/context/fixo-md.d.ts +50 -0
- package/dist/context/fixo-md.d.ts.map +1 -0
- package/dist/context/fixo-md.js +118 -0
- package/dist/context/fixo-md.js.map +1 -0
- package/dist/context/todo.d.ts +65 -0
- package/dist/context/todo.d.ts.map +1 -0
- package/dist/context/todo.js +194 -0
- package/dist/context/todo.js.map +1 -0
- package/dist/git/git-manager.d.ts +33 -0
- package/dist/git/git-manager.d.ts.map +1 -0
- package/dist/git/git-manager.js +293 -0
- package/dist/git/git-manager.js.map +1 -0
- package/dist/git/git-ops.d.ts +10 -0
- package/dist/git/git-ops.d.ts.map +1 -0
- package/dist/git/git-ops.js +131 -0
- package/dist/git/git-ops.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +352 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +30 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +273 -0
- package/dist/indexer.js.map +1 -0
- package/dist/lsp/lsp-client.d.ts +24 -0
- package/dist/lsp/lsp-client.d.ts.map +1 -0
- package/dist/lsp/lsp-client.js +205 -0
- package/dist/lsp/lsp-client.js.map +1 -0
- package/dist/lsp/lsp-manager.d.ts +17 -0
- package/dist/lsp/lsp-manager.d.ts.map +1 -0
- package/dist/lsp/lsp-manager.js +154 -0
- package/dist/lsp/lsp-manager.js.map +1 -0
- package/dist/lsp/lsp-pre-save.d.ts +137 -0
- package/dist/lsp/lsp-pre-save.d.ts.map +1 -0
- package/dist/lsp/lsp-pre-save.js +245 -0
- package/dist/lsp/lsp-pre-save.js.map +1 -0
- package/dist/lsp/syntax-fallback.d.ts +83 -0
- package/dist/lsp/syntax-fallback.d.ts.map +1 -0
- package/dist/lsp/syntax-fallback.js +275 -0
- package/dist/lsp/syntax-fallback.js.map +1 -0
- package/dist/model-outcomes.d.ts +12 -0
- package/dist/model-outcomes.d.ts.map +1 -0
- package/dist/model-outcomes.js +46 -0
- package/dist/model-outcomes.js.map +1 -0
- package/dist/planner.d.ts +32 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +163 -0
- package/dist/planner.js.map +1 -0
- package/dist/project-memory.d.ts +29 -0
- package/dist/project-memory.d.ts.map +1 -0
- package/dist/project-memory.js +349 -0
- package/dist/project-memory.js.map +1 -0
- package/dist/review.d.ts +2 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +61 -0
- package/dist/review.js.map +1 -0
- package/dist/runtime/background-jobs.d.ts +97 -0
- package/dist/runtime/background-jobs.d.ts.map +1 -0
- package/dist/runtime/background-jobs.js +331 -0
- package/dist/runtime/background-jobs.js.map +1 -0
- package/dist/runtime/credential-vault.d.ts +124 -0
- package/dist/runtime/credential-vault.d.ts.map +1 -0
- package/dist/runtime/credential-vault.js +184 -0
- package/dist/runtime/credential-vault.js.map +1 -0
- package/dist/runtime/loop-trap.d.ts +197 -0
- package/dist/runtime/loop-trap.d.ts.map +1 -0
- package/dist/runtime/loop-trap.js +420 -0
- package/dist/runtime/loop-trap.js.map +1 -0
- package/dist/runtime/policy.d.ts +15 -0
- package/dist/runtime/policy.d.ts.map +1 -0
- package/dist/runtime/policy.js +60 -0
- package/dist/runtime/policy.js.map +1 -0
- package/dist/runtime/redaction.d.ts +66 -0
- package/dist/runtime/redaction.d.ts.map +1 -0
- package/dist/runtime/redaction.js +155 -0
- package/dist/runtime/redaction.js.map +1 -0
- package/dist/runtime/session-snapshots.d.ts +76 -0
- package/dist/runtime/session-snapshots.d.ts.map +1 -0
- package/dist/runtime/session-snapshots.js +166 -0
- package/dist/runtime/session-snapshots.js.map +1 -0
- package/dist/runtime/staging.d.ts +205 -0
- package/dist/runtime/staging.d.ts.map +1 -0
- package/dist/runtime/staging.js +526 -0
- package/dist/runtime/staging.js.map +1 -0
- package/dist/runtime/task-session.d.ts +95 -0
- package/dist/runtime/task-session.d.ts.map +1 -0
- package/dist/runtime/task-session.js +263 -0
- package/dist/runtime/task-session.js.map +1 -0
- package/dist/runtime/worktree.d.ts +55 -0
- package/dist/runtime/worktree.d.ts.map +1 -0
- package/dist/runtime/worktree.js +175 -0
- package/dist/runtime/worktree.js.map +1 -0
- package/dist/setup-wizard.d.ts +8 -0
- package/dist/setup-wizard.d.ts.map +1 -0
- package/dist/setup-wizard.js +73 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/shared/content.d.ts +43 -0
- package/dist/shared/content.d.ts.map +1 -0
- package/dist/shared/content.js +61 -0
- package/dist/shared/content.js.map +1 -0
- package/dist/shared/types.d.ts +217 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +3 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/test-runner.d.ts +5 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +42 -0
- package/dist/test-runner.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/ascii.d.ts +23 -0
- package/dist/ui/ascii.d.ts.map +1 -0
- package/dist/ui/ascii.js +45 -0
- package/dist/ui/ascii.js.map +1 -0
- package/dist/ui/colors.d.ts +111 -0
- package/dist/ui/colors.d.ts.map +1 -0
- package/dist/ui/colors.js +166 -0
- package/dist/ui/colors.js.map +1 -0
- package/dist/ui/image-attach.d.ts +27 -0
- package/dist/ui/image-attach.d.ts.map +1 -0
- package/dist/ui/image-attach.js +100 -0
- package/dist/ui/image-attach.js.map +1 -0
- package/dist/ui/index.d.ts +18 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +18 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/markdown-stream.d.ts +91 -0
- package/dist/ui/markdown-stream.d.ts.map +1 -0
- package/dist/ui/markdown-stream.js +524 -0
- package/dist/ui/markdown-stream.js.map +1 -0
- package/dist/ui/plan-renderer.d.ts +36 -0
- package/dist/ui/plan-renderer.d.ts.map +1 -0
- package/dist/ui/plan-renderer.js +79 -0
- package/dist/ui/plan-renderer.js.map +1 -0
- package/dist/ui/prompt.d.ts +11 -0
- package/dist/ui/prompt.d.ts.map +1 -0
- package/dist/ui/prompt.js +1960 -0
- package/dist/ui/prompt.js.map +1 -0
- package/dist/ui/render-primitives.d.ts +117 -0
- package/dist/ui/render-primitives.d.ts.map +1 -0
- package/dist/ui/render-primitives.js +322 -0
- package/dist/ui/render-primitives.js.map +1 -0
- package/dist/ui/render.d.ts +133 -0
- package/dist/ui/render.d.ts.map +1 -0
- package/dist/ui/render.js +547 -0
- package/dist/ui/render.js.map +1 -0
- package/dist/ui/session-header.d.ts +30 -0
- package/dist/ui/session-header.d.ts.map +1 -0
- package/dist/ui/session-header.js +74 -0
- package/dist/ui/session-header.js.map +1 -0
- package/dist/workspace-guard.d.ts +68 -0
- package/dist/workspace-guard.d.ts.map +1 -0
- package/dist/workspace-guard.js +168 -0
- package/dist/workspace-guard.js.map +1 -0
- package/dist/workspace-lock.d.ts +27 -0
- package/dist/workspace-lock.d.ts.map +1 -0
- package/dist/workspace-lock.js +95 -0
- package/dist/workspace-lock.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConversationManager — manages multi-turn chat context for the FixO CLI agent.
|
|
3
|
+
*
|
|
4
|
+
* Provides automatic context window management inspired by OpenCode:
|
|
5
|
+
* 1. Tracks estimated token usage per model's context window limit
|
|
6
|
+
* 2. Auto-compacts when the next request would overflow the context
|
|
7
|
+
* 3. Uses a structured summary template to preserve critical information
|
|
8
|
+
* 4. Preserves the N most-recent turns verbatim for continuity
|
|
9
|
+
* 5. Prunes old tool outputs to free space before full compaction
|
|
10
|
+
*/
|
|
11
|
+
import { countMessagesTokens, countTokens } from './tokenizer.js';
|
|
12
|
+
import { ContextBudgetEnforcer } from './context-budget.js';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Constants
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Known context window limits (input tokens) for models/providers.
|
|
18
|
+
* These are conservative estimates — we leave headroom for output tokens.
|
|
19
|
+
* Format: pattern → max input tokens (context minus output reservation).
|
|
20
|
+
*/
|
|
21
|
+
const MODEL_CONTEXT_LIMITS = [
|
|
22
|
+
// Google Gemini — huge contexts
|
|
23
|
+
[/gemini-2\.5-flash/i, 900_000],
|
|
24
|
+
[/gemini-2\.5-pro/i, 900_000],
|
|
25
|
+
[/gemini-2\.0/i, 900_000],
|
|
26
|
+
[/gemini/i, 900_000],
|
|
27
|
+
// Groq — standard
|
|
28
|
+
[/llama-3\.3-70b/i, 120_000],
|
|
29
|
+
[/llama-4/i, 120_000],
|
|
30
|
+
[/deepseek-r1/i, 120_000],
|
|
31
|
+
[/compound/i, 120_000],
|
|
32
|
+
[/gpt-oss/i, 120_000],
|
|
33
|
+
// Cerebras
|
|
34
|
+
[/qwen-3-235b/i, 8_000], // Very small on free tier
|
|
35
|
+
[/llama3\.1-8b/i, 8_000],
|
|
36
|
+
// SambaNova
|
|
37
|
+
[/deepseek-v3/i, 120_000],
|
|
38
|
+
[/qwen3-coder/i, 120_000],
|
|
39
|
+
// Mistral
|
|
40
|
+
[/mistral-large/i, 120_000],
|
|
41
|
+
[/codestral/i, 250_000],
|
|
42
|
+
[/devstral/i, 120_000],
|
|
43
|
+
[/magistral/i, 120_000],
|
|
44
|
+
// OpenRouter — varies by model
|
|
45
|
+
[/openrouter/i, 120_000],
|
|
46
|
+
// Cloudflare — depends on model
|
|
47
|
+
[/cloudflare/i, 120_000],
|
|
48
|
+
// Cohere
|
|
49
|
+
[/command-r/i, 120_000],
|
|
50
|
+
// Zen / NVIDIA
|
|
51
|
+
[/zen|nvidia/i, 120_000],
|
|
52
|
+
];
|
|
53
|
+
/** Default context limit when model is unknown */
|
|
54
|
+
const DEFAULT_CONTEXT_LIMIT = 120_000;
|
|
55
|
+
/** Reserve this many tokens for the output response */
|
|
56
|
+
const OUTPUT_TOKEN_RESERVATION = 8_000;
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the *usable input* context limit for a model identifier.
|
|
59
|
+
* The result is the model's full window minus {@link OUTPUT_TOKEN_RESERVATION}
|
|
60
|
+
* so callers that only care about how much room they have left for input
|
|
61
|
+
* tokens (predictive gate, budget planner) can use the answer directly.
|
|
62
|
+
*/
|
|
63
|
+
export function resolveModelContextLimit(model) {
|
|
64
|
+
if (!model)
|
|
65
|
+
return DEFAULT_CONTEXT_LIMIT - OUTPUT_TOKEN_RESERVATION;
|
|
66
|
+
for (const [pattern, limit] of MODEL_CONTEXT_LIMITS) {
|
|
67
|
+
if (pattern.test(model))
|
|
68
|
+
return limit - OUTPUT_TOKEN_RESERVATION;
|
|
69
|
+
}
|
|
70
|
+
return DEFAULT_CONTEXT_LIMIT - OUTPUT_TOKEN_RESERVATION;
|
|
71
|
+
}
|
|
72
|
+
/** Maximum token budget for conversation history (usable input space) */
|
|
73
|
+
const DEFAULT_MAX_TOKEN_BUDGET = 100_000;
|
|
74
|
+
/** Minimum number of individual messages to keep (2 turn-pairs = 4 messages). */
|
|
75
|
+
const MIN_MESSAGES_TO_KEEP = 4;
|
|
76
|
+
/** Number of recent turn-pairs to preserve verbatim during compaction */
|
|
77
|
+
const TAIL_TURNS = 2;
|
|
78
|
+
/** Maximum characters for tool output in old messages before truncation */
|
|
79
|
+
const TOOL_OUTPUT_MAX_CHARS = 2_000;
|
|
80
|
+
/** Structured summary template (inspired by OpenCode) */
|
|
81
|
+
const SUMMARY_TEMPLATE = `Output exactly the Markdown structure shown below. Keep every section even when empty.
|
|
82
|
+
|
|
83
|
+
## Goal
|
|
84
|
+
- [single-sentence task summary]
|
|
85
|
+
|
|
86
|
+
## Constraints & Preferences
|
|
87
|
+
- [user constraints, preferences, specs, or "(none)"]
|
|
88
|
+
|
|
89
|
+
## Progress
|
|
90
|
+
### Done
|
|
91
|
+
- [completed work or "(none)"]
|
|
92
|
+
|
|
93
|
+
### In Progress
|
|
94
|
+
- [current work or "(none)"]
|
|
95
|
+
|
|
96
|
+
## Key Decisions
|
|
97
|
+
- [decision and why, or "(none)"]
|
|
98
|
+
|
|
99
|
+
## Next Steps
|
|
100
|
+
- [ordered next actions or "(none)"]
|
|
101
|
+
|
|
102
|
+
## Critical Context
|
|
103
|
+
- [important technical facts, errors, open questions, or "(none)"]
|
|
104
|
+
|
|
105
|
+
## Relevant Files
|
|
106
|
+
- [file or directory path: why it matters, or "(none)"]
|
|
107
|
+
|
|
108
|
+
Rules:
|
|
109
|
+
- Use terse bullets, not prose paragraphs.
|
|
110
|
+
- Preserve exact file paths, commands, error strings, and identifiers.
|
|
111
|
+
- Do not mention the summary process or that context was compacted.`;
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// ConversationManager
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
export class ConversationManager {
|
|
116
|
+
history = [];
|
|
117
|
+
maxTokenBudget;
|
|
118
|
+
summary = '';
|
|
119
|
+
contextLimit = DEFAULT_CONTEXT_LIMIT;
|
|
120
|
+
_lastCompactionInfo = null;
|
|
121
|
+
/**
|
|
122
|
+
* When set (>0), `getTotalTokens()` returns this value instead of
|
|
123
|
+
* summing the history. Used by `--resume` so the restored session
|
|
124
|
+
* shows the same token count the user saw at save time.
|
|
125
|
+
*/
|
|
126
|
+
tokenOverride = 0;
|
|
127
|
+
constructor(maxTokenBudget = DEFAULT_MAX_TOKEN_BUDGET) {
|
|
128
|
+
this.maxTokenBudget = maxTokenBudget;
|
|
129
|
+
}
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Model-aware context limits
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
/**
|
|
134
|
+
* Auto-configure the context budget based on the model being used.
|
|
135
|
+
* Call this whenever the model changes.
|
|
136
|
+
*/
|
|
137
|
+
setContextLimit(model) {
|
|
138
|
+
for (const [pattern, limit] of MODEL_CONTEXT_LIMITS) {
|
|
139
|
+
if (pattern.test(model)) {
|
|
140
|
+
this.contextLimit = limit - OUTPUT_TOKEN_RESERVATION;
|
|
141
|
+
this.maxTokenBudget = Math.min(this.maxTokenBudget, this.contextLimit);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
this.contextLimit = DEFAULT_CONTEXT_LIMIT - OUTPUT_TOKEN_RESERVATION;
|
|
146
|
+
}
|
|
147
|
+
getContextLimit() {
|
|
148
|
+
return this.contextLimit;
|
|
149
|
+
}
|
|
150
|
+
/** Returns info about the last compaction (for UX display). */
|
|
151
|
+
getLastCompactionInfo() {
|
|
152
|
+
const info = this._lastCompactionInfo;
|
|
153
|
+
this._lastCompactionInfo = null;
|
|
154
|
+
return info;
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Token estimation
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
/**
|
|
160
|
+
* Real BPE token count for a piece of text. Uses the OpenAI cl100k
|
|
161
|
+
* encoding by default (good proxy for llama-3, mistral, qwen,
|
|
162
|
+
* deepseek, gemini etc. that the FreeLLMAPI proxy fronts). Pass the
|
|
163
|
+
* model name for an encoder-tuned count.
|
|
164
|
+
*/
|
|
165
|
+
estimateTokens(text, model) {
|
|
166
|
+
return countTokens(text, model);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Estimate tokens consumed by a single message, accounting for both its
|
|
170
|
+
* `content` and any attached `tool_calls`.
|
|
171
|
+
*/
|
|
172
|
+
estimateMessageTokens(message) {
|
|
173
|
+
return countMessagesTokens([message]);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Calculate the total estimated token count across the entire history.
|
|
177
|
+
*/
|
|
178
|
+
getTotalTokens() {
|
|
179
|
+
if (this.tokenOverride > 0)
|
|
180
|
+
return this.tokenOverride;
|
|
181
|
+
return this.history.reduce((sum, msg) => sum + this.estimateMessageTokens(msg), 0);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Restore the conversation from a previously-saved snapshot. Replaces
|
|
185
|
+
* the entire history, summary, and token override atomically. The
|
|
186
|
+
* `tokens` argument is the value recorded at save time; subsequent
|
|
187
|
+
* reads of `getTotalTokens()` will prefer this override so the
|
|
188
|
+
* resumed session shows the same context-usage meter the user saw
|
|
189
|
+
* when they saved.
|
|
190
|
+
*/
|
|
191
|
+
restoreFromSnapshot(messages, summary, tokens) {
|
|
192
|
+
this.history = [...messages];
|
|
193
|
+
this.summary = summary;
|
|
194
|
+
this.tokenOverride = Math.max(0, tokens);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Estimate the total token count for the NEXT LLM request.
|
|
198
|
+
* This is what actually matters for context overflow detection.
|
|
199
|
+
*/
|
|
200
|
+
estimateNextRequestTokens(systemPrompt, userMessage) {
|
|
201
|
+
const systemTokens = this.estimateTokens(systemPrompt);
|
|
202
|
+
const historyTokens = this.getTotalTokens();
|
|
203
|
+
const userTokens = this.estimateTokens(userMessage);
|
|
204
|
+
const summaryTokens = this.summary ? this.estimateTokens(this.summary) : 0;
|
|
205
|
+
return systemTokens + summaryTokens + historyTokens + userTokens;
|
|
206
|
+
}
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// Budget enforcement (Pillar 4)
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
/**
|
|
211
|
+
* Proactively trim the conversation to fit a token budget, using the
|
|
212
|
+
* tiered {@link ContextBudgetEnforcer} strategy. The `model` argument
|
|
213
|
+
* is forwarded to the BPE encoder so the counts are tuned to the
|
|
214
|
+
* downstream provider.
|
|
215
|
+
*
|
|
216
|
+
* If the enforcer cannot fit the budget even after pruning tool
|
|
217
|
+
* outputs, dropping old turns, and truncating tool arguments, it
|
|
218
|
+
* sets `report.markForCompaction = true`; the caller should then
|
|
219
|
+
* invoke {@link ConversationManager.compact} to summarise the
|
|
220
|
+
* oldest turns via an LLM.
|
|
221
|
+
*
|
|
222
|
+
* Returns a report describing the actions taken and the new total
|
|
223
|
+
* token count.
|
|
224
|
+
*/
|
|
225
|
+
enforceBudget(maxTokens, model) {
|
|
226
|
+
const enforcer = new ContextBudgetEnforcer(model);
|
|
227
|
+
const { messages, report } = enforcer.enforce(this.history, { maxTokens, model });
|
|
228
|
+
if (report.actions[0] !== 'none') {
|
|
229
|
+
this.history = messages;
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
trimmed: report.actions[0] !== 'none',
|
|
233
|
+
report: {
|
|
234
|
+
tokensBefore: report.tokensBefore,
|
|
235
|
+
tokensAfter: report.tokensAfter,
|
|
236
|
+
actions: report.actions,
|
|
237
|
+
markForCompaction: report.markForCompaction,
|
|
238
|
+
withinBudget: report.withinBudget,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// ---------------------------------------------------------------------------
|
|
243
|
+
// Mutation helpers
|
|
244
|
+
// ---------------------------------------------------------------------------
|
|
245
|
+
/**
|
|
246
|
+
* Add a user message and the corresponding assistant response as a single
|
|
247
|
+
* conversational turn, then prune if the budget is exceeded.
|
|
248
|
+
*/
|
|
249
|
+
addTurn(userMessage, assistantResponse) {
|
|
250
|
+
this.history.push({ role: 'user', content: userMessage }, { role: 'assistant', content: assistantResponse });
|
|
251
|
+
this.pruneToFitBudget();
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Add a raw {@link ChatMessage} (useful for tool-call results or other
|
|
255
|
+
* non-standard messages), then prune if the budget is exceeded.
|
|
256
|
+
*/
|
|
257
|
+
addMessage(message) {
|
|
258
|
+
this.history.push(message);
|
|
259
|
+
this.pruneToFitBudget();
|
|
260
|
+
}
|
|
261
|
+
// ---------------------------------------------------------------------------
|
|
262
|
+
// Accessors
|
|
263
|
+
// ---------------------------------------------------------------------------
|
|
264
|
+
/**
|
|
265
|
+
* Return all messages for injection into the LLM context.
|
|
266
|
+
* If a compacted summary exists, it is prepended as the first message.
|
|
267
|
+
*/
|
|
268
|
+
getMessages() {
|
|
269
|
+
const msgs = [];
|
|
270
|
+
if (this.summary) {
|
|
271
|
+
msgs.push({
|
|
272
|
+
role: 'assistant',
|
|
273
|
+
content: `[Previous conversation context]\n\n${this.summary}`,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
msgs.push(...this.history);
|
|
277
|
+
return msgs;
|
|
278
|
+
}
|
|
279
|
+
/** Number of complete user/assistant turn pairs in the history. */
|
|
280
|
+
getTurnCount() {
|
|
281
|
+
return Math.floor(this.history.length / 2);
|
|
282
|
+
}
|
|
283
|
+
/** Total number of messages in history (excluding summary). */
|
|
284
|
+
getMessageCount() {
|
|
285
|
+
return this.history.length;
|
|
286
|
+
}
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
288
|
+
// Pruning
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
/**
|
|
291
|
+
* Remove the oldest user/assistant pairs until the total token estimate
|
|
292
|
+
* fits within {@link maxTokenBudget}.
|
|
293
|
+
*/
|
|
294
|
+
pruneToFitBudget() {
|
|
295
|
+
while (this.getTotalTokens() > this.maxTokenBudget &&
|
|
296
|
+
this.history.length > MIN_MESSAGES_TO_KEEP) {
|
|
297
|
+
let nextUserIndex = -1;
|
|
298
|
+
for (let i = 1; i < this.history.length; i++) {
|
|
299
|
+
if (this.history[i].role === 'user') {
|
|
300
|
+
nextUserIndex = i;
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (nextUserIndex !== -1 && (this.history.length - nextUserIndex) >= MIN_MESSAGES_TO_KEEP) {
|
|
305
|
+
this.history.splice(0, nextUserIndex);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Prune large tool outputs in older messages to free context space.
|
|
314
|
+
* Keeps the last TAIL_TURNS * 2 messages untouched.
|
|
315
|
+
*/
|
|
316
|
+
pruneToolOutputs() {
|
|
317
|
+
let freedChars = 0;
|
|
318
|
+
const keepFrom = Math.max(0, this.history.length - TAIL_TURNS * 2);
|
|
319
|
+
for (let i = 0; i < keepFrom; i++) {
|
|
320
|
+
const msg = this.history[i];
|
|
321
|
+
if (msg.role === 'tool' && msg.content && msg.content.length > TOOL_OUTPUT_MAX_CHARS) {
|
|
322
|
+
const original = msg.content.length;
|
|
323
|
+
msg.content = msg.content.slice(0, TOOL_OUTPUT_MAX_CHARS) +
|
|
324
|
+
`\n\n... [truncated: ${original} → ${TOOL_OUTPUT_MAX_CHARS} chars to save context]`;
|
|
325
|
+
freedChars += original - TOOL_OUTPUT_MAX_CHARS;
|
|
326
|
+
}
|
|
327
|
+
// Also truncate large assistant tool_calls arguments
|
|
328
|
+
if (msg.role === 'assistant' && msg.tool_calls) {
|
|
329
|
+
for (const tc of msg.tool_calls) {
|
|
330
|
+
if (tc.function?.arguments && tc.function.arguments.length > TOOL_OUTPUT_MAX_CHARS * 2) {
|
|
331
|
+
const original = tc.function.arguments.length;
|
|
332
|
+
tc.function.arguments = tc.function.arguments.slice(0, TOOL_OUTPUT_MAX_CHARS) + '...}';
|
|
333
|
+
freedChars += original - TOOL_OUTPUT_MAX_CHARS;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return Math.ceil(freedChars / 4); // Return estimated tokens freed
|
|
339
|
+
}
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
// Lifecycle
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
/** Clear all conversation history and summary. */
|
|
344
|
+
clear() {
|
|
345
|
+
this.history = [];
|
|
346
|
+
this.summary = '';
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// Serialisation — session persistence / recovery
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
/** Export a deep copy of the raw history for external persistence. */
|
|
352
|
+
exportHistory() {
|
|
353
|
+
return this.history.map((msg) => ({ ...msg }));
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Import a previously-exported history, replacing the current one.
|
|
357
|
+
* Automatically prunes to fit the current token budget after import.
|
|
358
|
+
*/
|
|
359
|
+
importHistory(messages) {
|
|
360
|
+
this.history = messages.map((msg) => ({ ...msg }));
|
|
361
|
+
this.pruneToFitBudget();
|
|
362
|
+
}
|
|
363
|
+
// ---------------------------------------------------------------------------
|
|
364
|
+
// Compaction & Summarization
|
|
365
|
+
// ---------------------------------------------------------------------------
|
|
366
|
+
getSummary() {
|
|
367
|
+
return this.summary;
|
|
368
|
+
}
|
|
369
|
+
setSummary(summary) {
|
|
370
|
+
this.summary = summary;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Check if the conversation should be compacted before the next request.
|
|
374
|
+
* Uses the estimated next request size vs the model's context limit.
|
|
375
|
+
* If systemPrompt/userMessage are not provided, uses a simpler history-only check.
|
|
376
|
+
*/
|
|
377
|
+
shouldCompact(systemPrompt, userMessage) {
|
|
378
|
+
if (this.history.length <= MIN_MESSAGES_TO_KEEP)
|
|
379
|
+
return false;
|
|
380
|
+
if (systemPrompt && userMessage) {
|
|
381
|
+
// Predictive check: will the next request overflow the context window?
|
|
382
|
+
const estimated = this.estimateNextRequestTokens(systemPrompt, userMessage);
|
|
383
|
+
// Trigger compaction at 75% of context limit to leave headroom
|
|
384
|
+
return estimated > this.contextLimit * 0.75;
|
|
385
|
+
}
|
|
386
|
+
// Fallback: simple history-based check
|
|
387
|
+
return this.getTotalTokens() > this.maxTokenBudget * 0.7;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Compact the conversation using a structured summary.
|
|
391
|
+
* - Preserves the last TAIL_TURNS turn-pairs verbatim
|
|
392
|
+
* - Summarizes everything else using the SUMMARY_TEMPLATE
|
|
393
|
+
* - Prunes old tool outputs before summarizing
|
|
394
|
+
*
|
|
395
|
+
* Returns true if compaction succeeded.
|
|
396
|
+
*/
|
|
397
|
+
async compact(client, model) {
|
|
398
|
+
if (this.history.length <= MIN_MESSAGES_TO_KEEP) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
const messagesBefore = this.history.length;
|
|
402
|
+
const tokensBefore = this.getTotalTokens();
|
|
403
|
+
// Step 1: Prune tool outputs to free immediate space
|
|
404
|
+
this.pruneToolOutputs();
|
|
405
|
+
// Step 2: Identify what to compact vs preserve
|
|
406
|
+
// Preserve: last TAIL_TURNS turn-pairs (user+assistant = 2 messages each)
|
|
407
|
+
const tailMessages = TAIL_TURNS * 2;
|
|
408
|
+
const keepCount = Math.min(tailMessages, this.history.length);
|
|
409
|
+
const toCompact = this.history.slice(0, this.history.length - keepCount);
|
|
410
|
+
const preserved = this.history.slice(this.history.length - keepCount);
|
|
411
|
+
if (toCompact.length === 0) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
// Step 3: Format history for summarization
|
|
415
|
+
const formattedHistory = toCompact
|
|
416
|
+
.map((msg) => {
|
|
417
|
+
const role = msg.role.toUpperCase();
|
|
418
|
+
if (msg.role === 'tool') {
|
|
419
|
+
const content = (msg.content ?? '').slice(0, 500);
|
|
420
|
+
return `TOOL_RESULT (${msg.tool_call_id ?? 'unknown'}): ${content}`;
|
|
421
|
+
}
|
|
422
|
+
if (msg.tool_calls && msg.tool_calls.length > 0) {
|
|
423
|
+
const tools = msg.tool_calls.map(tc => ` → ${tc.function?.name}(${(tc.function?.arguments ?? '').slice(0, 100)}...)`).join('\n');
|
|
424
|
+
return `${role}: ${msg.content || '(tool calls)'}\n${tools}`;
|
|
425
|
+
}
|
|
426
|
+
return `${role}: ${msg.content || '(empty)'}`;
|
|
427
|
+
})
|
|
428
|
+
.join('\n\n');
|
|
429
|
+
// Step 4: Build compaction prompt
|
|
430
|
+
const previousSummarySection = this.summary
|
|
431
|
+
? `Here is the previous summary to UPDATE (preserve still-true details, remove stale details, merge new facts):\n<previous-summary>\n${this.summary}\n</previous-summary>\n\n`
|
|
432
|
+
: '';
|
|
433
|
+
const compactionPrompt = `${previousSummarySection}Create a comprehensive summary from the conversation history above.\n\n${SUMMARY_TEMPLATE}`;
|
|
434
|
+
try {
|
|
435
|
+
const response = await client.chat([
|
|
436
|
+
{
|
|
437
|
+
role: 'system',
|
|
438
|
+
content: 'You are a technical context summarization engine. You produce structured summaries that preserve every critical fact needed to continue a coding conversation.',
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
role: 'user',
|
|
442
|
+
content: `Here is the conversation history to summarize:\n\n${formattedHistory}\n\n${compactionPrompt}`,
|
|
443
|
+
},
|
|
444
|
+
], model, { max_tokens: 4000, agent_task_type: 'investigation', required_capabilities: ['fast'] });
|
|
445
|
+
this.summary = response.content?.trim() || '';
|
|
446
|
+
// Replace history with only the preserved tail messages
|
|
447
|
+
this.history = [...preserved];
|
|
448
|
+
const tokensAfter = this.getTotalTokens() + this.estimateTokens(this.summary);
|
|
449
|
+
this._lastCompactionInfo = {
|
|
450
|
+
messagesBefore,
|
|
451
|
+
tokensFreed: Math.max(0, tokensBefore - tokensAfter),
|
|
452
|
+
};
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
catch (error) {
|
|
456
|
+
console.warn(`[Context Compaction] Failed to compact: ${error instanceof Error ? error.message : String(error)}`);
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Check if an error indicates context window overflow from the provider.
|
|
462
|
+
* If true, the caller should auto-compact and retry.
|
|
463
|
+
*/
|
|
464
|
+
static isContextOverflowError(error) {
|
|
465
|
+
const msg = (error?.message ?? '').toLowerCase();
|
|
466
|
+
return msg.includes('too many tokens')
|
|
467
|
+
|| msg.includes('context length')
|
|
468
|
+
|| msg.includes('context_length_exceeded')
|
|
469
|
+
|| msg.includes('maximum context')
|
|
470
|
+
|| msg.includes('token limit')
|
|
471
|
+
|| msg.includes('input too long')
|
|
472
|
+
|| msg.includes('request too large')
|
|
473
|
+
|| (msg.includes('413') && (msg.includes('token') || msg.includes('too large')))
|
|
474
|
+
|| (msg.includes('400') && msg.includes('token'));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
import fs from 'node:fs';
|
|
478
|
+
import path from 'node:path';
|
|
479
|
+
import crypto from 'node:crypto';
|
|
480
|
+
import { getConfigDir } from '../config.js';
|
|
481
|
+
export class SessionManager {
|
|
482
|
+
static getSessionsDir() {
|
|
483
|
+
const dir = path.join(getConfigDir(), 'sessions');
|
|
484
|
+
if (!fs.existsSync(dir)) {
|
|
485
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
486
|
+
}
|
|
487
|
+
return dir;
|
|
488
|
+
}
|
|
489
|
+
static saveSession(conversation, model, modifiedFiles, tokenUsage, sessionId) {
|
|
490
|
+
const id = sessionId || crypto.randomUUID();
|
|
491
|
+
const dir = this.getSessionsDir();
|
|
492
|
+
const filePath = path.join(dir, `session_${id}.json`);
|
|
493
|
+
const data = {
|
|
494
|
+
sessionId: id,
|
|
495
|
+
timestamp: new Date().toISOString(),
|
|
496
|
+
model,
|
|
497
|
+
history: conversation.exportHistory(),
|
|
498
|
+
summary: conversation.getSummary(),
|
|
499
|
+
modifiedFiles,
|
|
500
|
+
tokenUsage,
|
|
501
|
+
};
|
|
502
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
503
|
+
return id;
|
|
504
|
+
}
|
|
505
|
+
static listSessions() {
|
|
506
|
+
const dir = this.getSessionsDir();
|
|
507
|
+
const results = [];
|
|
508
|
+
try {
|
|
509
|
+
const files = fs.readdirSync(dir);
|
|
510
|
+
for (const file of files) {
|
|
511
|
+
if (file.startsWith('session_') && file.endsWith('.json')) {
|
|
512
|
+
try {
|
|
513
|
+
const raw = fs.readFileSync(path.join(dir, file), 'utf-8');
|
|
514
|
+
const data = JSON.parse(raw);
|
|
515
|
+
results.push({
|
|
516
|
+
sessionId: data.sessionId,
|
|
517
|
+
timestamp: data.timestamp,
|
|
518
|
+
model: data.model,
|
|
519
|
+
messageCount: data.history.length,
|
|
520
|
+
summary: data.summary,
|
|
521
|
+
totalTokens: data.tokenUsage?.total_tokens || 0,
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
catch (err) {
|
|
525
|
+
console.warn(`[Debug Warning] Failed to parse session file ${file}:`, err.message || err);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
catch (err) {
|
|
531
|
+
if (err.code !== 'ENOENT') {
|
|
532
|
+
console.warn(`[Debug Warning] Failed to list sessions in ${dir}:`, err.message || err);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return results.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
536
|
+
}
|
|
537
|
+
static loadSession(id) {
|
|
538
|
+
const dir = this.getSessionsDir();
|
|
539
|
+
const filePath = path.join(dir, `session_${id}.json`);
|
|
540
|
+
if (!fs.existsSync(filePath)) {
|
|
541
|
+
throw new Error(`Session file not found for ID: ${id}`);
|
|
542
|
+
}
|
|
543
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
544
|
+
return JSON.parse(raw);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../src/agent/conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export type HookEvent = 'PreToolUse' | 'PostToolUse';
|
|
2
|
+
export type HookDecision = 'allow' | 'deny' | 'modify';
|
|
3
|
+
export interface HookPayload {
|
|
4
|
+
event: HookEvent;
|
|
5
|
+
tool: string;
|
|
6
|
+
args: Record<string, unknown>;
|
|
7
|
+
sessionId: string;
|
|
8
|
+
/** Cwd at the time the hook fired. */
|
|
9
|
+
cwd: string;
|
|
10
|
+
}
|
|
11
|
+
export interface HookCommandResult {
|
|
12
|
+
decision: HookDecision;
|
|
13
|
+
reason?: string;
|
|
14
|
+
modifiedArgs?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface HookSpec {
|
|
17
|
+
/** Stable identifier for the hook (used in telemetry). */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Event this hook listens to. */
|
|
20
|
+
event: HookEvent;
|
|
21
|
+
/** Command to run, including args. */
|
|
22
|
+
command: string;
|
|
23
|
+
/** Args passed to the command. */
|
|
24
|
+
args?: string[];
|
|
25
|
+
/** When false, the hook is skipped. Default: true. */
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
/** Per-hook timeout in ms. Default: 5000. */
|
|
28
|
+
timeoutMs?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface HooksFile {
|
|
31
|
+
version: 1;
|
|
32
|
+
hooks: HookSpec[];
|
|
33
|
+
}
|
|
34
|
+
export interface HookExecutionResult {
|
|
35
|
+
fired: boolean;
|
|
36
|
+
decision: HookDecision;
|
|
37
|
+
reason?: string;
|
|
38
|
+
modifiedArgs?: Record<string, unknown>;
|
|
39
|
+
durationMs: number;
|
|
40
|
+
hookId: string | null;
|
|
41
|
+
}
|
|
42
|
+
/** Read `.fixo/hooks.json` from cwd. Returns null if absent. */
|
|
43
|
+
export declare function loadHooksFile(cwd: string): HooksFile | null;
|
|
44
|
+
/** Save the hooks file. Used by /hooks slash command. */
|
|
45
|
+
export declare function saveHooksFile(cwd: string, file: HooksFile): {
|
|
46
|
+
ok: boolean;
|
|
47
|
+
error?: string;
|
|
48
|
+
};
|
|
49
|
+
/** Hooks for a given event. */
|
|
50
|
+
export declare function getHooksForEvent(cwd: string, event: HookEvent): HookSpec[];
|
|
51
|
+
/**
|
|
52
|
+
* Fire all hooks for an event, in declaration order. The
|
|
53
|
+
* first non-`allow` decision wins. Returns the aggregated
|
|
54
|
+
* result.
|
|
55
|
+
*/
|
|
56
|
+
export declare function fireHooks(cwd: string, event: HookEvent, payload: Omit<HookPayload, 'event' | 'cwd'>): HookExecutionResult;
|
|
57
|
+
/**
|
|
58
|
+
* Apply a pre-hook's `modify` decision: re-validate
|
|
59
|
+
* `modifiedArgs` through `WorkspaceGuard.resolve()` to
|
|
60
|
+
* prevent an attacker-controlled hook from writing outside
|
|
61
|
+
* the workspace. The check is a *best-effort* scan: any
|
|
62
|
+
* `path`/`filePath`/`cwd` field in the args must resolve
|
|
63
|
+
* inside `cwd` (relative paths are fine).
|
|
64
|
+
*/
|
|
65
|
+
export declare function applyModifiedArgs(cwd: string, original: Record<string, unknown>, modified: Record<string, unknown>): {
|
|
66
|
+
ok: boolean;
|
|
67
|
+
args: Record<string, unknown>;
|
|
68
|
+
reason?: string;
|
|
69
|
+
};
|
|
70
|
+
/** Get the hooks file path for a cwd (test-only introspection). */
|
|
71
|
+
export declare function getHooksPath(cwd: string): string;
|
|
72
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/agent/hooks.ts"],"names":[],"mappings":"AAoCA,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,aAAa,CAAC;AAErD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,QAAQ;IACvB,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAU3D;AAED,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAS3F;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,QAAQ,EAAE,CAI1E;AAsDD;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,KAAK,CAAC,GAC1C,mBAAmB,CAyCrB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAwBjE;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|