Compare commits

...

1 Commits

Author SHA1 Message Date
HugoCasa
58bf036613 fix: use uuid instead of crypto for unique ids in AI chat 2025-03-27 23:22:49 +01:00
5 changed files with 95 additions and 97 deletions

View File

@@ -62,6 +62,7 @@
"svelte-infinite-loading": "^1.4.0", "svelte-infinite-loading": "^1.4.0",
"svelte-tiny-virtual-list": "^2.0.5", "svelte-tiny-virtual-list": "^2.0.5",
"tailwind-merge": "^1.13.2", "tailwind-merge": "^1.13.2",
"uuid": "^11.1.0",
"vscode": "npm:@codingame/monaco-vscode-api@~11.1.2", "vscode": "npm:@codingame/monaco-vscode-api@~11.1.2",
"vscode-languageclient": "~9.0.1", "vscode-languageclient": "~9.0.1",
"vscode-uri": "~3.0.8", "vscode-uri": "~3.0.8",
@@ -12222,6 +12223,19 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"devOptional": true "devOptional": true
}, },
"node_modules/uuid": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/validate-npm-package-license": { "node_modules/validate-npm-package-license": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",

View File

@@ -138,6 +138,7 @@
"svelte-infinite-loading": "^1.4.0", "svelte-infinite-loading": "^1.4.0",
"svelte-tiny-virtual-list": "^2.0.5", "svelte-tiny-virtual-list": "^2.0.5",
"tailwind-merge": "^1.13.2", "tailwind-merge": "^1.13.2",
"uuid": "^11.1.0",
"vscode": "npm:@codingame/monaco-vscode-api@~11.1.2", "vscode": "npm:@codingame/monaco-vscode-api@~11.1.2",
"vscode-languageclient": "~9.0.1", "vscode-languageclient": "~9.0.1",
"vscode-uri": "~3.0.8", "vscode-uri": "~3.0.8",

View File

@@ -612,12 +612,8 @@
} }
function addChatHandler(editor: meditor.IStandaloneCodeEditor) { function addChatHandler(editor: meditor.IStandaloneCodeEditor) {
try { aiChatEditorHandler = new AIChatEditorHandler(editor)
aiChatEditorHandler = new AIChatEditorHandler(editor) reviewingChanges = aiChatEditorHandler.reviewingChanges
reviewingChanges = aiChatEditorHandler.reviewingChanges
} catch (err) {
console.error('Could not add chat handler', err)
}
} }
$: $reviewingChanges && autocompletor?.reject() $: $reviewingChanges && autocompletor?.reject()
@@ -625,62 +621,58 @@
let completorDisposable: Disposable | undefined = undefined let completorDisposable: Disposable | undefined = undefined
let autocompletor: Autocompletor | undefined = undefined let autocompletor: Autocompletor | undefined = undefined
function addSuperCompletor(editor: meditor.IStandaloneCodeEditor) { function addSuperCompletor(editor: meditor.IStandaloneCodeEditor) {
try { if (completorDisposable) {
if (completorDisposable) { completorDisposable.dispose()
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
}
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)
} }
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
}
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()
}
})
} }
$: $copilotInfo.enabled && $: $copilotInfo.enabled &&

View File

