aegiscode 3.1.10 → 3.4.2
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/bin/aegis.js +165 -0
- package/package.json +18 -86
- package/LICENSE +0 -21
- package/README.md +0 -394
- package/dist/main.js +0 -2171
- package/gui/run-gui.cjs +0 -13
- package/src/agent/Agent.ts +0 -903
- package/src/agent/SimpleAgent.ts +0 -48
- package/src/agent/index.ts +0 -54
- package/src/agent/orchestrator/AppBuilder.ts +0 -443
- package/src/agent/orchestrator/CouncilAgent.ts +0 -310
- package/src/agent/orchestrator/DiscussionRoom.ts +0 -462
- package/src/agent/orchestrator/OrchestratorAgent.ts +0 -637
- package/src/agent/orchestrator/index.ts +0 -38
- package/src/agent/orchestrator/utils.ts +0 -397
- package/src/agent/pricing.ts +0 -115
- package/src/agent/router.ts +0 -74
- package/src/agent/routerStats.ts +0 -121
- package/src/agent/types.ts +0 -318
- package/src/auth/login.ts +0 -383
- package/src/cli/config.ts +0 -189
- package/src/cli/index.ts +0 -17
- package/src/cli/middleware.ts +0 -119
- package/src/cli/types.ts +0 -75
- package/src/config/ConfigManager.ts +0 -587
- package/src/config/index.ts +0 -7
- package/src/config/types.ts +0 -584
- package/src/context/CompactionService.ts +0 -300
- package/src/context/ContextManager.ts +0 -450
- package/src/context/FileAnalyzer.ts +0 -267
- package/src/context/TokenCounter.ts +0 -265
- package/src/context/index.ts +0 -27
- package/src/context/storage/CacheStore.ts +0 -176
- package/src/context/storage/JSONLStore.ts +0 -201
- package/src/context/storage/MemoryStore.ts +0 -205
- package/src/context/storage/PersistentStore.ts +0 -327
- package/src/context/storage/index.ts +0 -9
- package/src/context/storage/pathUtils.ts +0 -114
- package/src/context/test.ts +0 -309
- package/src/context/types.ts +0 -268
- package/src/hooks/HookExecutor.ts +0 -434
- package/src/hooks/HookManager.ts +0 -596
- package/src/hooks/HookService.ts +0 -269
- package/src/hooks/Matcher.ts +0 -157
- package/src/hooks/index.ts +0 -63
- package/src/hooks/types.ts +0 -424
- package/src/main.tsx +0 -596
- package/src/mcp/HealthMonitor.ts +0 -150
- package/src/mcp/McpClient.ts +0 -491
- package/src/mcp/McpRegistry.ts +0 -321
- package/src/mcp/createMcpTool.ts +0 -251
- package/src/mcp/index.ts +0 -15
- package/src/mcp/server.ts +0 -334
- package/src/mcp/test-server.ts +0 -88
- package/src/mcp/test.ts +0 -372
- package/src/mcp/types.ts +0 -247
- package/src/memory/AgentMemoryBus.ts +0 -432
- package/src/memory/CloudSync.ts +0 -99
- package/src/memory/DriveSync.ts +0 -106
- package/src/memory/SharedMemory.ts +0 -951
- package/src/memory/index.ts +0 -14
- package/src/memory/machineFingerprint.ts +0 -40
- package/src/orchestrator/SubAgentMetadata.ts +0 -136
- package/src/prompts/builder.ts +0 -213
- package/src/prompts/default.ts +0 -144
- package/src/prompts/index.ts +0 -16
- package/src/prompts/plan.ts +0 -64
- package/src/prompts/test.ts +0 -78
- package/src/services/AnthropicChatService.ts +0 -341
- package/src/services/ChatService.ts +0 -347
- package/src/services/ClaudeCliChatService.ts +0 -256
- package/src/services/CloudSync.ts +0 -168
- package/src/services/CostLedger.ts +0 -211
- package/src/services/Heartbeat.ts +0 -135
- package/src/services/LearningCollector.ts +0 -291
- package/src/services/OllamaInstaller.ts +0 -342
- package/src/services/VersionChecker.ts +0 -445
- package/src/services/index.ts +0 -57
- package/src/services/streaming/OpenAIEventAdapter.ts +0 -126
- package/src/services/streaming/RenderingProfile.ts +0 -90
- package/src/services/streaming/StreamEventParser.ts +0 -181
- package/src/services/streaming/ThrottledRenderer.ts +0 -139
- package/src/services/streaming/TranscriptBuffer.ts +0 -574
- package/src/services/streaming/eventStatusMap.ts +0 -52
- package/src/services/streaming/index.ts +0 -46
- package/src/services/streaming/renderFormatting.ts +0 -79
- package/src/services/streaming/types.ts +0 -234
- package/src/skills/SkillLoader.ts +0 -126
- package/src/skills/SkillRegistry.ts +0 -366
- package/src/skills/index.ts +0 -48
- package/src/skills/types.ts +0 -146
- package/src/slash-commands/billing.ts +0 -70
- package/src/slash-commands/build.ts +0 -413
- package/src/slash-commands/builtinCommands.ts +0 -2733
- package/src/slash-commands/clone.ts +0 -242
- package/src/slash-commands/council.ts +0 -125
- package/src/slash-commands/custom/CustomCommandExecutor.ts +0 -143
- package/src/slash-commands/custom/CustomCommandLoader.ts +0 -251
- package/src/slash-commands/custom/CustomCommandRegistry.ts +0 -144
- package/src/slash-commands/custom/index.ts +0 -7
- package/src/slash-commands/debate.ts +0 -254
- package/src/slash-commands/gmail.ts +0 -105
- package/src/slash-commands/index.ts +0 -388
- package/src/slash-commands/mcpCommand.ts +0 -205
- package/src/slash-commands/types.ts +0 -201
- package/src/store/index.ts +0 -76
- package/src/store/selectors.ts +0 -246
- package/src/store/slices/appSlice.ts +0 -205
- package/src/store/slices/commandSlice.ts +0 -115
- package/src/store/slices/configSlice.ts +0 -46
- package/src/store/slices/focusSlice.ts +0 -64
- package/src/store/slices/index.ts +0 -9
- package/src/store/slices/sessionSlice.ts +0 -424
- package/src/store/streaming-buffer.ts +0 -425
- package/src/store/test.ts +0 -296
- package/src/store/types.ts +0 -274
- package/src/store/vanilla.ts +0 -186
- package/src/tools/builtin/bash.ts +0 -236
- package/src/tools/builtin/council.ts +0 -105
- package/src/tools/builtin/edit.ts +0 -213
- package/src/tools/builtin/glob.ts +0 -136
- package/src/tools/builtin/grep.ts +0 -263
- package/src/tools/builtin/index.ts +0 -61
- package/src/tools/builtin/memory.ts +0 -66
- package/src/tools/builtin/read.ts +0 -168
- package/src/tools/builtin/skill.ts +0 -97
- package/src/tools/builtin/snapshot.ts +0 -40
- package/src/tools/builtin/task.ts +0 -106
- package/src/tools/builtin/write.ts +0 -134
- package/src/tools/createTool.ts +0 -221
- package/src/tools/execution/ExecutionPipeline.ts +0 -263
- package/src/tools/execution/index.ts +0 -40
- package/src/tools/execution/stages/CacheStage.ts +0 -131
- package/src/tools/execution/stages/ConfirmationStage.ts +0 -203
- package/src/tools/execution/stages/DiscoveryStage.ts +0 -46
- package/src/tools/execution/stages/ExecutionStage.ts +0 -48
- package/src/tools/execution/stages/FormattingStage.ts +0 -44
- package/src/tools/execution/stages/HookStage.ts +0 -72
- package/src/tools/execution/stages/PermissionStage.ts +0 -287
- package/src/tools/execution/stages/PostHookStage.ts +0 -71
- package/src/tools/execution/stages/index.ts +0 -12
- package/src/tools/execution/test.ts +0 -266
- package/src/tools/execution/types.ts +0 -273
- package/src/tools/index.ts +0 -81
- package/src/tools/registry.ts +0 -304
- package/src/tools/schemas.ts +0 -109
- package/src/tools/test.ts +0 -220
- package/src/tools/types.ts +0 -175
- package/src/tools/validation/PermissionChecker.ts +0 -242
- package/src/tools/validation/SensitiveFileDetector.ts +0 -210
- package/src/tools/validation/index.ts +0 -11
- package/src/ui/App.tsx +0 -166
- package/src/ui/components/AegisInterface.tsx +0 -484
- package/src/ui/components/common/ChatSearch.tsx +0 -150
- package/src/ui/components/common/ErrorBoundary.tsx +0 -82
- package/src/ui/components/common/ExitMessage.tsx +0 -120
- package/src/ui/components/common/LoadingIndicator.tsx +0 -49
- package/src/ui/components/common/index.ts +0 -6
- package/src/ui/components/dialog/ConfirmationPrompt.tsx +0 -208
- package/src/ui/components/dialog/InteractiveSelector.tsx +0 -149
- package/src/ui/components/dialog/SetupWizard.tsx +0 -297
- package/src/ui/components/dialog/UpdatePrompt.tsx +0 -155
- package/src/ui/components/dialog/index.ts +0 -8
- package/src/ui/components/index.ts +0 -28
- package/src/ui/components/input/CommandSuggestions.tsx +0 -139
- package/src/ui/components/input/CustomTextInput.tsx +0 -220
- package/src/ui/components/input/InputArea.tsx +0 -361
- package/src/ui/components/input/PromptSuggestions.tsx +0 -66
- package/src/ui/components/input/index.ts +0 -6
- package/src/ui/components/layout/ChatStatusBar.tsx +0 -90
- package/src/ui/components/layout/ContextBar.tsx +0 -79
- package/src/ui/components/layout/MessageArea.tsx +0 -96
- package/src/ui/components/layout/MessageList.tsx +0 -647
- package/src/ui/components/layout/MessageSeparator.tsx +0 -26
- package/src/ui/components/layout/WelcomeMessage.tsx +0 -93
- package/src/ui/components/layout/index.ts +0 -7
- package/src/ui/components/markdown/CodeHighlighter.tsx +0 -292
- package/src/ui/components/markdown/MessageRenderer.tsx +0 -1211
- package/src/ui/components/markdown/index.ts +0 -8
- package/src/ui/components/markdown/parser.ts +0 -336
- package/src/ui/components/markdown/types.ts +0 -66
- package/src/ui/focus/FocusManager.ts +0 -137
- package/src/ui/focus/index.ts +0 -13
- package/src/ui/focus/types.ts +0 -54
- package/src/ui/focus/useFocus.ts +0 -75
- package/src/ui/hooks/index.ts +0 -11
- package/src/ui/hooks/useAgent.ts +0 -284
- package/src/ui/hooks/useCommandHistory.ts +0 -87
- package/src/ui/hooks/useCommandProcessor.ts +0 -443
- package/src/ui/hooks/useConfirmation.ts +0 -99
- package/src/ui/hooks/useCtrlCHandler.ts +0 -100
- package/src/ui/hooks/useInputBuffer.ts +0 -122
- package/src/ui/hooks/useTerminalSize.ts +0 -68
- package/src/ui/hooks/useTerminalWidth.ts +0 -5
- package/src/ui/hooks/useWindowedList.ts +0 -118
- package/src/ui/render-debugger.ts +0 -621
- package/src/ui/test.ts +0 -189
- package/src/ui/themes/ThemeManager.ts +0 -332
- package/src/ui/themes/aegisTheme.ts +0 -87
- package/src/ui/themes/darkTheme.ts +0 -87
- package/src/ui/themes/defaultTheme.ts +0 -85
- package/src/ui/themes/index.ts +0 -10
- package/src/ui/themes/lightTheme.ts +0 -89
- package/src/ui/themes/popularThemes.ts +0 -187
- package/src/ui/themes/types.ts +0 -130
- package/src/utils/clipboard.ts +0 -48
- package/src/utils/debug.ts +0 -43
- package/src/utils/environment.ts +0 -68
- package/src/utils/index.ts +0 -10
package/src/tools/createTool.ts
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { z } from 'zod';
|
|
8
|
-
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
9
|
-
import {
|
|
10
|
-
ToolErrorType,
|
|
11
|
-
type Tool,
|
|
12
|
-
type ToolKind,
|
|
13
|
-
type ToolDescription,
|
|
14
|
-
type ToolResult,
|
|
15
|
-
type ExecutionContext,
|
|
16
|
-
type FunctionDeclaration,
|
|
17
|
-
type ToolInvocation,
|
|
18
|
-
} from './types.js';
|
|
19
|
-
|
|
20
|
-
// ========== 配置类
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
*/
|
|
25
|
-
export interface ToolConfig<TSchema extends z.ZodType> {
|
|
26
|
-
/** 工具唯一名称 */
|
|
27
|
-
name: string;
|
|
28
|
-
/** 显示名称 */
|
|
29
|
-
displayName?: string;
|
|
30
|
-
/** 工具类型 */
|
|
31
|
-
kind: ToolKind;
|
|
32
|
-
/** 参数 Schema */
|
|
33
|
-
schema: TSchema;
|
|
34
|
-
/** 工具描述 */
|
|
35
|
-
description: ToolDescription;
|
|
36
|
-
/** 执行函数 */
|
|
37
|
-
execute: (
|
|
38
|
-
params: z.infer<TSchema>,
|
|
39
|
-
context?: ExecutionContext
|
|
40
|
-
) => Promise<ToolResult>;
|
|
41
|
-
/** 版本 */
|
|
42
|
-
version?: string;
|
|
43
|
-
/** 分类 */
|
|
44
|
-
category?: string;
|
|
45
|
-
/** 标签 */
|
|
46
|
-
tags?: string[];
|
|
47
|
-
/** 是否只读(默认根据 kind 推断) */
|
|
48
|
-
isReadOnly?: boolean;
|
|
49
|
-
/** 是否并发安全(默认 true) */
|
|
50
|
-
isConcurrencySafe?: boolean;
|
|
51
|
-
/** 是否启用结构化输出(默认 false) */
|
|
52
|
-
strict?: boolean;
|
|
53
|
-
/** 提取签名内容(用于权限规则) */
|
|
54
|
-
extractSignatureContent?: (params: unknown) => string;
|
|
55
|
-
/** 抽象权限规则(用于权限匹配) */
|
|
56
|
-
abstractPermissionRule?: (params: unknown) => string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// ========== 工厂函
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* ```typescript
|
|
66
|
-
* const readTool = createTool({
|
|
67
|
-
* name: 'Read',
|
|
68
|
-
* kind: ToolKind.ReadOnly,
|
|
69
|
-
* schema: z.object({
|
|
70
|
-
* file_path: z.string(),
|
|
71
|
-
* }),
|
|
72
|
-
* description: { short: 'Read files' },
|
|
73
|
-
* execute: async (params) => {
|
|
74
|
-
* // ...
|
|
75
|
-
* },
|
|
76
|
-
* });
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export function createTool<TSchema extends z.ZodType>(
|
|
80
|
-
config: ToolConfig<TSchema>
|
|
81
|
-
): Tool<z.infer<TSchema>> {
|
|
82
|
-
const {
|
|
83
|
-
name,
|
|
84
|
-
displayName,
|
|
85
|
-
kind,
|
|
86
|
-
schema,
|
|
87
|
-
description,
|
|
88
|
-
execute,
|
|
89
|
-
version = '1.0.0',
|
|
90
|
-
category,
|
|
91
|
-
tags = [],
|
|
92
|
-
isReadOnly,
|
|
93
|
-
isConcurrencySafe = true,
|
|
94
|
-
strict = false,
|
|
95
|
-
extractSignatureContent,
|
|
96
|
-
abstractPermissionRule,
|
|
97
|
-
} = config;
|
|
98
|
-
|
|
99
|
-
// 从 Zod Schema 生
|
|
100
|
-
const jsonSchema = zodToJsonSchema(schema, {
|
|
101
|
-
$refStrategy: 'none',
|
|
102
|
-
target: 'openApi3',
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// 提取 properties
|
|
106
|
-
const schemaObj = jsonSchema as {
|
|
107
|
-
type?: string;
|
|
108
|
-
properties?: Record<string, unknown>;
|
|
109
|
-
required?: string[];
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
name,
|
|
114
|
-
displayName: displayName || name,
|
|
115
|
-
kind,
|
|
116
|
-
isReadOnly: isReadOnly ?? kind === 'readonly',
|
|
117
|
-
isConcurrencySafe,
|
|
118
|
-
strict,
|
|
119
|
-
description,
|
|
120
|
-
version,
|
|
121
|
-
category,
|
|
122
|
-
tags,
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
*
|
|
126
|
-
*/
|
|
127
|
-
getFunctionDeclaration(): FunctionDeclaration {
|
|
128
|
-
return {
|
|
129
|
-
name,
|
|
130
|
-
description: buildFullDescription(description),
|
|
131
|
-
parameters: {
|
|
132
|
-
type: 'object',
|
|
133
|
-
properties: schemaObj.properties || {},
|
|
134
|
-
required: schemaObj.required,
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
},
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
*
|
|
141
|
-
*/
|
|
142
|
-
build(params: z.infer<TSchema>): ToolInvocation<z.infer<TSchema>> {
|
|
143
|
-
return {
|
|
144
|
-
toolName: name,
|
|
145
|
-
params,
|
|
146
|
-
};
|
|
147
|
-
},
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
*
|
|
151
|
-
*/
|
|
152
|
-
async execute(
|
|
153
|
-
params: z.infer<TSchema>,
|
|
154
|
-
context?: ExecutionContext
|
|
155
|
-
): Promise<ToolResult> {
|
|
156
|
-
try {
|
|
157
|
-
// 验证参
|
|
158
|
-
const validated = schema.parse(params);
|
|
159
|
-
// 执行工
|
|
160
|
-
return await execute(validated, context);
|
|
161
|
-
} catch (error) {
|
|
162
|
-
// 处理 Zod 验证错
|
|
163
|
-
if (error instanceof z.ZodError) {
|
|
164
|
-
const messages = error.errors.map(e =>
|
|
165
|
-
`${e.path.join('.')}: ${e.message}`
|
|
166
|
-
).join('; ');
|
|
167
|
-
|
|
168
|
-
return {
|
|
169
|
-
success: false,
|
|
170
|
-
llmContent: `Parameter validation failed: ${messages}`,
|
|
171
|
-
displayContent: `❌ 参数验证失败: ${messages}`,
|
|
172
|
-
error: {
|
|
173
|
-
type: ToolErrorType.VALIDATION_ERROR,
|
|
174
|
-
message: messages,
|
|
175
|
-
details: error.errors,
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// 处理其他错
|
|
181
|
-
const errorMessage = error instanceof Error ? error.message : '未知错误';
|
|
182
|
-
return {
|
|
183
|
-
success: false,
|
|
184
|
-
llmContent: `Tool execution failed: ${errorMessage}`,
|
|
185
|
-
displayContent: `❌ 执行失败: ${errorMessage}`,
|
|
186
|
-
error: {
|
|
187
|
-
type: ToolErrorType.EXECUTION_ERROR,
|
|
188
|
-
message: errorMessage,
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
// 可选方
|
|
195
|
-
extractSignatureContent,
|
|
196
|
-
abstractPermissionRule,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
*
|
|
202
|
-
*/
|
|
203
|
-
function buildFullDescription(desc: ToolDescription): string {
|
|
204
|
-
const parts: string[] = [desc.short];
|
|
205
|
-
|
|
206
|
-
if (desc.long) {
|
|
207
|
-
parts.push(desc.long);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (desc.usageNotes && desc.usageNotes.length > 0) {
|
|
211
|
-
parts.push('\nUsage notes:');
|
|
212
|
-
parts.push(...desc.usageNotes.map(note => `- ${note}`));
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (desc.important && desc.important.length > 0) {
|
|
216
|
-
parts.push('\nIMPORTANT:');
|
|
217
|
-
parts.push(...desc.important.map(note => `- ${note}`));
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return parts.join('\n');
|
|
221
|
-
}
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ExecutionPipeline - 执行管道
|
|
3
|
-
*
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
ToolExecution,
|
|
8
|
-
PermissionMode,
|
|
9
|
-
type PipelineStage,
|
|
10
|
-
type PipelineExecutionContext,
|
|
11
|
-
type ExecutionPipelineConfig,
|
|
12
|
-
type ExecutionHistoryEntry,
|
|
13
|
-
type StageStartEvent,
|
|
14
|
-
type StageCompleteEvent,
|
|
15
|
-
} from './types.js';
|
|
16
|
-
import type { ToolResult, ToolErrorType } from '../types.js';
|
|
17
|
-
import type { ToolRegistry } from '../registry.js';
|
|
18
|
-
import {
|
|
19
|
-
DiscoveryStage,
|
|
20
|
-
CacheStage,
|
|
21
|
-
PermissionStage,
|
|
22
|
-
HookStage,
|
|
23
|
-
ConfirmationStage,
|
|
24
|
-
ExecutionStage,
|
|
25
|
-
PostHookStage,
|
|
26
|
-
FormattingStage,
|
|
27
|
-
} from './stages/index.js';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
*
|
|
31
|
-
*/
|
|
32
|
-
export interface ExecutionPipelineEvents {
|
|
33
|
-
stageStart: (event: StageStartEvent) => void;
|
|
34
|
-
stageComplete: (event: StageCompleteEvent) => void;
|
|
35
|
-
executionStart: (execution: ToolExecution) => void;
|
|
36
|
-
executionComplete: (execution: ToolExecution, result: ToolResult) => void;
|
|
37
|
-
executionError: (execution: ToolExecution, error: Error) => void;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
*/
|
|
43
|
-
export class ExecutionPipeline {
|
|
44
|
-
private stages: PipelineStage[];
|
|
45
|
-
private cacheStage: CacheStage;
|
|
46
|
-
private executionHistory: ExecutionHistoryEntry[] = [];
|
|
47
|
-
private readonly sessionApprovals = new Set<string>();
|
|
48
|
-
private readonly sessionDenials = new Set<string>();
|
|
49
|
-
private readonly maxHistorySize = 1000;
|
|
50
|
-
|
|
51
|
-
constructor(
|
|
52
|
-
private registry: ToolRegistry,
|
|
53
|
-
config: ExecutionPipelineConfig = {}
|
|
54
|
-
) {
|
|
55
|
-
|
|
56
|
-
const defaultMode = config.defaultMode || PermissionMode.DEFAULT;
|
|
57
|
-
this.cacheStage = new CacheStage();
|
|
58
|
-
|
|
59
|
-
// 初始化八个执行阶
|
|
60
|
-
this.stages = [
|
|
61
|
-
new DiscoveryStage(this.registry, config.allowedTools, config.disallowedTools),
|
|
62
|
-
this.cacheStage,
|
|
63
|
-
new PermissionStage(config.permissions, this.sessionApprovals, this.sessionDenials, defaultMode),
|
|
64
|
-
new HookStage(),
|
|
65
|
-
new ConfirmationStage(this.sessionApprovals, this.sessionDenials),
|
|
66
|
-
new ExecutionStage(this.cacheStage),
|
|
67
|
-
new PostHookStage(),
|
|
68
|
-
new FormattingStage(),
|
|
69
|
-
];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
*/
|
|
75
|
-
async execute(
|
|
76
|
-
toolName: string,
|
|
77
|
-
params: Record<string, unknown>,
|
|
78
|
-
context: PipelineExecutionContext
|
|
79
|
-
): Promise<ToolResult> {
|
|
80
|
-
const startTime = Date.now();
|
|
81
|
-
const executedStages: string[] = [];
|
|
82
|
-
|
|
83
|
-
// 创建执行实
|
|
84
|
-
const execution = new ToolExecution(toolName, params, context);
|
|
85
|
-
|
|
86
|
-
// 发出执行开始事
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
// 依次执行各阶
|
|
90
|
-
for (const stage of this.stages) {
|
|
91
|
-
if (execution.isAborted()) {
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// 发出阶段开始事
|
|
96
|
-
|
|
97
|
-
// 执行阶
|
|
98
|
-
await stage.process(execution);
|
|
99
|
-
|
|
100
|
-
// 记录已执行的阶
|
|
101
|
-
executedStages.push(stage.name);
|
|
102
|
-
|
|
103
|
-
// 发出阶段完成事
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 获取或创建结
|
|
107
|
-
const result = execution.getResult() || this.createErrorResult(execution);
|
|
108
|
-
|
|
109
|
-
// 记录执行历
|
|
110
|
-
this.recordExecution({
|
|
111
|
-
toolName,
|
|
112
|
-
params,
|
|
113
|
-
result,
|
|
114
|
-
timestamp: startTime,
|
|
115
|
-
duration: Date.now() - startTime,
|
|
116
|
-
permissionMode: context.permissionMode,
|
|
117
|
-
stages: executedStages,
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
// 发出执行完成事
|
|
121
|
-
|
|
122
|
-
return result;
|
|
123
|
-
} catch (error) {
|
|
124
|
-
// 发出执行错误事
|
|
125
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
126
|
-
|
|
127
|
-
// 返回错误结
|
|
128
|
-
return {
|
|
129
|
-
success: false,
|
|
130
|
-
llmContent: `Pipeline execution error: ${err.message}`,
|
|
131
|
-
displayContent: `❌ Pipeline error: ${err.message}`,
|
|
132
|
-
error: {
|
|
133
|
-
type: 'execution_error' as ToolErrorType,
|
|
134
|
-
message: err.message,
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
*
|
|
142
|
-
*/
|
|
143
|
-
private createErrorResult(execution: ToolExecution): ToolResult {
|
|
144
|
-
const reason = execution.getAbortReason() || 'Unknown error';
|
|
145
|
-
return {
|
|
146
|
-
success: false,
|
|
147
|
-
llmContent: `Tool execution aborted: ${reason}`,
|
|
148
|
-
displayContent: `❌ ${execution.toolName}: ${reason}`,
|
|
149
|
-
error: {
|
|
150
|
-
type: 'execution_error' as ToolErrorType,
|
|
151
|
-
message: reason,
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
*
|
|
158
|
-
*/
|
|
159
|
-
private recordExecution(entry: ExecutionHistoryEntry): void {
|
|
160
|
-
this.executionHistory.push(entry);
|
|
161
|
-
|
|
162
|
-
// 限制历史大
|
|
163
|
-
if (this.executionHistory.length > this.maxHistorySize) {
|
|
164
|
-
this.executionHistory.shift();
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
*
|
|
170
|
-
*/
|
|
171
|
-
getRegistry(): ToolRegistry {
|
|
172
|
-
return this.registry;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
*
|
|
177
|
-
*/
|
|
178
|
-
getHistory(): ExecutionHistoryEntry[] {
|
|
179
|
-
return [...this.executionHistory];
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
*
|
|
184
|
-
*/
|
|
185
|
-
clearHistory(): void {
|
|
186
|
-
this.executionHistory = [];
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
*
|
|
191
|
-
*/
|
|
192
|
-
getSessionApprovals(): Set<string> {
|
|
193
|
-
return new Set(this.sessionApprovals);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
*
|
|
198
|
-
*/
|
|
199
|
-
clearSessionApprovals(): void {
|
|
200
|
-
this.sessionApprovals.clear();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
*
|
|
205
|
-
*/
|
|
206
|
-
addSessionApproval(signature: string): void {
|
|
207
|
-
this.sessionApprovals.add(signature);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
*
|
|
212
|
-
*/
|
|
213
|
-
hasSessionApproval(signature: string): boolean {
|
|
214
|
-
return this.sessionApprovals.has(signature);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// ==================== Session Denials ====================
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
*
|
|
221
|
-
*/
|
|
222
|
-
getSessionDenials(): Set<string> {
|
|
223
|
-
return new Set(this.sessionDenials);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
*
|
|
228
|
-
*/
|
|
229
|
-
clearSessionDenials(): void {
|
|
230
|
-
this.sessionDenials.clear();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
*
|
|
235
|
-
*/
|
|
236
|
-
addSessionDenial(signature: string): void {
|
|
237
|
-
this.sessionDenials.add(signature);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
*
|
|
242
|
-
*/
|
|
243
|
-
hasSessionDenial(signature: string): boolean {
|
|
244
|
-
return this.sessionDenials.has(signature);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
*
|
|
249
|
-
*/
|
|
250
|
-
getStageNames(): string[] {
|
|
251
|
-
return this.stages.map(s => s.name);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/** Stats for the session-scoped Read/Grep/Glob result cache */
|
|
255
|
-
getCacheStats(): { size: number; maxSize: number } {
|
|
256
|
-
return this.cacheStage.stats();
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/** Clear cached entries for a specific session */
|
|
260
|
-
clearSessionCache(sessionId: string): void {
|
|
261
|
-
this.cacheStage.clearSession(sessionId);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// 类
|
|
6
|
-
export {
|
|
7
|
-
PermissionMode,
|
|
8
|
-
PermissionResult,
|
|
9
|
-
ToolExecution,
|
|
10
|
-
type PipelineStage,
|
|
11
|
-
type PipelineExecutionContext,
|
|
12
|
-
type ExecutionPipelineConfig,
|
|
13
|
-
type ExecutionHistoryEntry,
|
|
14
|
-
type PermissionCheckResult,
|
|
15
|
-
type PermissionConfig,
|
|
16
|
-
type ToolInvocationDescriptor,
|
|
17
|
-
type ConfirmationDetails,
|
|
18
|
-
type ConfirmationResponse,
|
|
19
|
-
type ConfirmationHandler,
|
|
20
|
-
type ToolProgress,
|
|
21
|
-
type PreToolHookResult,
|
|
22
|
-
type PostToolHookParams,
|
|
23
|
-
type StageStartEvent,
|
|
24
|
-
type StageCompleteEvent,
|
|
25
|
-
} from './types.js';
|
|
26
|
-
|
|
27
|
-
// 主
|
|
28
|
-
export { ExecutionPipeline, type ExecutionPipelineEvents } from './ExecutionPipeline.js';
|
|
29
|
-
|
|
30
|
-
// 阶
|
|
31
|
-
export {
|
|
32
|
-
DiscoveryStage,
|
|
33
|
-
CacheStage,
|
|
34
|
-
PermissionStage,
|
|
35
|
-
HookStage,
|
|
36
|
-
ConfirmationStage,
|
|
37
|
-
ExecutionStage,
|
|
38
|
-
PostHookStage,
|
|
39
|
-
FormattingStage,
|
|
40
|
-
} from './stages/index.js';
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CacheStage — session-scoped tool result caching
|
|
3
|
-
*
|
|
4
|
-
* Caches results from read-only tools (Read, Grep, Glob) so that re-requesting
|
|
5
|
-
* the same file / same glob / same grep within the same session does not re-execute
|
|
6
|
-
* the tool. The result is injected directly into the ToolExecution object, allowing
|
|
7
|
-
* the pipeline to short-circuit.
|
|
8
|
-
*
|
|
9
|
-
* Design parallels Claude Code's `tool-results/` directory per session UUID.
|
|
10
|
-
*
|
|
11
|
-
* Key decisions:
|
|
12
|
-
* - Cache key = SHA-256 hash of (toolName + sorted-JSON(params) + sessionId)
|
|
13
|
-
* - Only caches SUCCESSFUL results from read-only tools
|
|
14
|
-
* - Cache is in-memory (Map) + optionally persisted to disk
|
|
15
|
-
* - TTL = session lifetime (cleared when session ends or cache is purged)
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
import * as crypto from 'node:crypto';
|
|
19
|
-
import type { ToolResult } from '../../types.js';
|
|
20
|
-
import type { PipelineStage, ToolExecution } from '../types.js';
|
|
21
|
-
|
|
22
|
-
// ── Types ────────────────────────────────────────────────────────────────────
|
|
23
|
-
|
|
24
|
-
export interface CacheEntry {
|
|
25
|
-
result: ToolResult;
|
|
26
|
-
cachedAt: number;
|
|
27
|
-
hitCount: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface CacheStageOptions {
|
|
31
|
-
/** Maximum cache entries (default 500) */
|
|
32
|
-
maxSize?: number;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ── Read-only tool names that are safe to cache ──────────────────────────────
|
|
36
|
-
|
|
37
|
-
const READONLY_TOOLS = new Set(['Read', 'Grep', 'Glob']);
|
|
38
|
-
|
|
39
|
-
// ── CacheStage ───────────────────────────────────────────────────────────────
|
|
40
|
-
|
|
41
|
-
export class CacheStage implements PipelineStage {
|
|
42
|
-
readonly name = 'cache';
|
|
43
|
-
|
|
44
|
-
/** Cache key → CacheEntry */
|
|
45
|
-
private store = new Map<string, CacheEntry>();
|
|
46
|
-
private maxSize: number;
|
|
47
|
-
|
|
48
|
-
constructor(options: CacheStageOptions = {}) {
|
|
49
|
-
this.maxSize = options.maxSize ?? 500;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async process(execution: ToolExecution): Promise<void> {
|
|
53
|
-
// Only cache read-only tools
|
|
54
|
-
if (!READONLY_TOOLS.has(execution.toolName)) return;
|
|
55
|
-
|
|
56
|
-
const cacheKey = this.buildKey(
|
|
57
|
-
execution.toolName,
|
|
58
|
-
execution.params,
|
|
59
|
-
execution.context.sessionId,
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
const cached = this.store.get(cacheKey);
|
|
63
|
-
if (cached) {
|
|
64
|
-
cached.hitCount++;
|
|
65
|
-
execution.setResult(cached.result);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Not in cache — ExecutionStage reads this key to store the result once
|
|
70
|
-
// the tool actually runs.
|
|
71
|
-
execution._internal.cacheKey = cacheKey;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Called by ExecutionStage after a tool executes successfully, to store
|
|
76
|
-
* the result in the cache.
|
|
77
|
-
*/
|
|
78
|
-
cacheResult(cacheKey: string, result: ToolResult): void {
|
|
79
|
-
if (!result.success) return;
|
|
80
|
-
if (!result.llmContent && !result.displayContent) return;
|
|
81
|
-
|
|
82
|
-
// Evict oldest if at capacity
|
|
83
|
-
if (this.store.size >= this.maxSize) {
|
|
84
|
-
let oldestKey: string | undefined;
|
|
85
|
-
let oldestTime = Infinity;
|
|
86
|
-
for (const [k, v] of this.store) {
|
|
87
|
-
if (v.cachedAt < oldestTime) {
|
|
88
|
-
oldestTime = v.cachedAt;
|
|
89
|
-
oldestKey = k;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (oldestKey) this.store.delete(oldestKey);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
this.store.set(cacheKey, {
|
|
96
|
-
result,
|
|
97
|
-
cachedAt: Date.now(),
|
|
98
|
-
hitCount: 0,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Clear all cached entries */
|
|
103
|
-
clear(): void {
|
|
104
|
-
this.store.clear();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** Clear entries for a specific session */
|
|
108
|
-
clearSession(sessionId: string): void {
|
|
109
|
-
for (const [key, entry] of this.store) {
|
|
110
|
-
// Keys embed the sessionId — check by extracting it
|
|
111
|
-
if (key.includes(sessionId)) {
|
|
112
|
-
this.store.delete(key);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/** Get cache stats */
|
|
118
|
-
stats(): { size: number; maxSize: number } {
|
|
119
|
-
return { size: this.store.size, maxSize: this.maxSize };
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// ── Private ──────────────────────────────────────────────────────────────
|
|
123
|
-
|
|
124
|
-
private buildKey(toolName: string, params: Record<string, unknown>, sessionId: string): string {
|
|
125
|
-
const hash = crypto.createHash('sha256');
|
|
126
|
-
hash.update(toolName);
|
|
127
|
-
hash.update(JSON.stringify(params, Object.keys(params).sort()));
|
|
128
|
-
hash.update(sessionId);
|
|
129
|
-
return hash.digest('hex');
|
|
130
|
-
}
|
|
131
|
-
}
|