') 594 | // document.insertText(' / ') 595 | // } 596 | 597 | } 598 | let tokensByEndpoint = {} 599 | 600 | async function getSuggestion(prompt, { suffix }) { 601 | 602 | let { 603 | endpoint, auth, promptKey, otherBodyParams, arrayKey, resultKey, suffixKey 604 | } = settings.api 605 | 606 | // console.log({suffixKey, suffix}) 607 | // Get the suggestion from the external API. 608 | let json = await( 609 | await fetch( 610 | endpoint, 611 | { 612 | method: 'POST', 613 | headers: { 614 | 'Content-Type': 'application/json', 615 | 'Authorization': `${auth}` 616 | }, 617 | body: JSON.stringify({ 618 | [promptKey]: prompt, 619 | ...( suffixKey && suffix ) ? { [suffixKey]: suffix } : {}, 620 | ...otherBodyParams 621 | }) 622 | } 623 | ) 624 | ).json() 625 | 626 | let completion = get(arrayKey ? json[arrayKey][0] : json, resultKey) 627 | 628 | // Log token stats via encode(...).length 629 | console.log('Token stats:') 630 | console.log('Prompt:', encode(prompt).length) 631 | suffix && console.log('Suffix:', encode(suffix).length) 632 | console.log('Completion:', encode(completion).length) 633 | 634 | let totalTokens = [prompt, suffix, completion].map(encode).map(s => s.length).reduce((a, b) => a + b) 635 | 636 | console.log('Total tokens:', totalTokens) 637 | 638 | tokensByEndpoint[endpoint] = ( tokensByEndpoint[endpoint] || 0 ) + totalTokens 639 | 640 | console.log('Tokens by endpoint:', tokensByEndpoint) 641 | 642 | return completion 643 | 644 | } 645 | 646 | function saveSettings() { 647 | // Save to chrome storage 648 | chrome.storage.sync.set({ settings }, () => { 649 | // console.log('Saved config to chrome storage:', settings) 650 | }) 651 | } 652 | 653 | 654 | enable() -------------------------------------------------------------------------------- /lodashish.js: -------------------------------------------------------------------------------- 1 | // Various lodash-like functions 2 | 3 | // Get value by path in an object 4 | function get(obj, path) { 5 | return path.split('.').reduce((acc, part) => acc && acc[part], obj) 6 | } 7 | 8 | // Set value by path in an object 9 | function set(obj, path, value) { 10 | const parts = path.split('.') 11 | const last = parts.pop() 12 | const parent = parts.reduce((acc, part) => acc && acc[part], obj) 13 | parent[last] = value 14 | } 15 | 16 | // Escape regex characters in a string 17 | function escapeRegExp(str) { 18 | return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') 19 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Komple", 3 | "description": "Autocomplete with large language models on (almost) any web page", 4 | "version": "0.1", 5 | "icons": { 6 | "128": "icon128.png" 7 | }, 8 | "permissions": [ 9 | "tabs","
Action | 306 |Hotkey | 307 |
---|---|
318 | | 319 | 320 | 349 | | 350 |
365 | If checked, the autocomplete will be activated on a hanging character like space, comma, etc. WARNING: This can cause your tokens to deplete quickly. 366 |
367 |385 | If checked, newlines will be removed from the output. This can be useful for websites that handle newlines differently (e.g. Twitter) 386 |
387 |395 | WARNING: This is an advanced feature. Changing the JSON might break the settings, in which case they will be reset to their default values. 396 |
397 | 398 | 416 | 417 | 428 |