@shareai-lab/kode 1.1.13 → 1.1.16-dev.1
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/entrypoints/cli.js +59 -38
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/index.js +5 -26
- package/dist/package.json +4 -1
- package/package.json +11 -104
- package/dist/test/testAdapters.js +0 -88
- package/dist/test/testAdapters.js.map +0 -1
- package/src/ProjectOnboarding.tsx +0 -198
- package/src/Tool.ts +0 -83
- package/src/commands/agents.tsx +0 -3416
- package/src/commands/approvedTools.ts +0 -53
- package/src/commands/bug.tsx +0 -20
- package/src/commands/clear.ts +0 -43
- package/src/commands/compact.ts +0 -120
- package/src/commands/config.tsx +0 -19
- package/src/commands/cost.ts +0 -18
- package/src/commands/ctx_viz.ts +0 -209
- package/src/commands/doctor.ts +0 -24
- package/src/commands/help.tsx +0 -19
- package/src/commands/init.ts +0 -37
- package/src/commands/listen.ts +0 -42
- package/src/commands/login.tsx +0 -51
- package/src/commands/logout.tsx +0 -40
- package/src/commands/mcp.ts +0 -41
- package/src/commands/model.tsx +0 -40
- package/src/commands/modelstatus.tsx +0 -20
- package/src/commands/onboarding.tsx +0 -34
- package/src/commands/pr_comments.ts +0 -59
- package/src/commands/refreshCommands.ts +0 -54
- package/src/commands/release-notes.ts +0 -34
- package/src/commands/resume.tsx +0 -31
- package/src/commands/review.ts +0 -49
- package/src/commands/terminalSetup.ts +0 -221
- package/src/commands.ts +0 -139
- package/src/components/ApproveApiKey.tsx +0 -93
- package/src/components/AsciiLogo.tsx +0 -13
- package/src/components/AutoUpdater.tsx +0 -148
- package/src/components/Bug.tsx +0 -367
- package/src/components/Config.tsx +0 -293
- package/src/components/ConsoleOAuthFlow.tsx +0 -327
- package/src/components/Cost.tsx +0 -23
- package/src/components/CostThresholdDialog.tsx +0 -46
- package/src/components/CustomSelect/option-map.ts +0 -42
- package/src/components/CustomSelect/select-option.tsx +0 -78
- package/src/components/CustomSelect/select.tsx +0 -152
- package/src/components/CustomSelect/theme.ts +0 -45
- package/src/components/CustomSelect/use-select-state.ts +0 -414
- package/src/components/CustomSelect/use-select.ts +0 -35
- package/src/components/FallbackToolUseRejectedMessage.tsx +0 -15
- package/src/components/FileEditToolUpdatedMessage.tsx +0 -66
- package/src/components/Help.tsx +0 -215
- package/src/components/HighlightedCode.tsx +0 -33
- package/src/components/InvalidConfigDialog.tsx +0 -113
- package/src/components/Link.tsx +0 -32
- package/src/components/LogSelector.tsx +0 -86
- package/src/components/Logo.tsx +0 -170
- package/src/components/MCPServerApprovalDialog.tsx +0 -100
- package/src/components/MCPServerDialogCopy.tsx +0 -25
- package/src/components/MCPServerMultiselectDialog.tsx +0 -109
- package/src/components/Message.tsx +0 -221
- package/src/components/MessageResponse.tsx +0 -15
- package/src/components/MessageSelector.tsx +0 -211
- package/src/components/ModeIndicator.tsx +0 -88
- package/src/components/ModelConfig.tsx +0 -301
- package/src/components/ModelListManager.tsx +0 -227
- package/src/components/ModelSelector.tsx +0 -3387
- package/src/components/ModelStatusDisplay.tsx +0 -230
- package/src/components/Onboarding.tsx +0 -274
- package/src/components/PressEnterToContinue.tsx +0 -11
- package/src/components/PromptInput.tsx +0 -760
- package/src/components/SentryErrorBoundary.ts +0 -39
- package/src/components/Spinner.tsx +0 -129
- package/src/components/StickerRequestForm.tsx +0 -16
- package/src/components/StructuredDiff.tsx +0 -191
- package/src/components/TextInput.tsx +0 -259
- package/src/components/TodoItem.tsx +0 -47
- package/src/components/TokenWarning.tsx +0 -31
- package/src/components/ToolUseLoader.tsx +0 -40
- package/src/components/TrustDialog.tsx +0 -106
- package/src/components/binary-feedback/BinaryFeedback.tsx +0 -63
- package/src/components/binary-feedback/BinaryFeedbackOption.tsx +0 -111
- package/src/components/binary-feedback/BinaryFeedbackView.tsx +0 -172
- package/src/components/binary-feedback/utils.ts +0 -220
- package/src/components/messages/AssistantBashOutputMessage.tsx +0 -22
- package/src/components/messages/AssistantLocalCommandOutputMessage.tsx +0 -49
- package/src/components/messages/AssistantRedactedThinkingMessage.tsx +0 -19
- package/src/components/messages/AssistantTextMessage.tsx +0 -144
- package/src/components/messages/AssistantThinkingMessage.tsx +0 -40
- package/src/components/messages/AssistantToolUseMessage.tsx +0 -132
- package/src/components/messages/TaskProgressMessage.tsx +0 -32
- package/src/components/messages/TaskToolMessage.tsx +0 -58
- package/src/components/messages/UserBashInputMessage.tsx +0 -28
- package/src/components/messages/UserCommandMessage.tsx +0 -30
- package/src/components/messages/UserKodingInputMessage.tsx +0 -28
- package/src/components/messages/UserPromptMessage.tsx +0 -35
- package/src/components/messages/UserTextMessage.tsx +0 -39
- package/src/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +0 -12
- package/src/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +0 -36
- package/src/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +0 -31
- package/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +0 -57
- package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +0 -35
- package/src/components/messages/UserToolResultMessage/utils.tsx +0 -56
- package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +0 -121
- package/src/components/permissions/FallbackPermissionRequest.tsx +0 -153
- package/src/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +0 -182
- package/src/components/permissions/FileEditPermissionRequest/FileEditToolDiff.tsx +0 -77
- package/src/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +0 -164
- package/src/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +0 -83
- package/src/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +0 -240
- package/src/components/permissions/PermissionRequest.tsx +0 -101
- package/src/components/permissions/PermissionRequestTitle.tsx +0 -69
- package/src/components/permissions/hooks.ts +0 -44
- package/src/components/permissions/toolUseOptions.ts +0 -59
- package/src/components/permissions/utils.ts +0 -23
- package/src/constants/betas.ts +0 -5
- package/src/constants/claude-asterisk-ascii-art.tsx +0 -238
- package/src/constants/figures.ts +0 -4
- package/src/constants/keys.ts +0 -3
- package/src/constants/macros.ts +0 -11
- package/src/constants/modelCapabilities.ts +0 -179
- package/src/constants/models.ts +0 -1025
- package/src/constants/oauth.ts +0 -18
- package/src/constants/product.ts +0 -17
- package/src/constants/prompts.ts +0 -168
- package/src/constants/releaseNotes.ts +0 -7
- package/src/context/PermissionContext.tsx +0 -149
- package/src/context.ts +0 -278
- package/src/cost-tracker.ts +0 -84
- package/src/entrypoints/cli.tsx +0 -1561
- package/src/entrypoints/mcp.ts +0 -175
- package/src/history.ts +0 -25
- package/src/hooks/useApiKeyVerification.ts +0 -59
- package/src/hooks/useArrowKeyHistory.ts +0 -55
- package/src/hooks/useCanUseTool.ts +0 -138
- package/src/hooks/useCancelRequest.ts +0 -39
- package/src/hooks/useDoublePress.ts +0 -41
- package/src/hooks/useExitOnCtrlCD.ts +0 -31
- package/src/hooks/useInterval.ts +0 -25
- package/src/hooks/useLogMessages.ts +0 -16
- package/src/hooks/useLogStartupTime.ts +0 -12
- package/src/hooks/useNotifyAfterTimeout.ts +0 -65
- package/src/hooks/usePermissionRequestLogging.ts +0 -44
- package/src/hooks/useTerminalSize.ts +0 -49
- package/src/hooks/useTextInput.ts +0 -317
- package/src/hooks/useUnifiedCompletion.ts +0 -1405
- package/src/index.ts +0 -34
- package/src/messages.ts +0 -38
- package/src/permissions.ts +0 -268
- package/src/query.ts +0 -720
- package/src/screens/ConfigureNpmPrefix.tsx +0 -197
- package/src/screens/Doctor.tsx +0 -219
- package/src/screens/LogList.tsx +0 -68
- package/src/screens/REPL.tsx +0 -813
- package/src/screens/ResumeConversation.tsx +0 -68
- package/src/services/adapters/base.ts +0 -38
- package/src/services/adapters/chatCompletions.ts +0 -90
- package/src/services/adapters/responsesAPI.ts +0 -170
- package/src/services/browserMocks.ts +0 -66
- package/src/services/claude.ts +0 -2197
- package/src/services/customCommands.ts +0 -704
- package/src/services/fileFreshness.ts +0 -377
- package/src/services/gpt5ConnectionTest.ts +0 -340
- package/src/services/mcpClient.ts +0 -564
- package/src/services/mcpServerApproval.tsx +0 -50
- package/src/services/mentionProcessor.ts +0 -273
- package/src/services/modelAdapterFactory.ts +0 -69
- package/src/services/notifier.ts +0 -40
- package/src/services/oauth.ts +0 -357
- package/src/services/openai.ts +0 -1359
- package/src/services/responseStateManager.ts +0 -90
- package/src/services/sentry.ts +0 -3
- package/src/services/statsig.ts +0 -172
- package/src/services/statsigStorage.ts +0 -86
- package/src/services/systemReminder.ts +0 -507
- package/src/services/vcr.ts +0 -161
- package/src/test/testAdapters.ts +0 -96
- package/src/tools/ArchitectTool/ArchitectTool.tsx +0 -135
- package/src/tools/ArchitectTool/prompt.ts +0 -15
- package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +0 -576
- package/src/tools/BashTool/BashTool.tsx +0 -243
- package/src/tools/BashTool/BashToolResultMessage.tsx +0 -38
- package/src/tools/BashTool/OutputLine.tsx +0 -49
- package/src/tools/BashTool/prompt.ts +0 -174
- package/src/tools/BashTool/utils.ts +0 -56
- package/src/tools/FileEditTool/FileEditTool.tsx +0 -319
- package/src/tools/FileEditTool/prompt.ts +0 -51
- package/src/tools/FileEditTool/utils.ts +0 -58
- package/src/tools/FileReadTool/FileReadTool.tsx +0 -404
- package/src/tools/FileReadTool/prompt.ts +0 -7
- package/src/tools/FileWriteTool/FileWriteTool.tsx +0 -301
- package/src/tools/FileWriteTool/prompt.ts +0 -10
- package/src/tools/GlobTool/GlobTool.tsx +0 -119
- package/src/tools/GlobTool/prompt.ts +0 -8
- package/src/tools/GrepTool/GrepTool.tsx +0 -147
- package/src/tools/GrepTool/prompt.ts +0 -11
- package/src/tools/MCPTool/MCPTool.tsx +0 -107
- package/src/tools/MCPTool/prompt.ts +0 -3
- package/src/tools/MemoryReadTool/MemoryReadTool.tsx +0 -127
- package/src/tools/MemoryReadTool/prompt.ts +0 -3
- package/src/tools/MemoryWriteTool/MemoryWriteTool.tsx +0 -89
- package/src/tools/MemoryWriteTool/prompt.ts +0 -3
- package/src/tools/MultiEditTool/MultiEditTool.tsx +0 -388
- package/src/tools/MultiEditTool/prompt.ts +0 -45
- package/src/tools/NotebookEditTool/NotebookEditTool.tsx +0 -298
- package/src/tools/NotebookEditTool/prompt.ts +0 -3
- package/src/tools/NotebookReadTool/NotebookReadTool.tsx +0 -258
- package/src/tools/NotebookReadTool/prompt.ts +0 -3
- package/src/tools/StickerRequestTool/StickerRequestTool.tsx +0 -107
- package/src/tools/StickerRequestTool/prompt.ts +0 -19
- package/src/tools/TaskTool/TaskTool.tsx +0 -438
- package/src/tools/TaskTool/constants.ts +0 -1
- package/src/tools/TaskTool/prompt.ts +0 -92
- package/src/tools/ThinkTool/ThinkTool.tsx +0 -54
- package/src/tools/ThinkTool/prompt.ts +0 -12
- package/src/tools/TodoWriteTool/TodoWriteTool.tsx +0 -313
- package/src/tools/TodoWriteTool/prompt.ts +0 -63
- package/src/tools/URLFetcherTool/URLFetcherTool.tsx +0 -178
- package/src/tools/URLFetcherTool/cache.ts +0 -55
- package/src/tools/URLFetcherTool/htmlToMarkdown.ts +0 -55
- package/src/tools/URLFetcherTool/prompt.ts +0 -17
- package/src/tools/WebSearchTool/WebSearchTool.tsx +0 -103
- package/src/tools/WebSearchTool/prompt.ts +0 -13
- package/src/tools/WebSearchTool/searchProviders.ts +0 -66
- package/src/tools/lsTool/lsTool.tsx +0 -272
- package/src/tools/lsTool/prompt.ts +0 -2
- package/src/tools.ts +0 -67
- package/src/types/PermissionMode.ts +0 -120
- package/src/types/RequestContext.ts +0 -72
- package/src/types/common.d.ts +0 -2
- package/src/types/conversation.ts +0 -51
- package/src/types/logs.ts +0 -58
- package/src/types/modelCapabilities.ts +0 -64
- package/src/types/notebook.ts +0 -87
- package/src/utils/Cursor.ts +0 -436
- package/src/utils/PersistentShell.ts +0 -552
- package/src/utils/advancedFuzzyMatcher.ts +0 -290
- package/src/utils/agentLoader.ts +0 -278
- package/src/utils/agentStorage.ts +0 -97
- package/src/utils/array.ts +0 -3
- package/src/utils/ask.tsx +0 -99
- package/src/utils/auth.ts +0 -13
- package/src/utils/autoCompactCore.ts +0 -223
- package/src/utils/autoUpdater.ts +0 -458
- package/src/utils/betas.ts +0 -20
- package/src/utils/browser.ts +0 -14
- package/src/utils/cleanup.ts +0 -72
- package/src/utils/commands.ts +0 -261
- package/src/utils/commonUnixCommands.ts +0 -161
- package/src/utils/config.ts +0 -945
- package/src/utils/conversationRecovery.ts +0 -55
- package/src/utils/debugLogger.ts +0 -1235
- package/src/utils/diff.ts +0 -42
- package/src/utils/env.ts +0 -57
- package/src/utils/errors.ts +0 -21
- package/src/utils/exampleCommands.ts +0 -109
- package/src/utils/execFileNoThrow.ts +0 -51
- package/src/utils/expertChatStorage.ts +0 -136
- package/src/utils/file.ts +0 -405
- package/src/utils/fileRecoveryCore.ts +0 -71
- package/src/utils/format.tsx +0 -44
- package/src/utils/fuzzyMatcher.ts +0 -328
- package/src/utils/generators.ts +0 -62
- package/src/utils/git.ts +0 -92
- package/src/utils/globalLogger.ts +0 -77
- package/src/utils/http.ts +0 -10
- package/src/utils/imagePaste.ts +0 -38
- package/src/utils/json.ts +0 -13
- package/src/utils/log.ts +0 -382
- package/src/utils/markdown.ts +0 -213
- package/src/utils/messageContextManager.ts +0 -294
- package/src/utils/messages.tsx +0 -945
- package/src/utils/model.ts +0 -914
- package/src/utils/permissions/filesystem.ts +0 -127
- package/src/utils/responseState.ts +0 -23
- package/src/utils/ripgrep.ts +0 -167
- package/src/utils/secureFile.ts +0 -564
- package/src/utils/sessionState.ts +0 -49
- package/src/utils/state.ts +0 -25
- package/src/utils/style.ts +0 -29
- package/src/utils/terminal.ts +0 -50
- package/src/utils/theme.ts +0 -127
- package/src/utils/thinking.ts +0 -144
- package/src/utils/todoStorage.ts +0 -431
- package/src/utils/tokens.ts +0 -43
- package/src/utils/toolExecutionController.ts +0 -163
- package/src/utils/unaryLogging.ts +0 -26
- package/src/utils/user.ts +0 -37
- package/src/utils/validate.ts +0 -165
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export const PROMPT = `Write a file to the local filesystem. Overwrites the existing file if there is one.
|
|
2
|
-
|
|
3
|
-
Before using this tool:
|
|
4
|
-
|
|
5
|
-
1. Use the ReadFile tool to understand the file's contents and context
|
|
6
|
-
|
|
7
|
-
2. Directory Verification (only applicable when creating new files):
|
|
8
|
-
- Use the LS tool to verify the parent directory exists and is the correct location`
|
|
9
|
-
|
|
10
|
-
export const DESCRIPTION = 'Write a file to the local filesystem.'
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { Box, Text } from 'ink'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { z } from 'zod'
|
|
4
|
-
import { Cost } from '../../components/Cost'
|
|
5
|
-
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage'
|
|
6
|
-
import { Tool } from '../../Tool'
|
|
7
|
-
import { getCwd } from '../../utils/state'
|
|
8
|
-
import { glob } from '../../utils/file'
|
|
9
|
-
import { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'
|
|
10
|
-
import { isAbsolute, relative, resolve } from 'path'
|
|
11
|
-
import { hasReadPermission } from '../../utils/permissions/filesystem'
|
|
12
|
-
|
|
13
|
-
const inputSchema = z.strictObject({
|
|
14
|
-
pattern: z.string().describe('The glob pattern to match files against'),
|
|
15
|
-
path: z
|
|
16
|
-
.string()
|
|
17
|
-
.optional()
|
|
18
|
-
.describe(
|
|
19
|
-
'The directory to search in. Defaults to the current working directory.',
|
|
20
|
-
),
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
type Output = {
|
|
24
|
-
durationMs: number
|
|
25
|
-
numFiles: number
|
|
26
|
-
filenames: string[]
|
|
27
|
-
truncated: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const GlobTool = {
|
|
31
|
-
name: TOOL_NAME_FOR_PROMPT,
|
|
32
|
-
async description() {
|
|
33
|
-
return DESCRIPTION
|
|
34
|
-
},
|
|
35
|
-
userFacingName() {
|
|
36
|
-
return 'Search'
|
|
37
|
-
},
|
|
38
|
-
inputSchema,
|
|
39
|
-
async isEnabled() {
|
|
40
|
-
return true
|
|
41
|
-
},
|
|
42
|
-
isReadOnly() {
|
|
43
|
-
return true
|
|
44
|
-
},
|
|
45
|
-
isConcurrencySafe() {
|
|
46
|
-
return true // GlobTool is read-only, safe for concurrent execution
|
|
47
|
-
},
|
|
48
|
-
needsPermissions({ path }) {
|
|
49
|
-
return !hasReadPermission(path || getCwd())
|
|
50
|
-
},
|
|
51
|
-
async prompt() {
|
|
52
|
-
return DESCRIPTION
|
|
53
|
-
},
|
|
54
|
-
renderToolUseMessage({ pattern, path }, { verbose }) {
|
|
55
|
-
const absolutePath = path
|
|
56
|
-
? isAbsolute(path)
|
|
57
|
-
? path
|
|
58
|
-
: resolve(getCwd(), path)
|
|
59
|
-
: undefined
|
|
60
|
-
const relativePath = absolutePath
|
|
61
|
-
? relative(getCwd(), absolutePath)
|
|
62
|
-
: undefined
|
|
63
|
-
return `pattern: "${pattern}"${relativePath || verbose ? `, path: "${verbose ? absolutePath : relativePath}"` : ''}`
|
|
64
|
-
},
|
|
65
|
-
renderToolUseRejectedMessage() {
|
|
66
|
-
return <FallbackToolUseRejectedMessage />
|
|
67
|
-
},
|
|
68
|
-
renderToolResultMessage(output) {
|
|
69
|
-
// Handle string content for backward compatibility
|
|
70
|
-
if (typeof output === 'string') {
|
|
71
|
-
output = JSON.parse(output) as Output
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Box justifyContent="space-between" width="100%">
|
|
76
|
-
<Box flexDirection="row">
|
|
77
|
-
<Text> ⎿ Found </Text>
|
|
78
|
-
<Text bold>{output.numFiles} </Text>
|
|
79
|
-
<Text>
|
|
80
|
-
{output.numFiles === 0 || output.numFiles > 1 ? 'files' : 'file'}
|
|
81
|
-
</Text>
|
|
82
|
-
</Box>
|
|
83
|
-
<Cost costUSD={0} durationMs={output.durationMs} debug={false} />
|
|
84
|
-
</Box>
|
|
85
|
-
)
|
|
86
|
-
},
|
|
87
|
-
async *call({ pattern, path }, { abortController }) {
|
|
88
|
-
const start = Date.now()
|
|
89
|
-
const { files, truncated } = await glob(
|
|
90
|
-
pattern,
|
|
91
|
-
path ?? getCwd(),
|
|
92
|
-
{ limit: 100, offset: 0 },
|
|
93
|
-
abortController.signal,
|
|
94
|
-
)
|
|
95
|
-
const output: Output = {
|
|
96
|
-
filenames: files,
|
|
97
|
-
durationMs: Date.now() - start,
|
|
98
|
-
numFiles: files.length,
|
|
99
|
-
truncated,
|
|
100
|
-
}
|
|
101
|
-
yield {
|
|
102
|
-
type: 'result',
|
|
103
|
-
resultForAssistant: this.renderResultForAssistant(output),
|
|
104
|
-
data: output,
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
renderResultForAssistant(output) {
|
|
108
|
-
let result = output.filenames.join('\n')
|
|
109
|
-
if (output.filenames.length === 0) {
|
|
110
|
-
result = 'No files found'
|
|
111
|
-
}
|
|
112
|
-
// Only add truncation message if results were actually truncated
|
|
113
|
-
else if (output.truncated) {
|
|
114
|
-
result +=
|
|
115
|
-
'\n(Results are truncated. Consider using a more specific path or pattern.)'
|
|
116
|
-
}
|
|
117
|
-
return result
|
|
118
|
-
},
|
|
119
|
-
} satisfies Tool<typeof inputSchema, Output>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const TOOL_NAME_FOR_PROMPT = 'GlobTool'
|
|
2
|
-
|
|
3
|
-
export const DESCRIPTION = `- Fast file pattern matching tool that works with any codebase size
|
|
4
|
-
- Supports glob patterns like "**/*.js" or "src/**/*.ts"
|
|
5
|
-
- Returns matching file paths sorted by modification time
|
|
6
|
-
- Use this tool when you need to find files by name patterns
|
|
7
|
-
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead
|
|
8
|
-
`
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { stat } from 'fs/promises'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import { z } from 'zod'
|
|
5
|
-
import { Cost } from '../../components/Cost'
|
|
6
|
-
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage'
|
|
7
|
-
import { Tool } from '../../Tool'
|
|
8
|
-
import { getCwd } from '../../utils/state'
|
|
9
|
-
import {
|
|
10
|
-
getAbsolutePath,
|
|
11
|
-
getAbsoluteAndRelativePaths,
|
|
12
|
-
} from '../../utils/file.js'
|
|
13
|
-
import { ripGrep } from '../../utils/ripgrep'
|
|
14
|
-
import { DESCRIPTION, TOOL_NAME_FOR_PROMPT } from './prompt'
|
|
15
|
-
import { hasReadPermission } from '../../utils/permissions/filesystem'
|
|
16
|
-
|
|
17
|
-
const inputSchema = z.strictObject({
|
|
18
|
-
pattern: z
|
|
19
|
-
.string()
|
|
20
|
-
.describe('The regular expression pattern to search for in file contents'),
|
|
21
|
-
path: z
|
|
22
|
-
.string()
|
|
23
|
-
.optional()
|
|
24
|
-
.describe(
|
|
25
|
-
'The directory to search in. Defaults to the current working directory.',
|
|
26
|
-
),
|
|
27
|
-
include: z
|
|
28
|
-
.string()
|
|
29
|
-
.optional()
|
|
30
|
-
.describe(
|
|
31
|
-
'File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")',
|
|
32
|
-
),
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
const MAX_RESULTS = 100
|
|
36
|
-
|
|
37
|
-
type Input = typeof inputSchema
|
|
38
|
-
type Output = {
|
|
39
|
-
durationMs: number
|
|
40
|
-
numFiles: number
|
|
41
|
-
filenames: string[]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const GrepTool = {
|
|
45
|
-
name: TOOL_NAME_FOR_PROMPT,
|
|
46
|
-
async description() {
|
|
47
|
-
return DESCRIPTION
|
|
48
|
-
},
|
|
49
|
-
userFacingName() {
|
|
50
|
-
return 'Search'
|
|
51
|
-
},
|
|
52
|
-
inputSchema,
|
|
53
|
-
isReadOnly() {
|
|
54
|
-
return true
|
|
55
|
-
},
|
|
56
|
-
isConcurrencySafe() {
|
|
57
|
-
return true // GrepTool is read-only, safe for concurrent execution
|
|
58
|
-
},
|
|
59
|
-
async isEnabled() {
|
|
60
|
-
return true
|
|
61
|
-
},
|
|
62
|
-
needsPermissions({ path }) {
|
|
63
|
-
return !hasReadPermission(path || getCwd())
|
|
64
|
-
},
|
|
65
|
-
async prompt() {
|
|
66
|
-
return DESCRIPTION
|
|
67
|
-
},
|
|
68
|
-
renderToolUseMessage({ pattern, path, include }, { verbose }) {
|
|
69
|
-
const { absolutePath, relativePath } = getAbsoluteAndRelativePaths(path)
|
|
70
|
-
return `pattern: "${pattern}"${relativePath || verbose ? `, path: "${verbose ? absolutePath : relativePath}"` : ''}${include ? `, include: "${include}"` : ''}`
|
|
71
|
-
},
|
|
72
|
-
renderToolUseRejectedMessage() {
|
|
73
|
-
return <FallbackToolUseRejectedMessage />
|
|
74
|
-
},
|
|
75
|
-
renderToolResultMessage(output) {
|
|
76
|
-
// Handle string content for backward compatibility
|
|
77
|
-
if (typeof output === 'string') {
|
|
78
|
-
// Convert string to Output type using tmpDeserializeOldLogResult if needed
|
|
79
|
-
output = output as unknown as Output
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<Box justifyContent="space-between" width="100%">
|
|
84
|
-
<Box flexDirection="row">
|
|
85
|
-
<Text> ⎿ Found </Text>
|
|
86
|
-
<Text bold>{output.numFiles} </Text>
|
|
87
|
-
<Text>
|
|
88
|
-
{output.numFiles === 0 || output.numFiles > 1 ? 'files' : 'file'}
|
|
89
|
-
</Text>
|
|
90
|
-
</Box>
|
|
91
|
-
<Cost costUSD={0} durationMs={output.durationMs} debug={false} />
|
|
92
|
-
</Box>
|
|
93
|
-
)
|
|
94
|
-
},
|
|
95
|
-
renderResultForAssistant({ numFiles, filenames }) {
|
|
96
|
-
if (numFiles === 0) {
|
|
97
|
-
return 'No files found'
|
|
98
|
-
}
|
|
99
|
-
let result = `Found ${numFiles} file${numFiles === 1 ? '' : 's'}\n${filenames.slice(0, MAX_RESULTS).join('\n')}`
|
|
100
|
-
if (numFiles > MAX_RESULTS) {
|
|
101
|
-
result +=
|
|
102
|
-
'\n(Results are truncated. Consider using a more specific path or pattern.)'
|
|
103
|
-
}
|
|
104
|
-
return result
|
|
105
|
-
},
|
|
106
|
-
async *call({ pattern, path, include }, { abortController }) {
|
|
107
|
-
const start = Date.now()
|
|
108
|
-
const absolutePath = getAbsolutePath(path) || getCwd()
|
|
109
|
-
|
|
110
|
-
const args = ['-li', pattern]
|
|
111
|
-
if (include) {
|
|
112
|
-
args.push('--glob', include)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const results = await ripGrep(args, absolutePath, abortController.signal)
|
|
116
|
-
|
|
117
|
-
const stats = await Promise.all(results.map(_ => stat(_)))
|
|
118
|
-
const matches = results
|
|
119
|
-
// Sort by modification time
|
|
120
|
-
.map((_, i) => [_, stats[i]!] as const)
|
|
121
|
-
.sort((a, b) => {
|
|
122
|
-
if (process.env.NODE_ENV === 'test') {
|
|
123
|
-
// In tests, we always want to sort by filename, so that results are deterministic
|
|
124
|
-
return a[0].localeCompare(b[0])
|
|
125
|
-
}
|
|
126
|
-
const timeComparison = (b[1].mtimeMs ?? 0) - (a[1].mtimeMs ?? 0)
|
|
127
|
-
if (timeComparison === 0) {
|
|
128
|
-
// Sort by filename as a tiebreaker
|
|
129
|
-
return a[0].localeCompare(b[0])
|
|
130
|
-
}
|
|
131
|
-
return timeComparison
|
|
132
|
-
})
|
|
133
|
-
.map(_ => _[0])
|
|
134
|
-
|
|
135
|
-
const output = {
|
|
136
|
-
filenames: matches,
|
|
137
|
-
durationMs: Date.now() - start,
|
|
138
|
-
numFiles: matches.length,
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
yield {
|
|
142
|
-
type: 'result',
|
|
143
|
-
resultForAssistant: this.renderResultForAssistant(output),
|
|
144
|
-
data: output,
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
} satisfies Tool<Input, Output>
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const TOOL_NAME_FOR_PROMPT = 'GrepTool'
|
|
2
|
-
|
|
3
|
-
export const DESCRIPTION = `
|
|
4
|
-
- Fast content search tool that works with any codebase size
|
|
5
|
-
- Searches file contents using regular expressions
|
|
6
|
-
- Supports full regex syntax (eg. "log.*Error", "function\\s+\\w+", etc.)
|
|
7
|
-
- Filter files by pattern with the include parameter (eg. "*.js", "*.{ts,tsx}")
|
|
8
|
-
- Returns matching file paths sorted by modification time
|
|
9
|
-
- Use this tool when you need to find files containing specific patterns
|
|
10
|
-
- When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead
|
|
11
|
-
`
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { Box, Text } from 'ink'
|
|
2
|
-
import * as React from 'react'
|
|
3
|
-
import { z } from 'zod'
|
|
4
|
-
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage'
|
|
5
|
-
import { type Tool } from '../../Tool'
|
|
6
|
-
import { getTheme } from '../../utils/theme'
|
|
7
|
-
import { DESCRIPTION, PROMPT } from './prompt'
|
|
8
|
-
import { OutputLine } from '../BashTool/OutputLine'
|
|
9
|
-
|
|
10
|
-
// Allow any input object since MCP tools define their own schemas
|
|
11
|
-
const inputSchema = z.object({}).passthrough()
|
|
12
|
-
|
|
13
|
-
export const MCPTool = {
|
|
14
|
-
async isEnabled() {
|
|
15
|
-
return true
|
|
16
|
-
},
|
|
17
|
-
isReadOnly() {
|
|
18
|
-
return false
|
|
19
|
-
},
|
|
20
|
-
isConcurrencySafe() {
|
|
21
|
-
return false // MCPTool can modify state through MCP calls, not safe for concurrent execution
|
|
22
|
-
},
|
|
23
|
-
// Overridden in mcpClient.ts
|
|
24
|
-
name: 'mcp',
|
|
25
|
-
// Overridden in mcpClient.ts
|
|
26
|
-
async description() {
|
|
27
|
-
return DESCRIPTION
|
|
28
|
-
},
|
|
29
|
-
// Overridden in mcpClient.ts
|
|
30
|
-
async prompt() {
|
|
31
|
-
return PROMPT
|
|
32
|
-
},
|
|
33
|
-
inputSchema,
|
|
34
|
-
// Overridden in mcpClient.ts
|
|
35
|
-
async *call() {
|
|
36
|
-
yield {
|
|
37
|
-
type: 'result',
|
|
38
|
-
data: '',
|
|
39
|
-
resultForAssistant: '',
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
needsPermissions() {
|
|
43
|
-
return true
|
|
44
|
-
},
|
|
45
|
-
renderToolUseMessage(input) {
|
|
46
|
-
return Object.entries(input)
|
|
47
|
-
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
48
|
-
.join(', ')
|
|
49
|
-
},
|
|
50
|
-
// Overridden in mcpClient.ts
|
|
51
|
-
userFacingName: () => 'mcp',
|
|
52
|
-
renderToolUseRejectedMessage() {
|
|
53
|
-
return <FallbackToolUseRejectedMessage />
|
|
54
|
-
},
|
|
55
|
-
renderToolResultMessage(output) {
|
|
56
|
-
const verbose = false // Set default value for verbose
|
|
57
|
-
if (Array.isArray(output)) {
|
|
58
|
-
return (
|
|
59
|
-
<Box flexDirection="column">
|
|
60
|
-
{output.map((item, i) => {
|
|
61
|
-
if (item.type === 'image') {
|
|
62
|
-
return (
|
|
63
|
-
<Box
|
|
64
|
-
key={i}
|
|
65
|
-
justifyContent="space-between"
|
|
66
|
-
overflowX="hidden"
|
|
67
|
-
width="100%"
|
|
68
|
-
>
|
|
69
|
-
<Box flexDirection="row">
|
|
70
|
-
<Text> ⎿ </Text>
|
|
71
|
-
<Text>[Image]</Text>
|
|
72
|
-
</Box>
|
|
73
|
-
</Box>
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
const lines = item.text.split('\n').length
|
|
77
|
-
return (
|
|
78
|
-
<OutputLine
|
|
79
|
-
key={i}
|
|
80
|
-
content={item.text}
|
|
81
|
-
lines={lines}
|
|
82
|
-
verbose={verbose}
|
|
83
|
-
/>
|
|
84
|
-
)
|
|
85
|
-
})}
|
|
86
|
-
</Box>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (!output) {
|
|
91
|
-
return (
|
|
92
|
-
<Box justifyContent="space-between" overflowX="hidden" width="100%">
|
|
93
|
-
<Box flexDirection="row">
|
|
94
|
-
<Text> ⎿ </Text>
|
|
95
|
-
<Text color={getTheme().secondaryText}>(No content)</Text>
|
|
96
|
-
</Box>
|
|
97
|
-
</Box>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const lines = output.split('\n').length
|
|
102
|
-
return <OutputLine content={output} lines={lines} verbose={verbose} />
|
|
103
|
-
},
|
|
104
|
-
renderResultForAssistant(content) {
|
|
105
|
-
return content
|
|
106
|
-
},
|
|
107
|
-
} satisfies Tool<typeof inputSchema, string>
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync } from 'fs'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
import { join } from 'path'
|
|
4
|
-
import * as React from 'react'
|
|
5
|
-
import { z } from 'zod'
|
|
6
|
-
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage'
|
|
7
|
-
import { Tool } from '../../Tool'
|
|
8
|
-
import { MEMORY_DIR } from '../../utils/env'
|
|
9
|
-
import { resolveAgentId } from '../../utils/agentStorage'
|
|
10
|
-
import { DESCRIPTION, PROMPT } from './prompt'
|
|
11
|
-
|
|
12
|
-
const inputSchema = z.strictObject({
|
|
13
|
-
file_path: z
|
|
14
|
-
.string()
|
|
15
|
-
.optional()
|
|
16
|
-
.describe('Optional path to a specific memory file to read'),
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
export const MemoryReadTool = {
|
|
20
|
-
name: 'MemoryRead',
|
|
21
|
-
async description() {
|
|
22
|
-
return DESCRIPTION
|
|
23
|
-
},
|
|
24
|
-
async prompt() {
|
|
25
|
-
return PROMPT
|
|
26
|
-
},
|
|
27
|
-
inputSchema,
|
|
28
|
-
userFacingName() {
|
|
29
|
-
return 'Read Memory'
|
|
30
|
-
},
|
|
31
|
-
async isEnabled() {
|
|
32
|
-
// TODO: Use a statsig gate
|
|
33
|
-
// TODO: Figure out how to do that without regressing app startup perf
|
|
34
|
-
return false
|
|
35
|
-
},
|
|
36
|
-
isReadOnly() {
|
|
37
|
-
return true
|
|
38
|
-
},
|
|
39
|
-
isConcurrencySafe() {
|
|
40
|
-
return true // MemoryRead is read-only, safe for concurrent execution
|
|
41
|
-
},
|
|
42
|
-
needsPermissions() {
|
|
43
|
-
return false
|
|
44
|
-
},
|
|
45
|
-
renderResultForAssistant({ content }) {
|
|
46
|
-
return content
|
|
47
|
-
},
|
|
48
|
-
renderToolUseMessage(input) {
|
|
49
|
-
return Object.entries(input)
|
|
50
|
-
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
51
|
-
.join(', ')
|
|
52
|
-
},
|
|
53
|
-
renderToolUseRejectedMessage() {
|
|
54
|
-
return <FallbackToolUseRejectedMessage />
|
|
55
|
-
},
|
|
56
|
-
renderToolResultMessage(output) {
|
|
57
|
-
return (
|
|
58
|
-
<Box justifyContent="space-between" overflowX="hidden" width="100%">
|
|
59
|
-
<Box flexDirection="row">
|
|
60
|
-
<Text> ⎿ </Text>
|
|
61
|
-
<Text>{output.content}</Text>
|
|
62
|
-
</Box>
|
|
63
|
-
</Box>
|
|
64
|
-
)
|
|
65
|
-
},
|
|
66
|
-
async validateInput({ file_path }, context) {
|
|
67
|
-
const agentId = resolveAgentId(context?.agentId)
|
|
68
|
-
const agentMemoryDir = join(MEMORY_DIR, 'agents', agentId)
|
|
69
|
-
|
|
70
|
-
if (file_path) {
|
|
71
|
-
const fullPath = join(agentMemoryDir, file_path)
|
|
72
|
-
if (!fullPath.startsWith(agentMemoryDir)) {
|
|
73
|
-
return { result: false, message: 'Invalid memory file path' }
|
|
74
|
-
}
|
|
75
|
-
if (!existsSync(fullPath)) {
|
|
76
|
-
return { result: false, message: 'Memory file does not exist' }
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return { result: true }
|
|
80
|
-
},
|
|
81
|
-
async *call({ file_path }, context) {
|
|
82
|
-
const agentId = resolveAgentId(context?.agentId)
|
|
83
|
-
const agentMemoryDir = join(MEMORY_DIR, 'agents', agentId)
|
|
84
|
-
mkdirSync(agentMemoryDir, { recursive: true })
|
|
85
|
-
|
|
86
|
-
// If a specific file is requested, return its contents
|
|
87
|
-
if (file_path) {
|
|
88
|
-
const fullPath = join(agentMemoryDir, file_path)
|
|
89
|
-
if (!existsSync(fullPath)) {
|
|
90
|
-
throw new Error('Memory file does not exist')
|
|
91
|
-
}
|
|
92
|
-
const content = readFileSync(fullPath, 'utf-8')
|
|
93
|
-
yield {
|
|
94
|
-
type: 'result',
|
|
95
|
-
data: {
|
|
96
|
-
content,
|
|
97
|
-
},
|
|
98
|
-
resultForAssistant: this.renderResultForAssistant({ content }),
|
|
99
|
-
}
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Otherwise return the index and file list for this agent
|
|
104
|
-
const files = readdirSync(agentMemoryDir, { recursive: true })
|
|
105
|
-
.map(f => join(agentMemoryDir, f.toString()))
|
|
106
|
-
.filter(f => !lstatSync(f).isDirectory())
|
|
107
|
-
.map(f => `- ${f}`)
|
|
108
|
-
.join('\n')
|
|
109
|
-
|
|
110
|
-
const indexPath = join(agentMemoryDir, 'index.md')
|
|
111
|
-
const index = existsSync(indexPath) ? readFileSync(indexPath, 'utf-8') : ''
|
|
112
|
-
|
|
113
|
-
const quotes = "'''"
|
|
114
|
-
const content = `Here are the contents of the agent memory file, \`${indexPath}\`:
|
|
115
|
-
${quotes}
|
|
116
|
-
${index}
|
|
117
|
-
${quotes}
|
|
118
|
-
|
|
119
|
-
Files in the agent memory directory:
|
|
120
|
-
${files}`
|
|
121
|
-
yield {
|
|
122
|
-
type: 'result',
|
|
123
|
-
data: { content },
|
|
124
|
-
resultForAssistant: this.renderResultForAssistant({ content }),
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
} satisfies Tool<typeof inputSchema, { content: string }>
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from 'fs'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
import { dirname, join } from 'path'
|
|
4
|
-
import * as React from 'react'
|
|
5
|
-
import { z } from 'zod'
|
|
6
|
-
import { FallbackToolUseRejectedMessage } from '../../components/FallbackToolUseRejectedMessage'
|
|
7
|
-
import { Tool } from '../../Tool'
|
|
8
|
-
import { MEMORY_DIR } from '../../utils/env'
|
|
9
|
-
import { resolveAgentId } from '../../utils/agentStorage'
|
|
10
|
-
import { recordFileEdit } from '../../services/fileFreshness'
|
|
11
|
-
import { DESCRIPTION, PROMPT } from './prompt'
|
|
12
|
-
|
|
13
|
-
const inputSchema = z.strictObject({
|
|
14
|
-
file_path: z.string().describe('Path to the memory file to write'),
|
|
15
|
-
content: z.string().describe('Content to write to the file'),
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
export const MemoryWriteTool = {
|
|
19
|
-
name: 'MemoryWrite',
|
|
20
|
-
async description() {
|
|
21
|
-
return DESCRIPTION
|
|
22
|
-
},
|
|
23
|
-
async prompt() {
|
|
24
|
-
return PROMPT
|
|
25
|
-
},
|
|
26
|
-
inputSchema,
|
|
27
|
-
userFacingName() {
|
|
28
|
-
return 'Write Memory'
|
|
29
|
-
},
|
|
30
|
-
async isEnabled() {
|
|
31
|
-
// TODO: Use a statsig gate
|
|
32
|
-
// TODO: Figure out how to do that without regressing app startup perf
|
|
33
|
-
return false
|
|
34
|
-
},
|
|
35
|
-
isReadOnly() {
|
|
36
|
-
return false
|
|
37
|
-
},
|
|
38
|
-
isConcurrencySafe() {
|
|
39
|
-
return false // MemoryWrite modifies state, not safe for concurrent execution
|
|
40
|
-
},
|
|
41
|
-
needsPermissions() {
|
|
42
|
-
return false
|
|
43
|
-
},
|
|
44
|
-
renderResultForAssistant(content) {
|
|
45
|
-
return content
|
|
46
|
-
},
|
|
47
|
-
renderToolUseMessage(input) {
|
|
48
|
-
return Object.entries(input)
|
|
49
|
-
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
50
|
-
.join(', ')
|
|
51
|
-
},
|
|
52
|
-
renderToolUseRejectedMessage() {
|
|
53
|
-
return <FallbackToolUseRejectedMessage />
|
|
54
|
-
},
|
|
55
|
-
renderToolResultMessage() {
|
|
56
|
-
return (
|
|
57
|
-
<Box justifyContent="space-between" overflowX="hidden" width="100%">
|
|
58
|
-
<Box flexDirection="row">
|
|
59
|
-
<Text>{' '}⎿ Updated memory</Text>
|
|
60
|
-
</Box>
|
|
61
|
-
</Box>
|
|
62
|
-
)
|
|
63
|
-
},
|
|
64
|
-
async validateInput({ file_path }, context) {
|
|
65
|
-
const agentId = resolveAgentId(context?.agentId)
|
|
66
|
-
const agentMemoryDir = join(MEMORY_DIR, 'agents', agentId)
|
|
67
|
-
const fullPath = join(agentMemoryDir, file_path)
|
|
68
|
-
if (!fullPath.startsWith(agentMemoryDir)) {
|
|
69
|
-
return { result: false, message: 'Invalid memory file path' }
|
|
70
|
-
}
|
|
71
|
-
return { result: true }
|
|
72
|
-
},
|
|
73
|
-
async *call({ file_path, content }, context) {
|
|
74
|
-
const agentId = resolveAgentId(context?.agentId)
|
|
75
|
-
const agentMemoryDir = join(MEMORY_DIR, 'agents', agentId)
|
|
76
|
-
const fullPath = join(agentMemoryDir, file_path)
|
|
77
|
-
mkdirSync(dirname(fullPath), { recursive: true })
|
|
78
|
-
writeFileSync(fullPath, content, 'utf-8')
|
|
79
|
-
|
|
80
|
-
// Record Agent edit operation for file freshness tracking
|
|
81
|
-
recordFileEdit(fullPath, content)
|
|
82
|
-
|
|
83
|
-
yield {
|
|
84
|
-
type: 'result',
|
|
85
|
-
data: 'Saved',
|
|
86
|
-
resultForAssistant: 'Saved',
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
} satisfies Tool<typeof inputSchema, string>
|