dexto 1.5.2 → 1.5.4
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/dist/agents/agent-registry.json +9 -0
- package/dist/agents/coding-agent/coding-agent.yml +53 -6
- package/dist/agents/explore-agent/explore-agent.yml +124 -0
- package/dist/cli/approval/cli-approval-handler.d.ts +28 -0
- package/dist/cli/approval/cli-approval-handler.d.ts.map +1 -0
- package/dist/cli/approval/cli-approval-handler.js +146 -0
- package/dist/cli/approval/index.d.ts +7 -0
- package/dist/cli/approval/index.d.ts.map +1 -0
- package/dist/cli/approval/index.js +6 -0
- package/dist/cli/cli-subscriber.d.ts +4 -1
- package/dist/cli/cli-subscriber.d.ts.map +1 -1
- package/dist/cli/cli-subscriber.js +31 -1
- package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/commands.js +2 -1
- package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/general-commands.js +163 -3
- package/dist/cli/commands/interactive-commands/session/index.d.ts +2 -1
- package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/index.js +2 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts +7 -0
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.js +16 -0
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts +3 -1
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/InkCLIRefactored.js +36 -7
- package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ApprovalPrompt.js +10 -2
- package/dist/cli/ink-cli/components/Footer.d.ts +3 -1
- package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/Footer.js +4 -2
- package/dist/cli/ink-cli/components/StatusBar.d.ts +2 -1
- package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/StatusBar.js +12 -3
- package/dist/cli/ink-cli/components/TextBufferInput.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/TextBufferInput.js +3 -2
- package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.js +21 -3
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.js +1 -1
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts +26 -0
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.js +240 -0
- package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.d.ts +21 -0
- package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.js +63 -0
- package/dist/cli/ink-cli/components/overlays/SessionSelectorRefactored.js +2 -2
- package/dist/cli/ink-cli/components/renderers/SearchRenderer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/SearchRenderer.js +15 -1
- package/dist/cli/ink-cli/components/shared/MarkdownText.js +2 -2
- package/dist/cli/ink-cli/constants/processingPhrases.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/processingPhrases.js +15 -4
- package/dist/cli/ink-cli/constants/tips.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/tips.js +4 -1
- package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/InputContainer.js +8 -0
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.js +53 -2
- package/dist/cli/ink-cli/contexts/SoundContext.d.ts +23 -0
- package/dist/cli/ink-cli/contexts/SoundContext.d.ts.map +1 -0
- package/dist/cli/ink-cli/contexts/SoundContext.js +22 -0
- package/dist/cli/ink-cli/contexts/index.d.ts +1 -0
- package/dist/cli/ink-cli/contexts/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/contexts/index.js +1 -0
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useCLIState.js +1 -0
- package/dist/cli/ink-cli/services/processStream.d.ts +4 -0
- package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/processStream.js +152 -14
- package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
- package/dist/cli/ink-cli/state/initialState.js +1 -0
- package/dist/cli/ink-cli/state/types.d.ts +25 -1
- package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.js +4 -0
- package/dist/cli/ink-cli/utils/index.d.ts +1 -0
- package/dist/cli/ink-cli/utils/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/index.js +2 -0
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts +24 -0
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.js +43 -4
- package/dist/cli/ink-cli/utils/soundNotification.d.ts +71 -0
- package/dist/cli/ink-cli/utils/soundNotification.d.ts.map +1 -0
- package/dist/cli/ink-cli/utils/soundNotification.js +203 -0
- package/dist/index.js +10 -15
- package/dist/webui/assets/{index-8j-KMkX1.js → index-Bh2aB65S.js} +209 -209
- package/dist/webui/assets/index-CUVc7IDL.css +1 -0
- package/dist/webui/index.html +2 -2
- package/package.json +7 -7
- package/dist/webui/assets/index-c_AX24V4.css +0 -1
|
@@ -134,6 +134,15 @@
|
|
|
134
134
|
"tags": ["gaming", "gameboy", "pokemon", "emulator", "mcp"],
|
|
135
135
|
"source": "gaming-agent/",
|
|
136
136
|
"main": "gaming-agent.yml"
|
|
137
|
+
},
|
|
138
|
+
"explore-agent": {
|
|
139
|
+
"id": "explore-agent",
|
|
140
|
+
"name": "Explore Agent",
|
|
141
|
+
"description": "Fast, read-only agent for codebase exploration. Use for: 'explore the codebase', 'what's in this folder', 'how does X work', 'find where Y is handled', 'understand the architecture'. Optimized for speed with Haiku.",
|
|
142
|
+
"author": "Truffle AI",
|
|
143
|
+
"tags": ["explore", "search", "understand", "find", "research"],
|
|
144
|
+
"source": "explore-agent/",
|
|
145
|
+
"main": "explore-agent.yml"
|
|
137
146
|
}
|
|
138
147
|
}
|
|
139
148
|
}
|
|
@@ -8,6 +8,14 @@ image: '@dexto/image-local'
|
|
|
8
8
|
# System prompt configuration - defines the agent's behavior as a coding assistant
|
|
9
9
|
systemPrompt:
|
|
10
10
|
contributors:
|
|
11
|
+
- id: date
|
|
12
|
+
type: dynamic
|
|
13
|
+
priority: 10
|
|
14
|
+
source: date
|
|
15
|
+
- id: env
|
|
16
|
+
type: dynamic
|
|
17
|
+
priority: 15
|
|
18
|
+
source: env
|
|
11
19
|
- id: primary
|
|
12
20
|
type: static
|
|
13
21
|
priority: 0
|
|
@@ -24,8 +32,27 @@ systemPrompt:
|
|
|
24
32
|
- Debug issues by examining error messages and code structure
|
|
25
33
|
- Refactor code following best practices and design patterns
|
|
26
34
|
- Explain complex code concepts clearly
|
|
35
|
+
- Delegate exploration tasks to specialized sub-agents
|
|
27
36
|
|
|
28
|
-
|
|
37
|
+
## Task Delegation
|
|
38
|
+
|
|
39
|
+
You have access to spawn_agent for delegating tasks to specialized sub-agents.
|
|
40
|
+
|
|
41
|
+
**When to delegate to explore-agent:**
|
|
42
|
+
- Open-ended exploration: "explore the codebase", "what's in this folder", "how does X work"
|
|
43
|
+
- Understanding architecture: "explain the project structure", "how are components organized"
|
|
44
|
+
- Finding patterns: "where is authentication handled", "find all API endpoints"
|
|
45
|
+
- Research tasks: "what testing framework is used", "how is state managed"
|
|
46
|
+
|
|
47
|
+
**When to use your own tools directly:**
|
|
48
|
+
- Specific file operations: "read src/index.ts", "edit the config file"
|
|
49
|
+
- Targeted searches: "find the User class", "grep for 'TODO'"
|
|
50
|
+
- Writing/editing code: any task that requires modifications
|
|
51
|
+
- Running commands: build, test, install dependencies
|
|
52
|
+
|
|
53
|
+
**Rule of thumb:** If the task requires understanding or exploring before you know what to do, delegate to explore-agent first. If you know exactly what file/function to target, use your tools directly.
|
|
54
|
+
|
|
55
|
+
## Guidelines
|
|
29
56
|
- Always read relevant code before making changes to understand context
|
|
30
57
|
- Use glob_files to find files and grep_content to search within files
|
|
31
58
|
- Test changes when possible using bash_exec
|
|
@@ -70,19 +97,28 @@ toolConfirmation:
|
|
|
70
97
|
# Tool policies optimized for coding workflows
|
|
71
98
|
toolPolicies:
|
|
72
99
|
# Tools that never require approval (safe, read-only operations)
|
|
100
|
+
# Use qualified names: custom--{tool_id} for custom tools, internal--{tool_id} for internal tools
|
|
73
101
|
alwaysAllow:
|
|
74
102
|
- internal--ask_user
|
|
75
|
-
- custom--
|
|
76
|
-
- custom--
|
|
77
|
-
- custom--
|
|
78
|
-
- custom--
|
|
79
|
-
- custom--
|
|
103
|
+
- custom--read_file # Read files without approval
|
|
104
|
+
- custom--glob_files # Search for files without approval
|
|
105
|
+
- custom--grep_content # Search within files without approval
|
|
106
|
+
- custom--bash_output # Check background process output
|
|
107
|
+
- custom--kill_process # Kill processes without approval (only processes started by agent)
|
|
80
108
|
|
|
81
109
|
# Tools that are always denied (dangerous operations)
|
|
82
110
|
# Uncomment to restrict certain operations
|
|
83
111
|
# alwaysDeny:
|
|
84
112
|
# - custom--process-tools--bash_exec--rm -rf* # Prevent recursive deletion
|
|
85
113
|
|
|
114
|
+
# Compaction configuration - automatically summarizes conversation when context is full
|
|
115
|
+
compaction:
|
|
116
|
+
type: reactive-overflow
|
|
117
|
+
enabled: true
|
|
118
|
+
# Uncomment to override model's context window (useful for testing or capping usage):
|
|
119
|
+
# maxContextTokens: 50000 # Cap at 50K tokens regardless of model's max
|
|
120
|
+
# thresholdPercent: 0.9 # Trigger at 90% of context window (leaves safety buffer)
|
|
121
|
+
|
|
86
122
|
# Elicitation configuration - required for ask_user tool
|
|
87
123
|
elicitation:
|
|
88
124
|
enabled: true
|
|
@@ -101,6 +137,17 @@ customTools:
|
|
|
101
137
|
enableBackups: false
|
|
102
138
|
- type: process-tools
|
|
103
139
|
securityLevel: moderate
|
|
140
|
+
- type: agent-spawner
|
|
141
|
+
maxConcurrentAgents: 5
|
|
142
|
+
defaultTimeout: 300000
|
|
143
|
+
allowSpawning: true
|
|
144
|
+
# List of agent IDs from the registry that can be spawned.
|
|
145
|
+
# Agent metadata (name, description) is pulled from the registry at runtime.
|
|
146
|
+
allowedAgents:
|
|
147
|
+
- explore-agent
|
|
148
|
+
# Agents with read-only tools that should have auto-approved tool calls
|
|
149
|
+
autoApproveAgents:
|
|
150
|
+
- explore-agent
|
|
104
151
|
|
|
105
152
|
# Internal resources configuration - expanded for coding projects
|
|
106
153
|
internalResources:
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Explore Agent Configuration
|
|
2
|
+
# Lightweight, read-only agent optimized for codebase exploration
|
|
3
|
+
# Designed to be spawned by other agents for research tasks
|
|
4
|
+
|
|
5
|
+
# No image bundle - uses only explicitly defined tools below
|
|
6
|
+
|
|
7
|
+
# System prompt optimized for exploration tasks
|
|
8
|
+
systemPrompt:
|
|
9
|
+
contributors:
|
|
10
|
+
- id: primary
|
|
11
|
+
type: static
|
|
12
|
+
priority: 0
|
|
13
|
+
content: |
|
|
14
|
+
You are a fast, focused exploration agent specialized in understanding codebases and finding information.
|
|
15
|
+
|
|
16
|
+
## Your Mission
|
|
17
|
+
Quickly and thoroughly explore codebases to answer questions, find patterns, locate files, and understand architecture. You are optimized for speed and accuracy.
|
|
18
|
+
|
|
19
|
+
## Available Tools
|
|
20
|
+
You have access to read-only tools:
|
|
21
|
+
- `glob_files` - Find files matching patterns (e.g., "src/**/*.ts", "*.config.js")
|
|
22
|
+
- `grep_content` - Search for text/patterns within files
|
|
23
|
+
- `read_file` - Read file contents
|
|
24
|
+
|
|
25
|
+
## Exploration Strategy
|
|
26
|
+
|
|
27
|
+
### For "quick" searches:
|
|
28
|
+
- Single glob or grep to find the target
|
|
29
|
+
- Read 1-2 most relevant files
|
|
30
|
+
- Return focused answer
|
|
31
|
+
|
|
32
|
+
### For "medium" exploration:
|
|
33
|
+
- Multiple search patterns to find related files
|
|
34
|
+
- Read key files to understand connections
|
|
35
|
+
- Summarize findings with file references
|
|
36
|
+
|
|
37
|
+
### For "very thorough" analysis:
|
|
38
|
+
- Comprehensive search across multiple naming conventions
|
|
39
|
+
- Trace imports, exports, and dependencies
|
|
40
|
+
- Map relationships between components
|
|
41
|
+
- Provide detailed analysis with evidence
|
|
42
|
+
|
|
43
|
+
## Guidelines
|
|
44
|
+
- Start with broad searches, then narrow down
|
|
45
|
+
- Use glob for file discovery, grep for content search
|
|
46
|
+
- Try multiple naming conventions (camelCase, snake_case, kebab-case, PascalCase)
|
|
47
|
+
- Check common locations: src/, lib/, packages/, tests/, config/
|
|
48
|
+
- Report what you found AND what you didn't find
|
|
49
|
+
- Include file paths and line numbers in your response
|
|
50
|
+
- Be concise but complete
|
|
51
|
+
|
|
52
|
+
## Response Format
|
|
53
|
+
Structure your response as:
|
|
54
|
+
1. **Summary** - Brief answer to the question
|
|
55
|
+
2. **Key Files** - List of relevant files found
|
|
56
|
+
3. **Details** - Specific findings with code references
|
|
57
|
+
4. **Notes** - Any caveats or areas that need further exploration
|
|
58
|
+
|
|
59
|
+
# LLM configuration - Haiku for speed and cost efficiency
|
|
60
|
+
llm:
|
|
61
|
+
provider: anthropic
|
|
62
|
+
model: claude-haiku-4-5-20251001
|
|
63
|
+
apiKey: $ANTHROPIC_API_KEY
|
|
64
|
+
|
|
65
|
+
# Minimal storage - in-memory only for ephemeral use
|
|
66
|
+
storage:
|
|
67
|
+
cache:
|
|
68
|
+
type: in-memory
|
|
69
|
+
database:
|
|
70
|
+
type: in-memory
|
|
71
|
+
blob:
|
|
72
|
+
type: in-memory
|
|
73
|
+
|
|
74
|
+
# Auto-approve all tools since they're read-only
|
|
75
|
+
toolConfirmation:
|
|
76
|
+
mode: auto-approve
|
|
77
|
+
allowedToolsStorage: memory
|
|
78
|
+
|
|
79
|
+
# No internal tools needed for exploration
|
|
80
|
+
internalTools: []
|
|
81
|
+
|
|
82
|
+
# Read-only filesystem tools only - explicitly enable only read operations
|
|
83
|
+
customTools:
|
|
84
|
+
- type: filesystem-tools
|
|
85
|
+
enabledTools: ["read_file", "glob_files", "grep_content"] # Read-only tools only
|
|
86
|
+
allowedPaths: ["."]
|
|
87
|
+
blockedPaths:
|
|
88
|
+
# Version control
|
|
89
|
+
- ".git"
|
|
90
|
+
# Binaries
|
|
91
|
+
- "node_modules/.bin"
|
|
92
|
+
# Environment files with secrets
|
|
93
|
+
- ".env"
|
|
94
|
+
- ".env.local"
|
|
95
|
+
- ".env.production"
|
|
96
|
+
- ".env.development"
|
|
97
|
+
- ".env.test"
|
|
98
|
+
- ".env.staging"
|
|
99
|
+
# Package manager credentials
|
|
100
|
+
- ".npmrc"
|
|
101
|
+
- ".yarnrc"
|
|
102
|
+
- ".pypirc"
|
|
103
|
+
# Git credentials
|
|
104
|
+
- ".git-credentials"
|
|
105
|
+
- ".gitconfig"
|
|
106
|
+
# SSH keys
|
|
107
|
+
- ".ssh"
|
|
108
|
+
# Cloud provider credentials
|
|
109
|
+
- ".aws"
|
|
110
|
+
- ".gcp"
|
|
111
|
+
- ".azure"
|
|
112
|
+
# Kubernetes config
|
|
113
|
+
- ".kube"
|
|
114
|
+
# Docker credentials
|
|
115
|
+
- ".docker"
|
|
116
|
+
blockedExtensions: [".exe", ".dll", ".so", ".dylib"]
|
|
117
|
+
maxFileSize: 10485760 # 10MB
|
|
118
|
+
enableBackups: false
|
|
119
|
+
|
|
120
|
+
# Note: This agent intentionally excludes:
|
|
121
|
+
# - write_file, edit_file (write operations) - not in enabledTools
|
|
122
|
+
# - process-tools (bash execution) - provider not included
|
|
123
|
+
# - agent-spawner (no sub-agent spawning) - provider not included
|
|
124
|
+
# This ensures it remains a safe, read-only exploration tool
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI-specific Approval Handler
|
|
3
|
+
*
|
|
4
|
+
* Creates a manual approval handler that works directly with AgentEventBus
|
|
5
|
+
* for the CLI/TUI mode. Unlike the server's ManualApprovalHandler which uses
|
|
6
|
+
* ApprovalCoordinator for HTTP-based flows, this handler emits events directly
|
|
7
|
+
* to the event bus that the TUI listens to.
|
|
8
|
+
*
|
|
9
|
+
* Flow:
|
|
10
|
+
* 1. Handler emits 'approval:request' → EventBus → TUI shows prompt
|
|
11
|
+
* 2. User responds in TUI → EventBus emits 'approval:response' → Handler resolves
|
|
12
|
+
* 3. For auto-approvals (parallel tools), handler emits 'approval:response' → TUI dismisses
|
|
13
|
+
*/
|
|
14
|
+
import type { ApprovalHandler, AgentEventBus } from '@dexto/core';
|
|
15
|
+
/**
|
|
16
|
+
* Creates a manual approval handler for CLI mode that uses AgentEventBus directly.
|
|
17
|
+
*
|
|
18
|
+
* @param eventBus The agent event bus for request/response communication
|
|
19
|
+
* @returns ApprovalHandler with cancellation and auto-approve support
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const handler = createCLIApprovalHandler(agent.agentEventBus);
|
|
24
|
+
* agent.setApprovalHandler(handler);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function createCLIApprovalHandler(eventBus: AgentEventBus): ApprovalHandler;
|
|
28
|
+
//# sourceMappingURL=cli-approval-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-approval-handler.d.ts","sourceRoot":"","sources":["../../../src/cli/approval/cli-approval-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACR,eAAe,EAGf,aAAa,EAChB,MAAM,aAAa,CAAC;AAGrB;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,aAAa,GAAG,eAAe,CAyJjF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI-specific Approval Handler
|
|
3
|
+
*
|
|
4
|
+
* Creates a manual approval handler that works directly with AgentEventBus
|
|
5
|
+
* for the CLI/TUI mode. Unlike the server's ManualApprovalHandler which uses
|
|
6
|
+
* ApprovalCoordinator for HTTP-based flows, this handler emits events directly
|
|
7
|
+
* to the event bus that the TUI listens to.
|
|
8
|
+
*
|
|
9
|
+
* Flow:
|
|
10
|
+
* 1. Handler emits 'approval:request' → EventBus → TUI shows prompt
|
|
11
|
+
* 2. User responds in TUI → EventBus emits 'approval:response' → Handler resolves
|
|
12
|
+
* 3. For auto-approvals (parallel tools), handler emits 'approval:response' → TUI dismisses
|
|
13
|
+
*/
|
|
14
|
+
import { ApprovalStatus, DenialReason } from '@dexto/core';
|
|
15
|
+
/**
|
|
16
|
+
* Creates a manual approval handler for CLI mode that uses AgentEventBus directly.
|
|
17
|
+
*
|
|
18
|
+
* @param eventBus The agent event bus for request/response communication
|
|
19
|
+
* @returns ApprovalHandler with cancellation and auto-approve support
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const handler = createCLIApprovalHandler(agent.agentEventBus);
|
|
24
|
+
* agent.setApprovalHandler(handler);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export function createCLIApprovalHandler(eventBus) {
|
|
28
|
+
// Track pending approvals for cancellation support
|
|
29
|
+
const pendingApprovals = new Map();
|
|
30
|
+
const handleApproval = (request) => {
|
|
31
|
+
return new Promise((resolve) => {
|
|
32
|
+
// Use per-request timeout (optional - undefined means no timeout)
|
|
33
|
+
const effectiveTimeout = request.timeout;
|
|
34
|
+
// Set timeout timer ONLY if timeout is specified
|
|
35
|
+
let timer;
|
|
36
|
+
if (effectiveTimeout !== undefined) {
|
|
37
|
+
timer = setTimeout(() => {
|
|
38
|
+
cleanup();
|
|
39
|
+
pendingApprovals.delete(request.approvalId);
|
|
40
|
+
// Create timeout response
|
|
41
|
+
const timeoutResponse = {
|
|
42
|
+
approvalId: request.approvalId,
|
|
43
|
+
status: ApprovalStatus.CANCELLED,
|
|
44
|
+
sessionId: request.sessionId,
|
|
45
|
+
reason: DenialReason.TIMEOUT,
|
|
46
|
+
message: `Approval request timed out after ${effectiveTimeout}ms`,
|
|
47
|
+
timeoutMs: effectiveTimeout,
|
|
48
|
+
};
|
|
49
|
+
// Emit timeout response so TUI can dismiss the prompt
|
|
50
|
+
eventBus.emit('approval:response', timeoutResponse);
|
|
51
|
+
resolve(timeoutResponse);
|
|
52
|
+
}, effectiveTimeout);
|
|
53
|
+
}
|
|
54
|
+
// Cleanup function to remove listener and clear timeout
|
|
55
|
+
const controller = new AbortController();
|
|
56
|
+
const cleanup = () => {
|
|
57
|
+
if (timer !== undefined) {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
}
|
|
60
|
+
controller.abort();
|
|
61
|
+
};
|
|
62
|
+
// Listen for approval:response events
|
|
63
|
+
const listener = (res) => {
|
|
64
|
+
// Only handle responses for this specific approval
|
|
65
|
+
if (res.approvalId === request.approvalId) {
|
|
66
|
+
cleanup();
|
|
67
|
+
pendingApprovals.delete(request.approvalId);
|
|
68
|
+
resolve(res);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
// Register listener with abort signal for cleanup
|
|
72
|
+
eventBus.on('approval:response', listener, { signal: controller.signal });
|
|
73
|
+
// Store for cancellation support
|
|
74
|
+
pendingApprovals.set(request.approvalId, {
|
|
75
|
+
cleanup,
|
|
76
|
+
resolve,
|
|
77
|
+
request,
|
|
78
|
+
});
|
|
79
|
+
// Emit the approval:request event for TUI to receive
|
|
80
|
+
eventBus.emit('approval:request', request);
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
const handler = Object.assign(handleApproval, {
|
|
84
|
+
cancel: (approvalId) => {
|
|
85
|
+
const pending = pendingApprovals.get(approvalId);
|
|
86
|
+
if (pending) {
|
|
87
|
+
pending.cleanup();
|
|
88
|
+
pendingApprovals.delete(approvalId);
|
|
89
|
+
// Create cancellation response
|
|
90
|
+
const cancelResponse = {
|
|
91
|
+
approvalId,
|
|
92
|
+
status: ApprovalStatus.CANCELLED,
|
|
93
|
+
sessionId: pending.request.sessionId,
|
|
94
|
+
reason: DenialReason.SYSTEM_CANCELLED,
|
|
95
|
+
message: 'Approval request was cancelled',
|
|
96
|
+
};
|
|
97
|
+
// Emit cancellation event so TUI can dismiss the prompt
|
|
98
|
+
eventBus.emit('approval:response', cancelResponse);
|
|
99
|
+
// Resolve with CANCELLED response
|
|
100
|
+
pending.resolve(cancelResponse);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
cancelAll: () => {
|
|
104
|
+
for (const [approvalId] of pendingApprovals) {
|
|
105
|
+
handler.cancel?.(approvalId);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
getPending: () => {
|
|
109
|
+
return Array.from(pendingApprovals.keys());
|
|
110
|
+
},
|
|
111
|
+
getPendingRequests: () => {
|
|
112
|
+
return Array.from(pendingApprovals.values()).map((p) => p.request);
|
|
113
|
+
},
|
|
114
|
+
/**
|
|
115
|
+
* Auto-approve pending requests that match a predicate.
|
|
116
|
+
* Used when a pattern is remembered to auto-approve other parallel requests
|
|
117
|
+
* that would now match the same pattern.
|
|
118
|
+
*/
|
|
119
|
+
autoApprovePending: (predicate, responseData) => {
|
|
120
|
+
let count = 0;
|
|
121
|
+
// Find all pending approvals that match the predicate
|
|
122
|
+
for (const [approvalId, pending] of pendingApprovals) {
|
|
123
|
+
if (predicate(pending.request)) {
|
|
124
|
+
// Clean up the pending state
|
|
125
|
+
pending.cleanup();
|
|
126
|
+
pendingApprovals.delete(approvalId);
|
|
127
|
+
// Create auto-approval response
|
|
128
|
+
const autoApproveResponse = {
|
|
129
|
+
approvalId,
|
|
130
|
+
status: ApprovalStatus.APPROVED,
|
|
131
|
+
sessionId: pending.request.sessionId,
|
|
132
|
+
message: 'Auto-approved due to matching remembered pattern',
|
|
133
|
+
data: responseData,
|
|
134
|
+
};
|
|
135
|
+
// Emit response so TUI can dismiss the prompt
|
|
136
|
+
eventBus.emit('approval:response', autoApproveResponse);
|
|
137
|
+
// Resolve the pending promise
|
|
138
|
+
pending.resolve(autoApproveResponse);
|
|
139
|
+
count++;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return count;
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
return handler;
|
|
146
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/approval/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { DextoAgent } from '@dexto/core';
|
|
9
9
|
import { EventSubscriber } from '@dexto/server';
|
|
10
10
|
import { AgentEventBus } from '@dexto/core';
|
|
11
|
-
import type { SanitizedToolResult } from '@dexto/core';
|
|
11
|
+
import type { SanitizedToolResult, AgentEventMap } from '@dexto/core';
|
|
12
12
|
/**
|
|
13
13
|
* Event subscriber for CLI headless mode
|
|
14
14
|
* Implements the standard EventSubscriber pattern used throughout the codebase
|
|
@@ -30,6 +30,9 @@ export declare class CLISubscriber implements EventSubscriber {
|
|
|
30
30
|
onResponse(text: string): void;
|
|
31
31
|
onError(error: Error): void;
|
|
32
32
|
onConversationReset(): void;
|
|
33
|
+
onContextCompacting(payload: AgentEventMap['context:compacting']): void;
|
|
34
|
+
onContextCompacted(payload: AgentEventMap['context:compacted']): void;
|
|
35
|
+
onSessionContinued(payload: AgentEventMap['session:continued']): void;
|
|
33
36
|
/**
|
|
34
37
|
* Capture LLM token usage analytics
|
|
35
38
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-subscriber.d.ts","sourceRoot":"","sources":["../../src/cli/cli-subscriber.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAU,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"cli-subscriber.d.ts","sourceRoot":"","sources":["../../src/cli/cli-subscriber.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAU,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtE;;;GAGG;AACH,qBAAa,aAAc,YAAW,eAAe;IACjD,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAa;IACvC,OAAO,CAAC,gBAAgB,CAAC,CAAyB;IAElD,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAgCxC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAcf,UAAU,IAAI,IAAI;IAIlB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3B,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAK9C,YAAY,CACR,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,mBAAmB,EAC9B,SAAS,CAAC,EAAE,OAAO,EACnB,OAAO,CAAC,EAAE,OAAO,GAClB,IAAI;IAMP,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA0B9B,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAyC3B,mBAAmB,IAAI,IAAI;IAM3B,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,oBAAoB,CAAC,GAAG,IAAI;IAOvE,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAcrE,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAAG,IAAI;IAWrE;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;;OAGG;IACG,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBxF"}
|
|
@@ -37,6 +37,9 @@ export class CLISubscriber {
|
|
|
37
37
|
});
|
|
38
38
|
eventBus.on('llm:error', (payload) => this.onError(payload.error));
|
|
39
39
|
eventBus.on('session:reset', this.onConversationReset.bind(this));
|
|
40
|
+
eventBus.on('context:compacting', this.onContextCompacting.bind(this));
|
|
41
|
+
eventBus.on('context:compacted', this.onContextCompacted.bind(this));
|
|
42
|
+
eventBus.on('session:continued', this.onSessionContinued.bind(this));
|
|
40
43
|
}
|
|
41
44
|
/**
|
|
42
45
|
* Clean up internal state
|
|
@@ -134,14 +137,39 @@ export class CLISubscriber {
|
|
|
134
137
|
this.streamingContent = '';
|
|
135
138
|
logger.info('🔄 Conversation history cleared.', null, 'blue');
|
|
136
139
|
}
|
|
140
|
+
onContextCompacting(payload) {
|
|
141
|
+
// Output to stderr (doesn't interfere with stdout response stream)
|
|
142
|
+
process.stderr.write(`[📦 Compacting context (~${payload.estimatedTokens.toLocaleString()} tokens)...]\n`);
|
|
143
|
+
}
|
|
144
|
+
onContextCompacted(payload) {
|
|
145
|
+
const { originalTokens, compactedTokens, originalMessages, compactedMessages, reason } = payload;
|
|
146
|
+
const reductionPercent = originalTokens > 0
|
|
147
|
+
? Math.round(((originalTokens - compactedTokens) / originalTokens) * 100)
|
|
148
|
+
: 0;
|
|
149
|
+
// Output to stderr (doesn't interfere with stdout response stream)
|
|
150
|
+
process.stderr.write(`[📦 Context compacted (${reason}): ${originalTokens.toLocaleString()} → ~${compactedTokens.toLocaleString()} tokens (${reductionPercent}% reduction), ${originalMessages} → ${compactedMessages} messages]\n`);
|
|
151
|
+
}
|
|
152
|
+
onSessionContinued(payload) {
|
|
153
|
+
const { previousSessionId, newSessionId, summaryTokens, originalMessages, reason } = payload;
|
|
154
|
+
// Output to stderr (doesn't interfere with stdout response stream)
|
|
155
|
+
process.stderr.write(`[📦 Context compacted → Continuing in new session\n` +
|
|
156
|
+
` ${previousSessionId.slice(0, 8)}... → ${newSessionId.slice(0, 8)}...\n` +
|
|
157
|
+
` ${originalMessages} messages → ~${summaryTokens.toLocaleString()} token summary (${reason})]\n`);
|
|
158
|
+
}
|
|
137
159
|
/**
|
|
138
160
|
* Capture LLM token usage analytics
|
|
139
161
|
*/
|
|
140
162
|
captureTokenUsage(payload) {
|
|
141
|
-
const { tokenUsage, provider, model, sessionId } = payload;
|
|
163
|
+
const { tokenUsage, provider, model, sessionId, estimatedInputTokens } = payload;
|
|
142
164
|
if (!tokenUsage || (!tokenUsage.inputTokens && !tokenUsage.outputTokens)) {
|
|
143
165
|
return;
|
|
144
166
|
}
|
|
167
|
+
// Calculate estimate accuracy if both estimate and actual are available
|
|
168
|
+
let estimateAccuracyPercent;
|
|
169
|
+
if (estimatedInputTokens !== undefined && tokenUsage.inputTokens) {
|
|
170
|
+
const diff = estimatedInputTokens - tokenUsage.inputTokens;
|
|
171
|
+
estimateAccuracyPercent = Math.round((diff / tokenUsage.inputTokens) * 100);
|
|
172
|
+
}
|
|
145
173
|
capture('dexto_llm_tokens_consumed', {
|
|
146
174
|
source: 'cli',
|
|
147
175
|
sessionId,
|
|
@@ -153,6 +181,8 @@ export class CLISubscriber {
|
|
|
153
181
|
totalTokens: tokenUsage.totalTokens,
|
|
154
182
|
cacheReadTokens: tokenUsage.cacheReadTokens,
|
|
155
183
|
cacheWriteTokens: tokenUsage.cacheWriteTokens,
|
|
184
|
+
estimatedInputTokens,
|
|
185
|
+
estimateAccuracyPercent,
|
|
156
186
|
});
|
|
157
187
|
}
|
|
158
188
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAYnF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,EAAE,iBAAiB,EAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAYnF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,EAAE,iBAAiB,EAAO,CAAC;AAsCpD;;;;;GAKG;AACH,wBAAsB,cAAc,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAyD/B;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,iBAAiB,EAAE,CAEpD"}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
// Import modular command definitions
|
|
22
22
|
import { generalCommands, createHelpCommand } from './general-commands.js';
|
|
23
|
-
import { searchCommand, resumeCommand } from './session/index.js';
|
|
23
|
+
import { searchCommand, resumeCommand, renameCommand } from './session/index.js';
|
|
24
24
|
import { modelCommands } from './model/index.js';
|
|
25
25
|
import { mcpCommands } from './mcp/index.js';
|
|
26
26
|
import { systemCommands } from './system/index.js';
|
|
@@ -51,6 +51,7 @@ const baseCommands = [
|
|
|
51
51
|
// Session management
|
|
52
52
|
searchCommand, // /search - opens search overlay
|
|
53
53
|
resumeCommand, // /resume - opens session selector overlay
|
|
54
|
+
renameCommand, // /rename <title> - rename current session
|
|
54
55
|
// Model management
|
|
55
56
|
modelCommands, // /model - opens model selector overlay
|
|
56
57
|
// MCP server management
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general-commands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/general-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAwC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"general-commands.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/interactive-commands/general-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAwC,MAAM,qBAAqB,CAAC;AAgGnG;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,iBAAiB,EAAE,GAAG,iBAAiB,CAgC9F;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,iBAAiB,EA8X9C,CAAC"}
|