mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
strict:true
This commit is contained in:
parent
cffe053226
commit
07e995fc2f
4 changed files with 23 additions and 22 deletions
|
|
@ -21,6 +21,8 @@ export type VoidCommandBarProps = {
|
|||
export const VoidCommandBarMain = ({ uri, editor }: VoidCommandBarProps) => {
|
||||
const isDark = useIsDark()
|
||||
|
||||
if (uri?.scheme !== 'file') return null // don't show in editors that we made, they must be files
|
||||
|
||||
return <div
|
||||
className={`@@void-scope ${isDark ? 'dark' : ''}`}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -103,24 +103,30 @@ const directoryResultToString = (params: ToolCallParams['list_dir'], result: Too
|
|||
const validateJSON = (s: string): { [s: string]: unknown } => {
|
||||
try {
|
||||
const o = JSON.parse(s)
|
||||
if (typeof o !== 'object') throw new Error()
|
||||
|
||||
if ('result' in o) { // openrouter sometimes wraps the result with { 'result': ... }
|
||||
return o.result
|
||||
}
|
||||
|
||||
return o
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Tool parameter was not a string of a valid JSON: "${s}".`)
|
||||
throw new Error(`Invalid LLM output format: Tool parameter was not a string of a valid JSON: "${s}".`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const validateStr = (argName: string, value: unknown) => {
|
||||
if (typeof value !== 'string') throw new Error(`Error: ${argName} must be a string.`)
|
||||
if (typeof value !== 'string') throw new Error(`Invalid LLM output format: ${argName} must be a string.`)
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
// We are NOT checking to make sure in workspace
|
||||
const validateURI = (uriStr: unknown) => {
|
||||
if (typeof uriStr !== 'string') throw new Error('Provided uri must be a string.')
|
||||
if (typeof uriStr !== 'string') throw new Error('Invalid LLM output format: Provided uri must be a string.')
|
||||
|
||||
const uri = URI.file(uriStr)
|
||||
return uri
|
||||
|
|
@ -130,12 +136,12 @@ const validatePageNum = (pageNumberUnknown: unknown) => {
|
|||
if (!pageNumberUnknown) return 1
|
||||
const parsedInt = Number.parseInt(pageNumberUnknown + '')
|
||||
if (!Number.isInteger(parsedInt)) throw new Error(`Page number was not an integer: "${pageNumberUnknown}".`)
|
||||
if (parsedInt < 1) throw new Error(`Specified page number must be 1 or greater: "${pageNumberUnknown}".`)
|
||||
if (parsedInt < 1) throw new Error(`Invalid LLM output format: Specified page number must be 1 or greater: "${pageNumberUnknown}".`)
|
||||
return parsedInt
|
||||
}
|
||||
|
||||
const validateRecursiveParamStr = (paramsUnknown: unknown) => {
|
||||
if (typeof paramsUnknown !== 'string') throw new Error('Error calling tool: provided params must be a string.')
|
||||
if (typeof paramsUnknown !== 'string') throw new Error('Invalid LLM output format: Error calling tool: provided params must be a string.')
|
||||
const params = paramsUnknown
|
||||
const isRecursive = params.includes('r')
|
||||
return isRecursive
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ export type InternalToolInfo = {
|
|||
params: {
|
||||
[paramName: string]: { type: string, description: string | undefined } // name -> type
|
||||
},
|
||||
required: string[], // required paramNames
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -33,7 +32,7 @@ export type ResolveReason = { type: 'toofull' | 'timeout' | 'bgtask' } | { type:
|
|||
|
||||
const paginationHelper = {
|
||||
desc: `Very large results may be paginated (indicated in the result). Pagination fails gracefully if out of bounds or invalid page number.`,
|
||||
param: { pageNumber: { type: 'number', description: 'The page number (optional, default is 1).' }, }
|
||||
param: { pageNumber: { type: 'number', description: 'The page number (default is the first page = 1).' }, }
|
||||
} as const
|
||||
|
||||
export const voidTools = {
|
||||
|
|
@ -46,7 +45,6 @@ export const voidTools = {
|
|||
uri: { type: 'string', description: undefined },
|
||||
...paginationHelper.param,
|
||||
},
|
||||
required: ['uri'],
|
||||
},
|
||||
|
||||
list_dir: {
|
||||
|
|
@ -56,7 +54,6 @@ export const voidTools = {
|
|||
uri: { type: 'string', description: undefined },
|
||||
...paginationHelper.param,
|
||||
},
|
||||
required: ['uri'],
|
||||
},
|
||||
|
||||
pathname_search: {
|
||||
|
|
@ -66,7 +63,6 @@ export const voidTools = {
|
|||
query: { type: 'string', description: undefined },
|
||||
...paginationHelper.param,
|
||||
},
|
||||
required: ['query'],
|
||||
},
|
||||
|
||||
text_search: {
|
||||
|
|
@ -76,7 +72,6 @@ export const voidTools = {
|
|||
query: { type: 'string', description: undefined },
|
||||
...paginationHelper.param,
|
||||
},
|
||||
required: ['query'],
|
||||
},
|
||||
|
||||
// --- editing (create/delete) ---
|
||||
|
|
@ -87,7 +82,6 @@ export const voidTools = {
|
|||
params: {
|
||||
uri: { type: 'string', description: undefined },
|
||||
},
|
||||
required: ['uri'],
|
||||
},
|
||||
|
||||
delete_uri: {
|
||||
|
|
@ -97,7 +91,6 @@ export const voidTools = {
|
|||
uri: { type: 'string', description: undefined },
|
||||
params: { type: 'string', description: 'Return -r here to delete this URI and all descendants (if applicable). Default is the empty string.' }
|
||||
},
|
||||
required: ['uri', 'params'],
|
||||
},
|
||||
|
||||
edit: { // APPLY TOOL
|
||||
|
|
@ -107,7 +100,6 @@ export const voidTools = {
|
|||
uri: { type: 'string', description: undefined },
|
||||
changeDescription: { type: 'string', description: editToolDesc_toolDescription } // long description here
|
||||
},
|
||||
required: ['uri', 'changeDescription'],
|
||||
},
|
||||
|
||||
terminal_command: {
|
||||
|
|
@ -116,9 +108,8 @@ export const voidTools = {
|
|||
params: {
|
||||
command: { type: 'string', description: 'The terminal command to execute.' },
|
||||
waitForCompletion: { type: 'string', description: `Whether or not to await the command to complete and get the final result. Default is true. Make this value false when you want a command to run indefinitely without waiting for it.` },
|
||||
terminalId: { type: 'string', description: 'Optional (if provided, value must be an integer >= 1). This is the ID of the terminal instance to execute the command in. The primary purpose of this is to start a new terminal for background processes or tasks that run indefinitely (e.g. if you want to run a server locally). Fails gracefully if a terminal ID does not exist, by creating a new terminal instance. Defaults to the preferred terminal ID.' },
|
||||
terminalId: { type: 'string', description: 'Optional (value must be an integer >= 1, or empty which will go with the default). This is the ID of the terminal instance to execute the command in. The primary purpose of this is to start a new terminal for background processes or tasks that run indefinitely (e.g. if you want to run a server locally). Fails gracefully if a terminal ID does not exist, by creating a new terminal instance. Defaults to the preferred terminal ID.' },
|
||||
},
|
||||
required: ['command'],
|
||||
},
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,17 +36,19 @@ const invalidApiKeyMessage = (providerName: ProviderName) => `Invalid ${displayI
|
|||
|
||||
// ------------ OPENAI-COMPATIBLE (HELPERS) ------------
|
||||
const toOpenAICompatibleTool = (toolInfo: InternalToolInfo) => {
|
||||
const { name, description, params, required } = toolInfo
|
||||
const { name, description, params } = toolInfo
|
||||
return {
|
||||
type: 'function',
|
||||
function: {
|
||||
name: name,
|
||||
strict: true, // strict mode - https://platform.openai.com/docs/guides/function-calling?api-mode=chat
|
||||
description: description,
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: params,
|
||||
required: required,
|
||||
}
|
||||
required: Object.keys(params), // in strict mode, all params are required and additionalProperties is false
|
||||
additionalProperties: false,
|
||||
},
|
||||
}
|
||||
} satisfies OpenAI.Chat.Completions.ChatCompletionTool
|
||||
}
|
||||
|
|
@ -283,15 +285,15 @@ const _openaiCompatibleList = async ({ onSuccess: onSuccess_, onError: onError_,
|
|||
|
||||
// ------------ ANTHROPIC ------------
|
||||
const toAnthropicTool = (toolInfo: InternalToolInfo) => {
|
||||
const { name, description, params, required } = toolInfo
|
||||
const { name, description, params } = toolInfo
|
||||
return {
|
||||
name: name,
|
||||
description: description,
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
properties: params,
|
||||
required: required,
|
||||
}
|
||||
required: Object.keys(params),
|
||||
},
|
||||
} satisfies Anthropic.Messages.Tool
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue