mirror of
https://github.com/voideditor/void
synced 2026-05-24 09:58:23 +00:00
feat: read .voidrules for system prompt
This commit is contained in:
parent
6d513a1e60
commit
9b130edcfe
6 changed files with 74 additions and 29 deletions
12
extensions/void/src/common/getRules.ts
Normal file
12
extensions/void/src/common/getRules.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { awaitVSCodeResponse, getVSCodeAPI } from '../sidebar/getVscodeApi';
|
||||||
|
|
||||||
|
export async function getRules() {
|
||||||
|
try {
|
||||||
|
getVSCodeAPI().postMessage({ type: 'getRules', rules: '' })
|
||||||
|
const rules = await awaitVSCodeResponse('getRules')
|
||||||
|
return rules.rules
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading .voidrules file:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ import { createOpenAI, OpenAIProviderSettings } from '@ai-sdk/openai';
|
||||||
import { AnthropicProviderSettings, createAnthropic } from '@ai-sdk/anthropic';
|
import { AnthropicProviderSettings, createAnthropic } from '@ai-sdk/anthropic';
|
||||||
import { AzureOpenAIProviderSettings, createAzure } from '@ai-sdk/azure';
|
import { AzureOpenAIProviderSettings, createAzure } from '@ai-sdk/azure';
|
||||||
import { createOllama, OllamaProviderSettings } from 'ollama-ai-provider';
|
import { createOllama, OllamaProviderSettings } from 'ollama-ai-provider';
|
||||||
|
import { getRules } from './getRules';
|
||||||
|
|
||||||
export type ApiConfig = {
|
export type ApiConfig = {
|
||||||
/** @default 'anthropic' */
|
/** @default 'anthropic' */
|
||||||
|
|
@ -142,24 +143,29 @@ const sendGreptileMsg: SendLLMMessageFnTypeInternal = ({ messages, onText, onFin
|
||||||
export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
|
export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText, onFinalMessage, apiConfig }) => {
|
||||||
if (!apiConfig) return { abort: () => { } }
|
if (!apiConfig) return { abort: () => { } }
|
||||||
const provider = apiConfig.provider
|
const provider = apiConfig.provider
|
||||||
// TODO: create an @ai-sdk provider for greptile
|
// TODO: create an @ai-sdk provider for greptile,
|
||||||
if (provider === 'greptile')
|
if (provider === 'greptile')
|
||||||
return sendGreptileMsg({ messages, onText, onFinalMessage, apiConfig })
|
return sendGreptileMsg({ messages, onText, onFinalMessage, apiConfig })
|
||||||
|
|
||||||
const model = getAiModel(apiConfig)
|
const model = getAiModel(apiConfig)
|
||||||
|
|
||||||
const abortController = new AbortController()
|
const abortController = new AbortController()
|
||||||
const abortSignal = abortController.signal
|
const abortSignal = abortController.signal
|
||||||
streamText({
|
|
||||||
model,
|
getRules().then(rules => {
|
||||||
messages,
|
streamText({
|
||||||
abortSignal,
|
model,
|
||||||
}).then(async (result) => {
|
system: rules || '',
|
||||||
let fullText = ''
|
messages,
|
||||||
for await (const textPart of result.textStream) {
|
abortSignal,
|
||||||
fullText += textPart
|
}).then(async (result) => {
|
||||||
onText(textPart, fullText)
|
let fullText = ''
|
||||||
}
|
for await (const textPart of result.textStream) {
|
||||||
onFinalMessage(fullText)
|
fullText += textPart
|
||||||
|
onText(textPart, fullText)
|
||||||
|
}
|
||||||
|
onFinalMessage(fullText)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return { abort: abortController.abort }
|
return { abort: abortController.abort }
|
||||||
|
|
@ -167,20 +173,28 @@ export const sendLLMMessage: SendLLMMessageFnTypeExternal = ({ messages, onText,
|
||||||
|
|
||||||
export const getAiModel = (apiConfig: ApiConfig) => {
|
export const getAiModel = (apiConfig: ApiConfig) => {
|
||||||
switch (apiConfig.provider) {
|
switch (apiConfig.provider) {
|
||||||
case 'openai': return createOpenAI({
|
case 'openai':
|
||||||
...apiConfig.openai.providerSettings,
|
return createOpenAI({
|
||||||
apiKey: apiConfig.openai.apiKey,
|
...apiConfig.openai.providerSettings,
|
||||||
})(apiConfig.openai.model || 'gpt-4o')
|
apiKey: apiConfig.openai.apiKey,
|
||||||
case 'anthropic': return createAnthropic({
|
})(apiConfig.openai.model || 'gpt-4o')
|
||||||
...apiConfig.anthropic.providerSettings,
|
|
||||||
apiKey: apiConfig.anthropic.apiKey,
|
case 'anthropic':
|
||||||
})(apiConfig.anthropic.model || 'claude-3-5-sonnet-20240620')
|
return createAnthropic({
|
||||||
case 'ollama': return createOllama(apiConfig.ollama.providerSettings)(apiConfig.ollama.model || 'llama3.1')
|
...apiConfig.anthropic.providerSettings,
|
||||||
case 'azure': return createAzure({
|
apiKey: apiConfig.anthropic.apiKey,
|
||||||
...apiConfig.azure.providerSettings,
|
})(apiConfig.anthropic.model || 'claude-3-5-sonnet-20240620')
|
||||||
apiKey: apiConfig.azure.apiKey,
|
|
||||||
resourceName: apiConfig.azure.resourceName,
|
case 'ollama':
|
||||||
})(`${apiConfig.azure.deploymentId}`)
|
return createOllama(apiConfig.ollama.providerSettings)(apiConfig.ollama.model || 'llama3.1')
|
||||||
|
|
||||||
|
case 'azure':
|
||||||
|
return createAzure({
|
||||||
|
...apiConfig.azure.providerSettings,
|
||||||
|
apiKey: apiConfig.azure.apiKey,
|
||||||
|
resourceName: apiConfig.azure.resourceName,
|
||||||
|
})(`${apiConfig.azure.deploymentId}`)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`Error: provider was ${apiConfig.provider}, which is not recognized!`)
|
throw new Error(`Error: provider was ${apiConfig.provider}, which is not recognized!`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,22 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
// Receive messages in the extension from the sidebar webview (messages are sent using `postMessage`)
|
// Receive messages in the extension from the sidebar webview (messages are sent using `postMessage`)
|
||||||
webview.onDidReceiveMessage(async (m: WebviewMessage) => {
|
webview.onDidReceiveMessage(async (m: WebviewMessage) => {
|
||||||
|
|
||||||
if (m.type === 'requestFiles') {
|
if (m.type === 'getRules') {
|
||||||
|
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
|
||||||
|
if (workspaceFolder) {
|
||||||
|
const rulesFilePath = vscode.Uri.joinPath(workspaceFolder.uri, '.voidrules');
|
||||||
|
try {
|
||||||
|
const rulesContent = await readFileContentOfUri(rulesFilePath);
|
||||||
|
webview.postMessage({ type: 'getRules', rules: rulesContent } satisfies WebviewMessage);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading .voidrules file:', error);
|
||||||
|
webview.postMessage({ type: 'getRules', rules: null } satisfies WebviewMessage);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
webview.postMessage({ type: 'getRules', rules: null } satisfies WebviewMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m.type === 'requestFiles') {
|
||||||
|
|
||||||
// get contents of all file paths
|
// get contents of all file paths
|
||||||
const files = await Promise.all(
|
const files = await Promise.all(
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,9 @@ type WebviewMessage = (
|
||||||
// editor -> sidebar
|
// editor -> sidebar
|
||||||
| { type: 'apiConfig', apiConfig: ApiConfig }
|
| { type: 'apiConfig', apiConfig: ApiConfig }
|
||||||
|
|
||||||
|
// sidebar -> editor
|
||||||
|
| { type: 'getRules', rules: string | null }
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command = WebviewMessage['type']
|
type Command = WebviewMessage['type']
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ const Sidebar = () => {
|
||||||
{!selection?.selectionStr ? null
|
{!selection?.selectionStr ? null
|
||||||
: (
|
: (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<button
|
<button
|
||||||
onClick={clearSelection}
|
onClick={clearSelection}
|
||||||
className="absolute top-2 right-2 text-white hover:text-gray-300 z-10"
|
className="absolute top-2 right-2 text-white hover:text-gray-300 z-10"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ const awaiting: { [c in Command]: ((res: any) => void)[] } = {
|
||||||
"requestFiles": [],
|
"requestFiles": [],
|
||||||
"files": [],
|
"files": [],
|
||||||
"apiConfig": [],
|
"apiConfig": [],
|
||||||
"getApiConfig": []
|
"getApiConfig": [],
|
||||||
|
"getRules": []
|
||||||
}
|
}
|
||||||
|
|
||||||
// use this function to await responses
|
// use this function to await responses
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue