add more logs and catches to ai chat (#5524)

This commit is contained in:
HugoCasa
2025-03-27 18:36:31 +01:00
committed by GitHub
parent d5d020ef72
commit fc3d2cd985
2 changed files with 162 additions and 120 deletions

View File

@@ -196,7 +196,7 @@
| 'csharp'
| 'nu'
| 'java'
// KJQXZ
// KJQXZ
export let code: string = ''
export let cmdEnterAction: (() => void) | undefined = undefined
export let formatAction: (() => void) | undefined = undefined
@@ -612,8 +612,12 @@
}
function addChatHandler(editor: meditor.IStandaloneCodeEditor) {
aiChatEditorHandler = new AIChatEditorHandler(editor)
reviewingChanges = aiChatEditorHandler.reviewingChanges
try {
aiChatEditorHandler = new AIChatEditorHandler(editor)
reviewingChanges = aiChatEditorHandler.reviewingChanges
} catch (err) {
console.error('Could not add chat handler', err)
}
}
$: $reviewingChanges && autocompletor?.reject()
@@ -621,58 +625,62 @@
let completorDisposable: Disposable | undefined = undefined
let autocompletor: Autocompletor | undefined = undefined
function addSuperCompletor(editor: meditor.IStandaloneCodeEditor) {
if (completorDisposable) {
completorDisposable.dispose()
}
autocompletor = new Autocompletor(editor, lang)
// last user events (currently disabled):
// let lastTs = Date.now()
// editor.onDidChangeModelContent((e) => {
// const thisTs = Date.now()
// lastTs = thisTs
// setTimeout(() => {
// if (thisTs === lastTs) {
// autocompletor?.savePatch()
// }
// }, 150)
// })
completorDisposable = editor.onDidChangeCursorPosition((e) => {
autocompletor?.reject()
if ($reviewingChanges) {
return
try {
if (completorDisposable) {
completorDisposable.dispose()
}
const position = editor.getPosition()
if (!position) {
return
}
const upToText = editor.getModel()?.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 0,
endLineNumber: position.lineNumber,
endColumn: position.column
})
const lastChar = upToText ? upToText[upToText.length - 1] : ''
if (lastChar && lastChar.match(/[\(\{\s:="',]/)) {
autocompletor?.predict()
}
})
autocompletor = new Autocompletor(editor, lang)
editor.addCommand(KeyCode.Tab, () => {
if (autocompletor?.hasChanges()) {
autocompletor?.accept()
autocompletor?.predict()
} else {
editor.trigger('keyboard', 'tab', {})
}
})
// last user events (currently disabled):
// let lastTs = Date.now()
// editor.onDidChangeModelContent((e) => {
// const thisTs = Date.now()
// lastTs = thisTs
// setTimeout(() => {
// if (thisTs === lastTs) {
// autocompletor?.savePatch()
// }
// }, 150)
// })
editor.onKeyDown((e) => {
if (e.keyCode === KeyCode.Escape) {
completorDisposable = editor.onDidChangeCursorPosition((e) => {
autocompletor?.reject()
}
})
if ($reviewingChanges) {
return
}
const position = editor.getPosition()
if (!position) {
return
}
const upToText = editor.getModel()?.getValueInRange({
startLineNumber: position.lineNumber,
startColumn: 0,
endLineNumber: position.lineNumber,
endColumn: position.column
})
const lastChar = upToText ? upToText[upToText.length - 1] : ''
if (lastChar && lastChar.match(/[\(\{\s:="',]/)) {
autocompletor?.predict()
}
})
editor.addCommand(KeyCode.Tab, () => {
if (autocompletor?.hasChanges()) {
autocompletor?.accept()
autocompletor?.predict()
} else {
editor.trigger('keyboard', 'tab', {})
}
})
editor.onKeyDown((e) => {
if (e.keyCode === KeyCode.Escape) {
autocompletor?.reject()
}
})
} catch (err) {
console.error('Could not add supercompletor', err)
}
}
$: $copilotInfo.enabled &&

View File

@@ -25,36 +25,44 @@
export let args: Record<string, any>
export let path: string | undefined
$: contextCodePath =
(path?.split('/').pop() ?? 'script') + '.' + langToExt(scriptLangToEditorLang(lang))
$: contextCodePath = path
? path.split('/').pop() + '.' + langToExt(scriptLangToEditorLang(lang))
: undefined
let initializedWithInitCode: boolean | null = null
$: lang && (initializedWithInitCode = null)
function onCodeChange() {
if (initializedWithInitCode === null && code) {
if (isInitialCode(code)) {
initializedWithInitCode = true
} else {
initializedWithInitCode = false
if (!contextCodePath) {
return
}
try {
if (initializedWithInitCode === null && code) {
if (isInitialCode(code)) {
initializedWithInitCode = true
} else {
initializedWithInitCode = false
selectedContext = [
{
type: 'code',
title: contextCodePath
}
]
}
} else if (initializedWithInitCode) {
// if the code was initial and was changed, add code context, then prevent it from being added again
selectedContext = [
{
type: 'code',
title: contextCodePath
}
]
initializedWithInitCode = false
}
} else if (initializedWithInitCode) {
// if the code was initial and was changed, add code context, then prevent it from being added again
selectedContext = [
{
type: 'code',
title: contextCodePath
}
]
initializedWithInitCode = false
} catch (err) {
console.error('Could not update context', err)
}
}
$: code && onCodeChange()
$: contextCodePath && code && onCodeChange()
let db: { schema: DBSchema; resource: string } | undefined = undefined
@@ -63,17 +71,21 @@
args: Record<string, any>,
dbSchemas: DBSchemas
) {
const schemaRes = lang === 'graphql' ? args.api : args.database
if (typeof schemaRes === 'string') {
const schemaPath = schemaRes.replace('$res:', '')
const schema = dbSchemas[schemaPath]
if (schema && schema.lang === lang) {
db = { schema, resource: schemaPath }
try {
const schemaRes = lang === 'graphql' ? args.api : args.database
if (typeof schemaRes === 'string') {
const schemaPath = schemaRes.replace('$res:', '')
const schema = dbSchemas[schemaPath]
if (schema && schema.lang === lang) {
db = { schema, resource: schemaPath }
} else {
db = undefined
}
} else {
db = undefined
}
} else {
db = undefined
} catch (err) {
console.error('Could not update schema', err)
}
}
$: updateSchema(lang, args, $dbSchemas)
@@ -83,42 +95,49 @@
let availableContext: ContextElement[] = []
function updateAvailableContext(
contextCodePath: string,
contextCodePath: string | undefined,
code: string,
lang: ScriptLang | 'bunnative',
error: string | undefined,
db: { schema: DBSchema; resource: string } | undefined,
providerModel: AIProviderModel | undefined
) {
availableContext = [
{
type: 'code',
title: contextCodePath,
content: code,
lang
}
]
if (error) {
availableContext = [
...availableContext,
{
type: 'error',
title: 'error',
content: error
}
]
if (!contextCodePath) {
return
}
if (db && !providerModel?.model.endsWith('/thinking')) {
try {
availableContext = [
...availableContext,
{
type: 'db',
title: db.resource,
schema: db.schema
type: 'code',
title: contextCodePath,
content: code,
lang
}
]
if (error) {
availableContext = [
...availableContext,
{
type: 'error',
title: 'error',
content: error
}
]
}
if (db && !providerModel?.model.endsWith('/thinking')) {
availableContext = [
...availableContext,
{
type: 'db',
title: db.resource,
schema: db.schema
}
]
}
} catch (err) {
console.error('Could not update available context', err)
}
}
@@ -163,17 +182,22 @@
let abortController: AbortController | undefined = undefined
function updateSelectedContextElements() {
const contextElements: ContextElement[] = []
try {
const contextElements: ContextElement[] = []
for (const selected of selectedContext) {
const el = availableContext.find(
(c) => c.type === selected.type && c.title === selected.title
)
if (el) {
contextElements.push(el)
for (const selected of selectedContext) {
const el = availableContext.find(
(c) => c.type === selected.type && c.title === selected.title
)
if (el) {
contextElements.push(el)
}
}
return contextElements
} catch (err) {
console.error('Could not update selected context elements', err)
return []
}
return contextElements
}
let selectedContextElements: ContextElement[] = []
@@ -289,6 +313,9 @@
}
export function fix() {
if (!contextCodePath) {
return
}
instructions = 'Fix the error'
selectedContext = [
@@ -320,19 +347,26 @@
let indexDB: IDBPDatabase<ChatSchema> | undefined = undefined
async function initIndexDB() {
indexDB = await openDB<ChatSchema>('copilot-chat-history', 1, {
upgrade(indexDB) {
if (!indexDB.objectStoreNames.contains('chats')) {
indexDB.createObjectStore('chats', { keyPath: 'id' })
try {
console.log('Initializing chat history database')
indexDB = await openDB<ChatSchema>('copilot-chat-history', 1, {
upgrade(indexDB) {
if (!indexDB.objectStoreNames.contains('chats')) {
indexDB.createObjectStore('chats', { keyPath: 'id' })
}
}
}
})
})
console.log('Chat history database initialized')
const chats = await indexDB.getAll('chats')
savedChats = chats.reduce((acc, chat) => {
acc[chat.id] = chat
return acc
}, {} as typeof savedChats)
const chats = await indexDB.getAll('chats')
console.log('Retrieved chats')
savedChats = chats.reduce((acc, chat) => {
acc[chat.id] = chat
return acc
}, {} as typeof savedChats)
} catch (err) {
console.error('Could not open chat history database', err)
}
}
initIndexDB()