llms-py 3.0.4__py3-none-any.whl → 3.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- llms/db.py +1 -1
- llms/llms.json +1 -1
- llms/main.py +16 -4
- llms/ui/ai.mjs +1 -1
- llms/ui/modules/chat/index.mjs +58 -0
- {llms_py-3.0.4.dist-info → llms_py-3.0.6.dist-info}/METADATA +1 -1
- {llms_py-3.0.4.dist-info → llms_py-3.0.6.dist-info}/RECORD +11 -11
- {llms_py-3.0.4.dist-info → llms_py-3.0.6.dist-info}/WHEEL +0 -0
- {llms_py-3.0.4.dist-info → llms_py-3.0.6.dist-info}/entry_points.txt +0 -0
- {llms_py-3.0.4.dist-info → llms_py-3.0.6.dist-info}/licenses/LICENSE +0 -0
- {llms_py-3.0.4.dist-info → llms_py-3.0.6.dist-info}/top_level.txt +0 -0
llms/db.py
CHANGED
llms/llms.json
CHANGED
llms/main.py
CHANGED
|
@@ -41,7 +41,7 @@ try:
|
|
|
41
41
|
except ImportError:
|
|
42
42
|
HAS_PIL = False
|
|
43
43
|
|
|
44
|
-
VERSION = "3.0.
|
|
44
|
+
VERSION = "3.0.6"
|
|
45
45
|
_ROOT = None
|
|
46
46
|
DEBUG = os.getenv("DEBUG") == "1"
|
|
47
47
|
MOCK = os.getenv("MOCK") == "1"
|
|
@@ -1829,7 +1829,10 @@ def print_status():
|
|
|
1829
1829
|
|
|
1830
1830
|
|
|
1831
1831
|
def home_llms_path(filename):
|
|
1832
|
-
|
|
1832
|
+
home_dir = os.getenv("LLMS_HOME", os.path.join(os.getenv("HOME"), ".llms"))
|
|
1833
|
+
relative_path = os.path.join(home_dir, filename)
|
|
1834
|
+
# return resolved full absolute path
|
|
1835
|
+
return os.path.abspath(os.path.normpath(relative_path))
|
|
1833
1836
|
|
|
1834
1837
|
|
|
1835
1838
|
def get_cache_path(path=""):
|
|
@@ -2703,7 +2706,7 @@ class ExtensionContext:
|
|
|
2703
2706
|
|
|
2704
2707
|
|
|
2705
2708
|
def get_extensions_path():
|
|
2706
|
-
return os.getenv("LLMS_EXTENSIONS_DIR",
|
|
2709
|
+
return os.getenv("LLMS_EXTENSIONS_DIR", home_llms_path("extensions"))
|
|
2707
2710
|
|
|
2708
2711
|
|
|
2709
2712
|
def get_disabled_extensions():
|
|
@@ -2731,6 +2734,11 @@ def get_extensions_dirs():
|
|
|
2731
2734
|
disabled_extensions = get_disabled_extensions()
|
|
2732
2735
|
|
|
2733
2736
|
builtin_extensions_dir = _ROOT / "extensions"
|
|
2737
|
+
if not os.path.exists(builtin_extensions_dir):
|
|
2738
|
+
# look for local ./extensions dir from script
|
|
2739
|
+
builtin_extensions_dir = os.path.join(os.path.dirname(__file__), "extensions")
|
|
2740
|
+
|
|
2741
|
+
_dbg(f"Loading extensions from {builtin_extensions_dir}")
|
|
2734
2742
|
if os.path.exists(builtin_extensions_dir):
|
|
2735
2743
|
for item in os.listdir(builtin_extensions_dir):
|
|
2736
2744
|
if os.path.isdir(os.path.join(builtin_extensions_dir, item)):
|
|
@@ -3463,8 +3471,10 @@ def main():
|
|
|
3463
3471
|
cache_root = Path(get_cache_path())
|
|
3464
3472
|
requested_path = Path(info_path).resolve()
|
|
3465
3473
|
if not str(requested_path).startswith(str(cache_root)):
|
|
3474
|
+
_dbg(f"Forbidden: {requested_path} is not in {cache_root}")
|
|
3466
3475
|
return web.Response(text="403: Forbidden", status=403)
|
|
3467
|
-
except Exception:
|
|
3476
|
+
except Exception as e:
|
|
3477
|
+
_err(f"Forbidden: {requested_path} is not in {cache_root}", e)
|
|
3468
3478
|
return web.Response(text="403: Forbidden", status=403)
|
|
3469
3479
|
|
|
3470
3480
|
with open(info_path) as f:
|
|
@@ -3479,8 +3489,10 @@ def main():
|
|
|
3479
3489
|
cache_root = Path(get_cache_path())
|
|
3480
3490
|
requested_path = Path(full_path).resolve()
|
|
3481
3491
|
if not str(requested_path).startswith(str(cache_root)):
|
|
3492
|
+
_dbg(f"Forbidden: {requested_path} is not in {cache_root}")
|
|
3482
3493
|
return web.Response(text="403: Forbidden", status=403)
|
|
3483
3494
|
except Exception:
|
|
3495
|
+
_err(f"Forbidden: {requested_path} is not in {cache_root}", e)
|
|
3484
3496
|
return web.Response(text="403: Forbidden", status=403)
|
|
3485
3497
|
|
|
3486
3498
|
mimetype = get_file_mime_type(full_path)
|
llms/ui/ai.mjs
CHANGED
llms/ui/modules/chat/index.mjs
CHANGED
|
@@ -115,6 +115,7 @@ export function addCopyButtons() {
|
|
|
115
115
|
|
|
116
116
|
export function useChatPrompt(ctx) {
|
|
117
117
|
const messageText = ref('')
|
|
118
|
+
const promptHistory = ref([])
|
|
118
119
|
const attachedFiles = ref([])
|
|
119
120
|
const hasImage = () => attachedFiles.value.some(f => imageExts.includes(lastRightPart(f.name, '.')))
|
|
120
121
|
const hasAudio = () => attachedFiles.value.some(f => audioExts.includes(lastRightPart(f.name, '.')))
|
|
@@ -363,6 +364,7 @@ export function useChatPrompt(ctx) {
|
|
|
363
364
|
createContent,
|
|
364
365
|
createRequest,
|
|
365
366
|
applySettings,
|
|
367
|
+
promptHistory,
|
|
366
368
|
messageText,
|
|
367
369
|
attachedFiles,
|
|
368
370
|
editingMessage,
|
|
@@ -420,6 +422,7 @@ const ChatPrompt = {
|
|
|
420
422
|
<textarea
|
|
421
423
|
ref="refMessage"
|
|
422
424
|
v-model="messageText"
|
|
425
|
+
@keydown="onKeyDown"
|
|
423
426
|
@keydown.enter.exact.prevent="sendMessage"
|
|
424
427
|
@keydown.enter.shift.exact="addNewLine"
|
|
425
428
|
@paste="onPaste"
|
|
@@ -491,6 +494,7 @@ const ChatPrompt = {
|
|
|
491
494
|
const config = ctx.state.config
|
|
492
495
|
const {
|
|
493
496
|
messageText,
|
|
497
|
+
promptHistory,
|
|
494
498
|
hasImage,
|
|
495
499
|
hasAudio,
|
|
496
500
|
hasFile,
|
|
@@ -500,6 +504,8 @@ const ChatPrompt = {
|
|
|
500
504
|
const fileInput = ref(null)
|
|
501
505
|
const refMessage = ref(null)
|
|
502
506
|
const showSettings = ref(false)
|
|
507
|
+
const historyIndex = ref(-1)
|
|
508
|
+
const isNavigatingHistory = ref(false)
|
|
503
509
|
|
|
504
510
|
// File attachments (+) handlers
|
|
505
511
|
const triggerFilePicker = () => {
|
|
@@ -639,6 +645,14 @@ const ChatPrompt = {
|
|
|
639
645
|
// 1. Construct Structured Content (Text + Attachments)
|
|
640
646
|
let text = messageText.value.trim()
|
|
641
647
|
|
|
648
|
+
if (text) {
|
|
649
|
+
const idx = promptHistory.value.indexOf(text)
|
|
650
|
+
if (idx !== -1) {
|
|
651
|
+
promptHistory.value.splice(idx, 1)
|
|
652
|
+
}
|
|
653
|
+
promptHistory.value.push(text)
|
|
654
|
+
}
|
|
655
|
+
|
|
642
656
|
messageText.value = ''
|
|
643
657
|
let content = ctx.chat.createContent({ text, files: ctx.chat.attachedFiles.value })
|
|
644
658
|
|
|
@@ -742,6 +756,49 @@ const ChatPrompt = {
|
|
|
742
756
|
//messageText.value += '\n'
|
|
743
757
|
}
|
|
744
758
|
|
|
759
|
+
const onKeyDown = (e) => {
|
|
760
|
+
if (e.key === 'ArrowUp') {
|
|
761
|
+
if (refMessage.value.selectionStart === 0 && refMessage.value.selectionEnd === 0) {
|
|
762
|
+
if (promptHistory.value.length > 0) {
|
|
763
|
+
e.preventDefault()
|
|
764
|
+
if (historyIndex.value === -1) {
|
|
765
|
+
historyIndex.value = promptHistory.value.length - 1
|
|
766
|
+
} else {
|
|
767
|
+
historyIndex.value = Math.max(0, historyIndex.value - 1)
|
|
768
|
+
}
|
|
769
|
+
isNavigatingHistory.value = true
|
|
770
|
+
messageText.value = promptHistory.value[historyIndex.value]
|
|
771
|
+
nextTick(() => {
|
|
772
|
+
refMessage.value.setSelectionRange(0, 0)
|
|
773
|
+
})
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
} else if (e.key === 'ArrowDown') {
|
|
777
|
+
if (historyIndex.value !== -1) {
|
|
778
|
+
e.preventDefault()
|
|
779
|
+
if (historyIndex.value < promptHistory.value.length - 1) {
|
|
780
|
+
historyIndex.value++
|
|
781
|
+
isNavigatingHistory.value = true
|
|
782
|
+
messageText.value = promptHistory.value[historyIndex.value]
|
|
783
|
+
} else {
|
|
784
|
+
historyIndex.value = -1
|
|
785
|
+
isNavigatingHistory.value = true
|
|
786
|
+
messageText.value = ''
|
|
787
|
+
}
|
|
788
|
+
nextTick(() => {
|
|
789
|
+
refMessage.value.setSelectionRange(0, 0)
|
|
790
|
+
})
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
watch(messageText, (newValue) => {
|
|
796
|
+
if (!isNavigatingHistory.value) {
|
|
797
|
+
historyIndex.value = -1
|
|
798
|
+
}
|
|
799
|
+
isNavigatingHistory.value = false
|
|
800
|
+
})
|
|
801
|
+
|
|
745
802
|
watch(() => ctx.state.selectedAspectRatio, newValue => {
|
|
746
803
|
ctx.setPrefs({ aspectRatio: newValue })
|
|
747
804
|
})
|
|
@@ -769,6 +826,7 @@ const ChatPrompt = {
|
|
|
769
826
|
removeAttachment,
|
|
770
827
|
sendMessage,
|
|
771
828
|
addNewLine,
|
|
829
|
+
onKeyDown,
|
|
772
830
|
imageAspectRatios,
|
|
773
831
|
}
|
|
774
832
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
llms/__init__.py,sha256=DKwTZDsyYL_wHe7yvLw49Nf8PSgPSyWaeVdotUqSvrQ,84
|
|
2
2
|
llms/__main__.py,sha256=hrBulHIt3lmPm1BCyAEVtB6DQ0Hvc3gnIddhHCmJasg,151
|
|
3
|
-
llms/db.py,sha256=
|
|
3
|
+
llms/db.py,sha256=oozp5I5lECVO8oZEFwcZl3ES5mARqWeR1BkoqG5kSqM,11687
|
|
4
4
|
llms/index.html,sha256=nGk1Djtn9p7l6LuKp4Kg0JIB9fCzxtTWXFfmDb4ggpc,1658
|
|
5
|
-
llms/llms.json,sha256=
|
|
6
|
-
llms/main.py,sha256
|
|
5
|
+
llms/llms.json,sha256=esbR3GFEFura3Ajw02HjepGf0AlJPFhQlOPBjT_Lekc,11156
|
|
6
|
+
llms/main.py,sha256=-KhtOKzdJeKj27FjIEaqKuL-dE2ejYAcnPsZrY3j0CE,157027
|
|
7
7
|
llms/providers-extra.json,sha256=w7_5gB0YUPK0PJNeViM7vRDfNGChXUKMHfGHenVxEkM,10165
|
|
8
8
|
llms/providers.json,sha256=Hc1STJW9hqM_MWBjeJljs_0I3bTo6qhGlEsL0o-dUuA,285221
|
|
9
9
|
llms/extensions/analytics/ui/index.mjs,sha256=cr9dPmEJjha2xX6A_7xbJxkOolWFP1p6TgIoO8M8juI,69540
|
|
@@ -142,7 +142,7 @@ llms/extensions/system_prompts/ui/prompts.json,sha256=t5DD3bird-87wFa4OlW-bC2wdo
|
|
|
142
142
|
llms/extensions/tools/__init__.py,sha256=yfIK7dVqYiZGX5VeJ3x7HQWLPQfuPqeNYJsd0lpZUM4,120
|
|
143
143
|
llms/extensions/tools/ui/index.mjs,sha256=Nu69U6odCUh8uu1i8d5f8ryO4Lj_OFbPX2LnVyYu1fk,9602
|
|
144
144
|
llms/ui/App.mjs,sha256=zU-GtbcSMREizjUS9nWiMK6m_oT14MNJ-p_RCz2RVqA,7445
|
|
145
|
-
llms/ui/ai.mjs,sha256=
|
|
145
|
+
llms/ui/ai.mjs,sha256=9bLrX3OSrJBTU3wiOehxwvpInpsyvmDMkiopLiUGclY,6540
|
|
146
146
|
llms/ui/app.css,sha256=6iQiPeFZ_7pcf6RB1b7tvh6EY22A9lCn9SCCmoJKP2I,176402
|
|
147
147
|
llms/ui/ctx.mjs,sha256=eFTkWzVBKRU5YDFFVUq3ZDd6eMPa4VRQpE3q0O5Sfgg,12337
|
|
148
148
|
llms/ui/fav.svg,sha256=_R6MFeXl6wBFT0lqcUxYQIDWgm246YH_3hSTW0oO8qw,734
|
|
@@ -167,10 +167,10 @@ llms/ui/modules/layout.mjs,sha256=8pAxs8bedQI3b3eRA9nrfpLZznLmrpp4BZvigYAQjpQ,12
|
|
|
167
167
|
llms/ui/modules/model-selector.mjs,sha256=6U4rAZ7vmQELFRQGWk4YEtq02v3lyHdMq6yUOp-ArXg,43184
|
|
168
168
|
llms/ui/modules/chat/ChatBody.mjs,sha256=YbpIEl6OeBi1RqCPkW5UFbUk6qNi5B_GfRUK5Pmfms8,42875
|
|
169
169
|
llms/ui/modules/chat/SettingsDialog.mjs,sha256=HMBJTwrapKrRIAstIIqp0QlJL5O-ho4hzgvfagPfsX8,19930
|
|
170
|
-
llms/ui/modules/chat/index.mjs,sha256=
|
|
171
|
-
llms_py-3.0.
|
|
172
|
-
llms_py-3.0.
|
|
173
|
-
llms_py-3.0.
|
|
174
|
-
llms_py-3.0.
|
|
175
|
-
llms_py-3.0.
|
|
176
|
-
llms_py-3.0.
|
|
170
|
+
llms/ui/modules/chat/index.mjs,sha256=3arA5PigH6BdBDqi5SbgcNkEIETENYNNxWF3Ro7HFsM,39349
|
|
171
|
+
llms_py-3.0.6.dist-info/licenses/LICENSE,sha256=bus9cuAOWeYqBk2OuhSABVV1P4z7hgrEFISpyda_H5w,1532
|
|
172
|
+
llms_py-3.0.6.dist-info/METADATA,sha256=o8-oUNHj2mr942bU-M_MOWCm3LQOk0IcSl3sYrlxk6g,2191
|
|
173
|
+
llms_py-3.0.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
174
|
+
llms_py-3.0.6.dist-info/entry_points.txt,sha256=WswyE7PfnkZMIxboC-MS6flBD6wm-CYU7JSUnMhqMfM,40
|
|
175
|
+
llms_py-3.0.6.dist-info/top_level.txt,sha256=gC7hk9BKSeog8gyg-EM_g2gxm1mKHwFRfK-10BxOsa4,5
|
|
176
|
+
llms_py-3.0.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|