@@ -18,6 +18,7 @@
import { isInitialCode } from '$lib/script_helpers' import { isInitialCode } from '$lib/script_helpers'
import { langToExt } from '$lib/editorUtils' import { langToExt } from '$lib/editorUtils'
import { scriptLangToEditorLang } from '$lib/scripts' import { scriptLangToEditorLang } from '$lib/scripts'
import { v4 as uuidv4 } from 'uuid'
export let lang: ScriptLang | 'bunnative' export let lang: ScriptLang | 'bunnative'
export let code: string export let code: string
@@ -35,31 +36,27 @@
if (!contextCodePath) { if (!contextCodePath) {
return return
} }
try { if (initializedWithInitCode === null && code) {
if (initializedWithInitCode === null && code) { if (isInitialCode(code)) {
if (isInitialCode(code)) { initializedWithInitCode = true
initializedWithInitCode = true } else {
} else { initializedWithInitCode = false
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 = [ selectedContext = [
{ {
type: 'code', type: 'code',
title: contextCodePath title: contextCodePath
} }
] ]
initializedWithInitCode = false
} }
} catch (err) { } else if (initializedWithInitCode) {
console.error('Could not update context', err) // 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
} }
} }
$: contextCodePath && code && onCodeChange() $: contextCodePath && code && onCodeChange()
@@ -71,21 +68,17 @@
args: Record<string, any>, args: Record<string, any>,
dbSchemas: DBSchemas dbSchemas: DBSchemas
) { ) {
try { const schemaRes = lang === 'graphql' ? args.api : args.database
const schemaRes = lang === 'graphql' ? args.api : args.database if (typeof schemaRes === 'string') {
if (typeof schemaRes === 'string') { const schemaPath = schemaRes.replace('$res:', '')
const schemaPath = schemaRes.replace('$res:', '') const schema = dbSchemas[schemaPath]
const schema = dbSchemas[schemaPath] if (schema && schema.lang === lang) {
if (schema && schema.lang === lang) { db = { schema, resource: schemaPath }
db = { schema, resource: schemaPath }
} else {
db = undefined
}
} else { } else {
db = undefined db = undefined
} }
} catch (err) { } else {
console.error('Could not update schema', err) db = undefined
} }
} }
$: updateSchema(lang, args, $dbSchemas) $: updateSchema(lang, args, $dbSchemas)
@@ -159,7 +152,7 @@
} }
}) })
let currentChatId: string = crypto.randomUUID() let currentChatId: string = uuidv4()
let savedChats: Record< let savedChats: Record<
string, string,
{ {
@@ -292,7 +285,7 @@
async function saveAndClear() { async function saveAndClear() {
await saveChat() await saveChat()
currentChatId = crypto.randomUUID() currentChatId = uuidv4()
displayMessages = [] displayMessages = []
messages = [prepareSystemMessage()] messages = [prepareSystemMessage()]
} }
@@ -348,7 +341,6 @@
let indexDB: IDBPDatabase<ChatSchema> | undefined = undefined let indexDB: IDBPDatabase<ChatSchema> | undefined = undefined
async function initIndexDB() { async function initIndexDB() {
try { try {
console.log('Initializing chat history database')
indexDB = await openDB<ChatSchema>('copilot-chat-history', 1, { indexDB = await openDB<ChatSchema>('copilot-chat-history', 1, {
upgrade(indexDB) { upgrade(indexDB) {
if (!indexDB.objectStoreNames.contains('chats')) { if (!indexDB.objectStoreNames.contains('chats')) {
@@ -356,10 +348,8 @@
} }
} }
}) })
console.log('Chat history database initialized')
const chats = await indexDB.getAll('chats') const chats = await indexDB.getAll('chats')
console.log('Retrieved chats')
savedChats = chats.reduce((acc, chat) => { savedChats = chats.reduce((acc, chat) => {
acc[chat.id] = chat acc[chat.id] = chat
return acc return acc

View File

@@ -1,4 +1,5 @@
import { type editor as meditor } from 'monaco-editor' import { type editor as meditor } from 'monaco-editor'
import { v4 as uuidv4 } from 'uuid'
export type VisualChange = export type VisualChange =
| { | {
@@ -71,7 +72,7 @@ export function setGlobalCSS(id: string, cssCode: string) {
} }
function addInlineGhostText(change: Extract<VisualChange, { type: 'added_inline' }>) { function addInlineGhostText(change: Extract<VisualChange, { type: 'added_inline' }>) {
const cssId = crypto.randomUUID() const cssId = uuidv4()
const decoration = { const decoration = {
range: { range: {
startLineNumber: change.position.line, startLineNumber: change.position.line,