llms-py 3.0.15__py3-none-any.whl → 3.0.16__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/extensions/computer/__init__.py +59 -0
- llms/extensions/{computer_use → computer}/bash.py +2 -2
- llms/extensions/{computer_use → computer}/edit.py +10 -14
- llms/extensions/computer/filesystem.py +542 -0
- llms/extensions/core_tools/__init__.py +0 -38
- llms/extensions/providers/google.py +57 -30
- llms/extensions/skills/ui/index.mjs +27 -0
- llms/extensions/tools/__init__.py +5 -82
- llms/extensions/tools/ui/index.mjs +92 -4
- llms/main.py +208 -31
- llms/ui/ai.mjs +1 -1
- llms/ui/app.css +491 -0
- llms/ui/modules/chat/ChatBody.mjs +64 -9
- llms/ui/modules/chat/index.mjs +103 -91
- {llms_py-3.0.15.dist-info → llms_py-3.0.16.dist-info}/METADATA +1 -1
- {llms_py-3.0.15.dist-info → llms_py-3.0.16.dist-info}/RECORD +25 -24
- {llms_py-3.0.15.dist-info → llms_py-3.0.16.dist-info}/WHEEL +1 -1
- llms/extensions/computer_use/__init__.py +0 -27
- /llms/extensions/{computer_use → computer}/README.md +0 -0
- /llms/extensions/{computer_use → computer}/base.py +0 -0
- /llms/extensions/{computer_use → computer}/computer.py +0 -0
- /llms/extensions/{computer_use → computer}/platform.py +0 -0
- /llms/extensions/{computer_use → computer}/run.py +0 -0
- {llms_py-3.0.15.dist-info → llms_py-3.0.16.dist-info}/entry_points.txt +0 -0
- {llms_py-3.0.15.dist-info → llms_py-3.0.16.dist-info}/licenses/LICENSE +0 -0
- {llms_py-3.0.15.dist-info → llms_py-3.0.16.dist-info}/top_level.txt +0 -0
|
@@ -29,6 +29,11 @@ function embedHtml(html) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
const ro = new ResizeObserver(sendHeight);
|
|
32
|
+
window.addEventListener('message', (e) => {
|
|
33
|
+
if (e.data && e.data.type === 'stop-resize') {
|
|
34
|
+
ro.disconnect();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
32
37
|
window.addEventListener('load', () => {
|
|
33
38
|
// Inject styles to prevent infinite loops
|
|
34
39
|
const style = document.createElement('style');
|
|
@@ -56,7 +61,7 @@ function embedHtml(html) {
|
|
|
56
61
|
export const TypeText = {
|
|
57
62
|
template: `
|
|
58
63
|
<div data-type="text" v-if="text.type === 'text'">
|
|
59
|
-
|
|
64
|
+
<div v-html="html?.trim()" class="whitespace-pre-wrap"></div>
|
|
60
65
|
</div>
|
|
61
66
|
`,
|
|
62
67
|
props: {
|
|
@@ -377,6 +382,12 @@ export const TextViewer = {
|
|
|
377
382
|
{{ $fmt.humanifyNumber(text.length) }}
|
|
378
383
|
</span>
|
|
379
384
|
|
|
385
|
+
<!-- Copy Button -->
|
|
386
|
+
<button type="button" @click="copyToClipboard" class="text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 focus:outline-none p-0.5 rounded transition-colors" title="Copy to clipboard">
|
|
387
|
+
<svg v-if="copied" class="size-4 text-green-600 dark:text-green-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="m9.55 18l-5.7-5.7l1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4z"/></svg>
|
|
388
|
+
<svg v-else xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24"><path fill="currentColor" d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2m0 16H8V7h11z"/></svg>
|
|
389
|
+
</button>
|
|
390
|
+
|
|
380
391
|
<!-- Maximize Toggle -->
|
|
381
392
|
<button type="button" @click="toggleMaximized" class="text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 focus:outline-none p-0.5 rounded transition-colors" :title="isMaximized ? 'Minimize' : 'Maximize'">
|
|
382
393
|
<svg class="size-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
@@ -391,6 +402,9 @@ export const TextViewer = {
|
|
|
391
402
|
<div v-if="prefs === 'markdown'" class="prose prose-sm max-w-none dark:prose-invert">
|
|
392
403
|
<div v-html="$fmt.markdown(text)"></div>
|
|
393
404
|
</div>
|
|
405
|
+
<div v-else-if="prefs === 'preview' && jsonValue">
|
|
406
|
+
<HtmlFormat :value="jsonValue" />
|
|
407
|
+
</div>
|
|
394
408
|
<div v-else :class="['p-0.5', contentClass]">{{ text }}</div>
|
|
395
409
|
</div>
|
|
396
410
|
</div>
|
|
@@ -402,16 +416,32 @@ export const TextViewer = {
|
|
|
402
416
|
},
|
|
403
417
|
setup(props) {
|
|
404
418
|
const ctx = inject('ctx')
|
|
405
|
-
const textStyles = ['pre', 'normal', 'markdown']
|
|
406
419
|
const prefs = ref('pre')
|
|
407
420
|
const maximized = ref({})
|
|
408
421
|
const dropdownOpen = ref(false)
|
|
409
422
|
const hash = computed(() => ctx.utils.hashString(props.text))
|
|
423
|
+
const jsonValue = computed(() => ctx.utils.toJsonObject(props.text))
|
|
424
|
+
const textStyles = computed(() => {
|
|
425
|
+
const ret = ['pre', 'normal', 'markdown']
|
|
426
|
+
if (jsonValue.value) {
|
|
427
|
+
ret.push('preview')
|
|
428
|
+
}
|
|
429
|
+
return ret
|
|
430
|
+
})
|
|
410
431
|
|
|
411
432
|
const toggleDropdown = () => {
|
|
412
433
|
dropdownOpen.value = !dropdownOpen.value
|
|
413
434
|
}
|
|
414
435
|
|
|
436
|
+
const copied = ref(false)
|
|
437
|
+
const copyToClipboard = () => {
|
|
438
|
+
navigator.clipboard.writeText(props.text)
|
|
439
|
+
copied.value = true
|
|
440
|
+
setTimeout(() => {
|
|
441
|
+
copied.value = false
|
|
442
|
+
}, 2000)
|
|
443
|
+
}
|
|
444
|
+
|
|
415
445
|
const setStyle = (style) => {
|
|
416
446
|
prefs.value = style
|
|
417
447
|
dropdownOpen.value = false
|
|
@@ -453,13 +483,17 @@ export const TextViewer = {
|
|
|
453
483
|
hash,
|
|
454
484
|
textStyles,
|
|
455
485
|
prefs,
|
|
486
|
+
jsonValue,
|
|
456
487
|
dropdownOpen,
|
|
457
488
|
toggleDropdown,
|
|
458
489
|
setStyle,
|
|
459
490
|
isMaximized,
|
|
460
491
|
toggleMaximized,
|
|
492
|
+
|
|
461
493
|
containerClass,
|
|
462
|
-
contentClass
|
|
494
|
+
contentClass,
|
|
495
|
+
copied,
|
|
496
|
+
copyToClipboard
|
|
463
497
|
}
|
|
464
498
|
}
|
|
465
499
|
}
|
|
@@ -507,11 +541,23 @@ export const ToolArguments = {
|
|
|
507
541
|
})
|
|
508
542
|
|
|
509
543
|
const handleMessage = (event) => {
|
|
544
|
+
console.log('handleMessage', event)
|
|
510
545
|
if (event.data?.type === 'iframe-resize' && typeof event.data.height === 'number') {
|
|
511
546
|
const iframes = refArgs.value?.querySelectorAll('iframe')
|
|
512
547
|
iframes?.forEach(iframe => {
|
|
513
548
|
if (iframe.contentWindow === event.source) {
|
|
514
|
-
|
|
549
|
+
const messages = document.getElementById('messages')
|
|
550
|
+
const maxHeight = messages ? messages.clientHeight : window.innerHeight
|
|
551
|
+
const calculatedHeight = event.data.height + 30
|
|
552
|
+
const targetHeight = Math.min(calculatedHeight, maxHeight)
|
|
553
|
+
|
|
554
|
+
if (iframe.style.height !== targetHeight + 'px') {
|
|
555
|
+
iframe.style.height = targetHeight + 'px'
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
if (calculatedHeight > maxHeight) {
|
|
559
|
+
event.source.postMessage({ type: 'stop-resize' }, '*')
|
|
560
|
+
}
|
|
515
561
|
}
|
|
516
562
|
})
|
|
517
563
|
}
|
|
@@ -591,7 +637,7 @@ export const ChatBody = {
|
|
|
591
637
|
template: `
|
|
592
638
|
<div class="flex flex-col h-full">
|
|
593
639
|
<!-- Messages Area -->
|
|
594
|
-
<div class="flex-1 overflow-y-auto" ref="messagesContainer">
|
|
640
|
+
<div id="messages" class="flex-1 overflow-y-auto" ref="messagesContainer">
|
|
595
641
|
<div class="mx-auto max-w-6xl px-4 py-6">
|
|
596
642
|
|
|
597
643
|
<div v-if="!$ai.hasAccess">
|
|
@@ -609,7 +655,7 @@ export const ChatBody = {
|
|
|
609
655
|
<ThreadHeader v-if="currentThread" :thread="currentThread" class="mb-2" />
|
|
610
656
|
<div class="space-y-2" v-if="currentThread?.messages?.length">
|
|
611
657
|
<div
|
|
612
|
-
v-for="message in
|
|
658
|
+
v-for="message in currentThreadMessages"
|
|
613
659
|
:key="message.timestamp"
|
|
614
660
|
v-show="!(message.role === 'tool' && isToolLinked(message))"
|
|
615
661
|
class="flex items-start space-x-3 group"
|
|
@@ -791,7 +837,7 @@ export const ChatBody = {
|
|
|
791
837
|
</div>
|
|
792
838
|
|
|
793
839
|
<!-- Thread error message bubble -->
|
|
794
|
-
<div v-if="currentThread?.error" class="mt-8 flex items-center
|
|
840
|
+
<div v-if="currentThread?.error" class="mt-8 flex items-center">
|
|
795
841
|
<!-- Avatar outside the bubble -->
|
|
796
842
|
<div class="flex-shrink-0">
|
|
797
843
|
<div class="size-8 rounded-full bg-red-600 dark:bg-red-500 text-white flex items-center justify-center text-lg font-bold">
|
|
@@ -799,13 +845,17 @@ export const ChatBody = {
|
|
|
799
845
|
</div>
|
|
800
846
|
</div>
|
|
801
847
|
<!-- Error bubble -->
|
|
802
|
-
<div class="max-w-[85%] rounded-lg px-3 py-1 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200 shadow-sm">
|
|
848
|
+
<div class="ml-3 max-w-[85%] rounded-lg px-3 py-1 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200 shadow-sm">
|
|
803
849
|
<div class="flex items-start space-x-2">
|
|
804
850
|
<div class="flex-1 min-w-0">
|
|
805
851
|
<div v-if="currentThread.error" class="text-base mb-1">{{ currentThread.error }}</div>
|
|
806
852
|
</div>
|
|
807
853
|
</div>
|
|
808
854
|
</div>
|
|
855
|
+
<button type="button" @click="$chat.sendUserMessage('retry')" title="Retry request"
|
|
856
|
+
class="ml-1 px-3 py-1 rounded text-sm text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-900/30 border border-transparent hover:border-gray-300 dark:hover:border-gray-600 transition-all">
|
|
857
|
+
retry
|
|
858
|
+
</button>
|
|
809
859
|
</div>
|
|
810
860
|
|
|
811
861
|
<!-- Error message bubble -->
|
|
@@ -839,7 +889,7 @@ export const ChatBody = {
|
|
|
839
889
|
</div>
|
|
840
890
|
</div>
|
|
841
891
|
</div>
|
|
842
|
-
<ThreadFooter v-if="$threads.threadDetails.value[currentThread.id]" :thread="$threads.threadDetails.value[currentThread.id]" />
|
|
892
|
+
<ThreadFooter v-if="!$threads.watchingThread && $threads.threadDetails.value[currentThread.id]" :thread="$threads.threadDetails.value[currentThread.id]" />
|
|
843
893
|
</div>
|
|
844
894
|
</div>
|
|
845
895
|
</div>
|
|
@@ -1074,12 +1124,17 @@ export const ChatBody = {
|
|
|
1074
1124
|
ctx.setPrefs(prefs.value)
|
|
1075
1125
|
}
|
|
1076
1126
|
|
|
1127
|
+
const ignoreUserMessages = ['proceed', 'retry']
|
|
1128
|
+
const currentThreadMessages = computed(() =>
|
|
1129
|
+
currentThread.value?.messages?.filter(x => x.role !== 'system' && !(x.role === 'user' && Array.isArray(x.content) && ignoreUserMessages.includes(x.content[0]?.text))))
|
|
1130
|
+
|
|
1077
1131
|
return {
|
|
1078
1132
|
prefs,
|
|
1079
1133
|
setPrefs,
|
|
1080
1134
|
config,
|
|
1081
1135
|
models,
|
|
1082
1136
|
currentThread,
|
|
1137
|
+
currentThreadMessages,
|
|
1083
1138
|
selectedModel,
|
|
1084
1139
|
selectedModelObj,
|
|
1085
1140
|
messagesContainer,
|
llms/ui/modules/chat/index.mjs
CHANGED
|
@@ -350,6 +350,105 @@ export function useChatPrompt(ctx) {
|
|
|
350
350
|
ctx.setState({ selectedAspectRatio })
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
+
async function sendUserMessage(text, { model, redirect = true } = {}) {
|
|
354
|
+
ctx.clearError()
|
|
355
|
+
|
|
356
|
+
if (!model) {
|
|
357
|
+
model = getSelectedModel()
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
let content = createContent({ text, files: attachedFiles.value })
|
|
361
|
+
|
|
362
|
+
let thread
|
|
363
|
+
|
|
364
|
+
// Create thread if none exists
|
|
365
|
+
if (!ctx.threads.currentThread.value) {
|
|
366
|
+
thread = await ctx.threads.startNewThread({ model, redirect })
|
|
367
|
+
} else {
|
|
368
|
+
thread = ctx.threads.currentThread.value
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
let threadId = thread.id
|
|
372
|
+
let messages = thread.messages || []
|
|
373
|
+
if (!threadId) {
|
|
374
|
+
console.error('No thread ID found', thread, ctx.threads.currentThread.value)
|
|
375
|
+
return
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Handle Editing / Redo Logic
|
|
379
|
+
const editingMsg = editingMessage.value
|
|
380
|
+
if (editingMsg) {
|
|
381
|
+
let messageIndex = messages.findIndex(m => m.timestamp === editingMsg)
|
|
382
|
+
if (messageIndex == -1) {
|
|
383
|
+
messageIndex = messages.findLastIndex(m => m.role === 'user')
|
|
384
|
+
}
|
|
385
|
+
console.log('Editing message', editingMsg, messageIndex, messages)
|
|
386
|
+
|
|
387
|
+
if (messageIndex >= 0) {
|
|
388
|
+
messages[messageIndex].content = content
|
|
389
|
+
// Truncate messages to only include up to the edited message
|
|
390
|
+
messages.length = messageIndex + 1
|
|
391
|
+
} else {
|
|
392
|
+
messages.push({
|
|
393
|
+
timestamp: new Date().valueOf(),
|
|
394
|
+
role: 'user',
|
|
395
|
+
content,
|
|
396
|
+
})
|
|
397
|
+
}
|
|
398
|
+
} else {
|
|
399
|
+
// Regular Send Logic
|
|
400
|
+
const lastMessage = messages[messages.length - 1]
|
|
401
|
+
|
|
402
|
+
// Check duplicate based on text content extracted from potential array
|
|
403
|
+
const getLastText = (msgContent) => {
|
|
404
|
+
if (typeof msgContent === 'string') return msgContent
|
|
405
|
+
if (Array.isArray(msgContent)) return msgContent.find(c => c.type === 'text')?.text || ''
|
|
406
|
+
return ''
|
|
407
|
+
}
|
|
408
|
+
const newText = text // content[0].text
|
|
409
|
+
const lastText = lastMessage && lastMessage.role === 'user' ? getLastText(lastMessage.content) : null
|
|
410
|
+
const isDuplicate = lastText === newText
|
|
411
|
+
|
|
412
|
+
// Add user message only if it's not a duplicate
|
|
413
|
+
// Note: We are saving the FULL STRUCTURED CONTENT array here
|
|
414
|
+
if (!isDuplicate) {
|
|
415
|
+
messages.push({
|
|
416
|
+
timestamp: new Date().valueOf(),
|
|
417
|
+
role: 'user',
|
|
418
|
+
content,
|
|
419
|
+
})
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const request = createRequest({ model })
|
|
424
|
+
|
|
425
|
+
// Add Thread History
|
|
426
|
+
messages.forEach(m => {
|
|
427
|
+
request.messages.push(m)
|
|
428
|
+
})
|
|
429
|
+
|
|
430
|
+
// Update Thread Title if not set or is default
|
|
431
|
+
if (!thread.title || thread.title === 'New Chat' || request.title === 'New Chat') {
|
|
432
|
+
request.title = text.length > 100
|
|
433
|
+
? text.slice(0, 100) + '...'
|
|
434
|
+
: text
|
|
435
|
+
console.debug(`changing thread title from '${thread.title}' to '${request.title}'`)
|
|
436
|
+
} else {
|
|
437
|
+
console.debug(`thread title is '${thread.title}'`, request.title)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const api = await ctx.threads.queueChat({ request, thread })
|
|
441
|
+
if (api.response) {
|
|
442
|
+
// success
|
|
443
|
+
editingMessage.value = null
|
|
444
|
+
attachedFiles.value = []
|
|
445
|
+
thread = api.response
|
|
446
|
+
ctx.threads.replaceThread(thread)
|
|
447
|
+
} else {
|
|
448
|
+
ctx.setError(api.error)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
353
452
|
return {
|
|
354
453
|
completion,
|
|
355
454
|
createContent,
|
|
@@ -374,6 +473,7 @@ export function useChatPrompt(ctx) {
|
|
|
374
473
|
getTextContent,
|
|
375
474
|
getAnswer,
|
|
376
475
|
selectAspectRatio,
|
|
476
|
+
sendUserMessage,
|
|
377
477
|
}
|
|
378
478
|
}
|
|
379
479
|
|
|
@@ -490,6 +590,7 @@ const ChatPrompt = {
|
|
|
490
590
|
hasAudio,
|
|
491
591
|
hasFile,
|
|
492
592
|
getTextContent,
|
|
593
|
+
sendUserMessage,
|
|
493
594
|
} = ctx.chat
|
|
494
595
|
|
|
495
596
|
const fileInput = ref(null)
|
|
@@ -631,8 +732,6 @@ const ChatPrompt = {
|
|
|
631
732
|
if (!messageText.value?.trim() && !hasImage() && !hasAudio() && !hasFile()) return
|
|
632
733
|
if (ctx.threads.isWatchingThread.value || !props.model) return
|
|
633
734
|
|
|
634
|
-
ctx.clearError()
|
|
635
|
-
|
|
636
735
|
// 1. Construct Structured Content (Text + Attachments)
|
|
637
736
|
let text = messageText.value.trim()
|
|
638
737
|
|
|
@@ -645,96 +744,8 @@ const ChatPrompt = {
|
|
|
645
744
|
}
|
|
646
745
|
|
|
647
746
|
messageText.value = ''
|
|
648
|
-
let content = ctx.chat.createContent({ text, files: ctx.chat.attachedFiles.value })
|
|
649
|
-
|
|
650
|
-
let thread
|
|
651
|
-
|
|
652
|
-
// Create thread if none exists
|
|
653
|
-
if (!ctx.threads.currentThread.value) {
|
|
654
|
-
thread = await ctx.threads.startNewThread({ model: props.model, redirect: true })
|
|
655
|
-
} else {
|
|
656
|
-
thread = ctx.threads.currentThread.value
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
let threadId = thread.id
|
|
660
|
-
let messages = thread.messages || []
|
|
661
|
-
if (!threadId) {
|
|
662
|
-
console.error('No thread ID found', thread, ctx.threads.currentThread.value)
|
|
663
|
-
return
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
// Handle Editing / Redo Logic
|
|
667
|
-
const editingMessage = ctx.chat.editingMessage.value
|
|
668
|
-
if (editingMessage) {
|
|
669
|
-
let messageIndex = messages.findIndex(m => m.timestamp === editingMessage)
|
|
670
|
-
if (messageIndex == -1) {
|
|
671
|
-
messageIndex = messages.findLastIndex(m => m.role === 'user')
|
|
672
|
-
}
|
|
673
|
-
console.log('Editing message', editingMessage, messageIndex, messages)
|
|
674
|
-
|
|
675
|
-
if (messageIndex >= 0) {
|
|
676
|
-
messages[messageIndex].content = content
|
|
677
|
-
// Truncate messages to only include up to the edited message
|
|
678
|
-
messages.length = messageIndex + 1
|
|
679
|
-
} else {
|
|
680
|
-
messages.push({
|
|
681
|
-
timestamp: new Date().valueOf(),
|
|
682
|
-
role: 'user',
|
|
683
|
-
content,
|
|
684
|
-
})
|
|
685
|
-
}
|
|
686
|
-
} else {
|
|
687
|
-
// Regular Send Logic
|
|
688
|
-
const lastMessage = messages[messages.length - 1]
|
|
689
|
-
|
|
690
|
-
// Check duplicate based on text content extracted from potential array
|
|
691
|
-
const getLastText = (msgContent) => {
|
|
692
|
-
if (typeof msgContent === 'string') return msgContent
|
|
693
|
-
if (Array.isArray(msgContent)) return msgContent.find(c => c.type === 'text')?.text || ''
|
|
694
|
-
return ''
|
|
695
|
-
}
|
|
696
|
-
const newText = text // content[0].text
|
|
697
|
-
const lastText = lastMessage && lastMessage.role === 'user' ? getLastText(lastMessage.content) : null
|
|
698
|
-
const isDuplicate = lastText === newText
|
|
699
|
-
|
|
700
|
-
// Add user message only if it's not a duplicate
|
|
701
|
-
// Note: We are saving the FULL STRUCTURED CONTENT array here
|
|
702
|
-
if (!isDuplicate) {
|
|
703
|
-
messages.push({
|
|
704
|
-
timestamp: new Date().valueOf(),
|
|
705
|
-
role: 'user',
|
|
706
|
-
content,
|
|
707
|
-
})
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
const request = ctx.chat.createRequest({ model: props.model })
|
|
712
747
|
|
|
713
|
-
|
|
714
|
-
messages.forEach(m => {
|
|
715
|
-
request.messages.push(m)
|
|
716
|
-
})
|
|
717
|
-
|
|
718
|
-
// Update Thread Title if not set or is default
|
|
719
|
-
if (!thread.title || thread.title === 'New Chat' || request.title === 'New Chat') {
|
|
720
|
-
request.title = text.length > 100
|
|
721
|
-
? text.slice(0, 100) + '...'
|
|
722
|
-
: text
|
|
723
|
-
console.debug(`changing thread title from '${thread.title}' to '${request.title}'`)
|
|
724
|
-
} else {
|
|
725
|
-
console.debug(`thread title is '${thread.title}'`, request.title)
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
const api = await ctx.threads.queueChat({ request, thread })
|
|
729
|
-
if (api.response) {
|
|
730
|
-
// success
|
|
731
|
-
ctx.chat.editingMessage.value = null
|
|
732
|
-
ctx.chat.attachedFiles.value = []
|
|
733
|
-
thread = api.response
|
|
734
|
-
ctx.threads.replaceThread(thread)
|
|
735
|
-
} else {
|
|
736
|
-
ctx.setError(api.error)
|
|
737
|
-
}
|
|
748
|
+
await sendUserMessage(text, { model: props.model })
|
|
738
749
|
|
|
739
750
|
// Restore focus to the textarea
|
|
740
751
|
nextTick(() => {
|
|
@@ -819,6 +830,7 @@ const ChatPrompt = {
|
|
|
819
830
|
addNewLine,
|
|
820
831
|
onKeyDown,
|
|
821
832
|
imageAspectRatios,
|
|
833
|
+
sendUserMessage,
|
|
822
834
|
}
|
|
823
835
|
}
|
|
824
836
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: llms-py
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.16
|
|
4
4
|
Summary: A lightweight CLI tool and OpenAI-compatible server for querying multiple Large Language Model (LLM) providers
|
|
5
5
|
Home-page: https://github.com/ServiceStack/llms
|
|
6
6
|
Author: ServiceStack
|
|
@@ -3,7 +3,7 @@ llms/__main__.py,sha256=hrBulHIt3lmPm1BCyAEVtB6DQ0Hvc3gnIddhHCmJasg,151
|
|
|
3
3
|
llms/db.py,sha256=oozp5I5lECVO8oZEFwcZl3ES5mARqWeR1BkoqG5kSqM,11687
|
|
4
4
|
llms/index.html,sha256=nGk1Djtn9p7l6LuKp4Kg0JIB9fCzxtTWXFfmDb4ggpc,1658
|
|
5
5
|
llms/llms.json,sha256=NEr9kJRkUGZ2YZHbWC-haGPlVVL2Qtnx4kKZENGH1wk,11494
|
|
6
|
-
llms/main.py,sha256=
|
|
6
|
+
llms/main.py,sha256=mce_QW7YCiV0oCNOP2GUCyngkIKIsscf_F9_qFX6bRc,182958
|
|
7
7
|
llms/providers-extra.json,sha256=_6DmGBiQY9LM6_Y0zOiObYn7ba4g3akSNQfmHcYlENc,11101
|
|
8
8
|
llms/providers.json,sha256=yjhDurlwo70xqfV0HNLiZaCpw3WvtIgkjoLahQIKX2w,282530
|
|
9
9
|
llms/extensions/analytics/ui/index.mjs,sha256=m1XwaqYCLwK267JAUCAltkN_nOXep0GxfpvGNS5i4_w,69547
|
|
@@ -13,16 +13,17 @@ llms/extensions/app/db.py,sha256=DU8YZ25yFsBI-O6msxh2GgzbwaqKqXkAHJLwQKcmFPI,215
|
|
|
13
13
|
llms/extensions/app/ui/Recents.mjs,sha256=2ypAKUp9_Oqcive1nUWZ8I2PQTBomBg_Pkjygi4oPgs,9261
|
|
14
14
|
llms/extensions/app/ui/index.mjs,sha256=sB9176LLNuKFsZ28yL-tROA6J4xePNtvxtSrzFcinRo,13271
|
|
15
15
|
llms/extensions/app/ui/threadStore.mjs,sha256=QS6mLqysw9Je_ixUKpbhAELGq-As8aFk6Qm_vO5hvUQ,12515
|
|
16
|
-
llms/extensions/
|
|
17
|
-
llms/extensions/
|
|
18
|
-
llms/extensions/
|
|
19
|
-
llms/extensions/
|
|
20
|
-
llms/extensions/
|
|
21
|
-
llms/extensions/
|
|
22
|
-
llms/extensions/
|
|
23
|
-
llms/extensions/
|
|
16
|
+
llms/extensions/computer/README.md,sha256=xGQXMFtTnjOLll9rDeF1b6Msl3uK5UwjvocvW7WCmps,4293
|
|
17
|
+
llms/extensions/computer/__init__.py,sha256=47nBZI4VMAJ0-mU0QCNtiqKRd-0CF9z8BnBsLE1jrQw,1813
|
|
18
|
+
llms/extensions/computer/base.py,sha256=Igio5R6kPQOxIbmpaA7X6j6eC4cpF3jwTTR8rURfp5E,2386
|
|
19
|
+
llms/extensions/computer/bash.py,sha256=-xo67wVAdrqxtXgR7MK-iAkJ4Wne7Dm1JmnuHC2xW8o,5953
|
|
20
|
+
llms/extensions/computer/computer.py,sha256=wehwcrYwi9usCRcziE_loMhWDbVgfjLk_T4_4TZa4W4,19642
|
|
21
|
+
llms/extensions/computer/edit.py,sha256=QluhvRhYSSQJfbih4QyfC4M8W8aVqiOApfYXZgZTI5M,12725
|
|
22
|
+
llms/extensions/computer/filesystem.py,sha256=4k_aq-wDySz1yV7k3ZshKr5q8LGH8gYkXgGDNAr62lc,19703
|
|
23
|
+
llms/extensions/computer/platform.py,sha256=w5ECar8lM4Lag7rTYUQmU7wEWaqCeejNXwwM3CB8ulQ,14866
|
|
24
|
+
llms/extensions/computer/run.py,sha256=ZIcoYyy2cc3IKR_T4yJgx6IUHu2m7UusIJi9Dx1s7dA,1566
|
|
24
25
|
llms/extensions/core_tools/CALCULATOR.md,sha256=pJRtCVF01BgxFrSNh2Ys_lrRi3SFwLgJzAX93AGh93Q,1944
|
|
25
|
-
llms/extensions/core_tools/__init__.py,sha256=
|
|
26
|
+
llms/extensions/core_tools/__init__.py,sha256=w8ovJRgXsvrcL8NF-XOrhuBE1oQXfnSQo-Xu7ww3NQY,21641
|
|
26
27
|
llms/extensions/core_tools/ui/index.mjs,sha256=KycJ2FcQ6BieBY7fjWGxVBGHN6WuFx712OFrO6flXww,31770
|
|
27
28
|
llms/extensions/core_tools/ui/codemirror/codemirror.css,sha256=60lOqXLSZh74b39qxlbdZ4bXIeScnBtG4euWfktvm_M,8720
|
|
28
29
|
llms/extensions/core_tools/ui/codemirror/codemirror.js,sha256=7cA89SlK249o7tVfiEWIiqDEA6ZEWxX4CoZmofVA14s,402008
|
|
@@ -139,7 +140,7 @@ llms/extensions/providers/__init__.py,sha256=C5zOBQEOB2L96rAZdjV42fPVk_dZxSh2Dv3
|
|
|
139
140
|
llms/extensions/providers/anthropic.py,sha256=ey3G9D3drhjzaNTKC8SS_XVSjdi3K7uqYTskmf26Aic,12011
|
|
140
141
|
llms/extensions/providers/cerebras.py,sha256=HaeFW0GwbD6V6Zrrwqyv78kQb0VXg9oHmykvJfIOOYE,1417
|
|
141
142
|
llms/extensions/providers/chutes.py,sha256=5ZrfbqoOhgzKLQy_qULcp4jlvW5WXPR0jP9kN2Jzb9g,6229
|
|
142
|
-
llms/extensions/providers/google.py,sha256=
|
|
143
|
+
llms/extensions/providers/google.py,sha256=rRmpmtSjTM04mZGNyEV2jcDxdDM99GNj_X68dNT1H20,27719
|
|
143
144
|
llms/extensions/providers/nvidia.py,sha256=C6cwqn3EufYDfRIgbc8MDkQNyD6w3c7hbjfYaHJSDik,4279
|
|
144
145
|
llms/extensions/providers/openai.py,sha256=hkE-LVsw6M92_qEbpayuPo17Z1OWKHe7lm2wduLMng8,6138
|
|
145
146
|
llms/extensions/providers/openrouter.py,sha256=5SfCJKo1aGKoDGez6HXYQe9elMMo9sSEDFqqdxamAgA,3330
|
|
@@ -150,17 +151,17 @@ llms/extensions/skills/errors.py,sha256=V4DTFNtzVADDlZ0g7RmoxZRFeG01oaG3zzaPAVdt
|
|
|
150
151
|
llms/extensions/skills/models.py,sha256=xmRfz8BMeOdzZXhW6MYFjkOVHOKD6bMDynId8aysans,1461
|
|
151
152
|
llms/extensions/skills/parser.py,sha256=Mb4NOtoY3Ip4Nng8ixb26oE8U_Sp5CI3n3l_qxbg1UM,5500
|
|
152
153
|
llms/extensions/skills/validator.py,sha256=te49hTfIPJWcMcLLCApSJ2Ru3lrqVF8ayDXtPEZF9sU,5154
|
|
153
|
-
llms/extensions/skills/ui/index.mjs,sha256=
|
|
154
|
+
llms/extensions/skills/ui/index.mjs,sha256=0_7TkyN1T1LH2j3nEz7ek-5RXqKOysEvC2NQ4rSorVE,17189
|
|
154
155
|
llms/extensions/skills/ui/skills/create-plan/SKILL.md,sha256=g_SLyBid2dwj56FBzh87lZGu1t08edLs0plimT2uNzs,2481
|
|
155
156
|
llms/extensions/system_prompts/README.md,sha256=ayr18lnSsGp62bunC6kxkvcSvZki775rbZ-8VoMDQEc,597
|
|
156
157
|
llms/extensions/system_prompts/__init__.py,sha256=TZy1CS2dPkBNBA_Ovf9BlVetZqTt2NgnsrZi6Mtg_C0,1535
|
|
157
158
|
llms/extensions/system_prompts/ui/index.mjs,sha256=Ec2dXSzEj6RnEuW2U3HxeXK3LTl_lJrVJIayozquoB4,11981
|
|
158
159
|
llms/extensions/system_prompts/ui/prompts.json,sha256=t5DD3bird-87wFa4OlW-bC2wdoYDrVzfyc8TO5OaotI,128489
|
|
159
|
-
llms/extensions/tools/__init__.py,sha256=
|
|
160
|
-
llms/extensions/tools/ui/index.mjs,sha256=
|
|
160
|
+
llms/extensions/tools/__init__.py,sha256=PRZe0QMfsOymJ3jTqO0VFppNEWI4f2bYSOImK_YrGQM,2036
|
|
161
|
+
llms/extensions/tools/ui/index.mjs,sha256=4gT0mHKuzcLWe8BmrYeVNS3VMd5Me9CX6Q0A_YLyLck,38633
|
|
161
162
|
llms/ui/App.mjs,sha256=CoUzO9mV__-jV19NKHYIbwHsjWMnO11jyNSbnJhe1gQ,7486
|
|
162
|
-
llms/ui/ai.mjs,sha256=
|
|
163
|
-
llms/ui/app.css,sha256=
|
|
163
|
+
llms/ui/ai.mjs,sha256=A5fGDgVa7mRC6aagXkKuXrSM_MlgAF1gsDTWHEZk2No,6541
|
|
164
|
+
llms/ui/app.css,sha256=kKKICFM_85H1BDFdUYJzo93S__1OZcj2cO6zL-4VdJs,209085
|
|
164
165
|
llms/ui/ctx.mjs,sha256=g1mmv87bhKCFyMbAImvX6mArmGliAoGPPupFEaMMf7c,14500
|
|
165
166
|
llms/ui/fav.svg,sha256=_R6MFeXl6wBFT0lqcUxYQIDWgm246YH_3hSTW0oO8qw,734
|
|
166
167
|
llms/ui/index.mjs,sha256=7GMbFyG3L4k6dxSrQYQ0BLzqL976xw5HeaqKco0THHA,4296
|
|
@@ -182,12 +183,12 @@ llms/ui/lib/vue.mjs,sha256=75FuLhUTPk19sncwNIrm0BGEL0_Qw298-_v01fPWYoI,542872
|
|
|
182
183
|
llms/ui/modules/icons.mjs,sha256=LGcH0ys0QLS2ZKCO42qHpwPYbBV_EssoWLezU4XZEzU,27751
|
|
183
184
|
llms/ui/modules/layout.mjs,sha256=8pAxs8bedQI3b3eRA9nrfpLZznLmrpp4BZvigYAQjpQ,12572
|
|
184
185
|
llms/ui/modules/model-selector.mjs,sha256=6U4rAZ7vmQELFRQGWk4YEtq02v3lyHdMq6yUOp-ArXg,43184
|
|
185
|
-
llms/ui/modules/chat/ChatBody.mjs,sha256=
|
|
186
|
+
llms/ui/modules/chat/ChatBody.mjs,sha256=Rwyr7JeqBn6LUn-VtHB9qj7kBsLsOr34SbHcK0twIZ0,58118
|
|
186
187
|
llms/ui/modules/chat/SettingsDialog.mjs,sha256=HMBJTwrapKrRIAstIIqp0QlJL5O-ho4hzgvfagPfsX8,19930
|
|
187
|
-
llms/ui/modules/chat/index.mjs,sha256=
|
|
188
|
-
llms_py-3.0.
|
|
189
|
-
llms_py-3.0.
|
|
190
|
-
llms_py-3.0.
|
|
191
|
-
llms_py-3.0.
|
|
192
|
-
llms_py-3.0.
|
|
193
|
-
llms_py-3.0.
|
|
188
|
+
llms/ui/modules/chat/index.mjs,sha256=nS_L6G1RSuCybgnA6n-q8Sn3OeSbQWL2iW3-zCIFqJk,39548
|
|
189
|
+
llms_py-3.0.16.dist-info/licenses/LICENSE,sha256=bus9cuAOWeYqBk2OuhSABVV1P4z7hgrEFISpyda_H5w,1532
|
|
190
|
+
llms_py-3.0.16.dist-info/METADATA,sha256=zP_aLsJ0caYROZZ-ch-oyoI0HlS86R4M-ZvY64_OmAg,2195
|
|
191
|
+
llms_py-3.0.16.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
192
|
+
llms_py-3.0.16.dist-info/entry_points.txt,sha256=WswyE7PfnkZMIxboC-MS6flBD6wm-CYU7JSUnMhqMfM,40
|
|
193
|
+
llms_py-3.0.16.dist-info/top_level.txt,sha256=gC7hk9BKSeog8gyg-EM_g2gxm1mKHwFRfK-10BxOsa4,5
|
|
194
|
+
llms_py-3.0.16.dist-info/RECORD,,
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Anthropic's Computer Use Tools
|
|
3
|
-
https://github.com/anthropics/claude-quickstarts/tree/main/computer-use-demo
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
|
|
8
|
-
from .bash import open, run_bash
|
|
9
|
-
from .computer import computer
|
|
10
|
-
from .edit import edit
|
|
11
|
-
from .platform import get_display_num, get_screen_resolution
|
|
12
|
-
|
|
13
|
-
width, height = get_screen_resolution()
|
|
14
|
-
# set enviroment variables
|
|
15
|
-
os.environ["WIDTH"] = str(width)
|
|
16
|
-
os.environ["HEIGHT"] = str(height)
|
|
17
|
-
os.environ["DISPLAY_NUM"] = str(get_display_num())
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def install(ctx):
|
|
21
|
-
ctx.register_tool(run_bash, group="computer_use")
|
|
22
|
-
ctx.register_tool(open, group="computer_use")
|
|
23
|
-
ctx.register_tool(edit, group="computer_use")
|
|
24
|
-
ctx.register_tool(computer, group="computer_use")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
__install__ = install
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|