llms-py 2.0.16__py3-none-any.whl → 2.0.18__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.
Binary file
llms/llms.json CHANGED
@@ -93,10 +93,6 @@
93
93
  }
94
94
  ],
95
95
  "max_completion_tokens": 16,
96
- "reasoning": {
97
- "max_tokens": 16,
98
- "reasoning_effort": "low"
99
- },
100
96
  "stream": false
101
97
  }
102
98
  },
@@ -147,7 +143,6 @@
147
143
  "api_key": "$GROQ_API_KEY",
148
144
  "models": {
149
145
  "allam-2-7b": "allam-2-7b",
150
- "gemma2:9b": "gemma2-9b-it",
151
146
  "compound": "groq/compound",
152
147
  "compound-mini": "groq/compound-mini",
153
148
  "llama3.1:8b": "llama-3.1-8b-instant",
@@ -168,7 +163,7 @@
168
163
  }
169
164
  },
170
165
  "google_free": {
171
- "enabled": true,
166
+ "enabled": false,
172
167
  "type": "GoogleProvider",
173
168
  "api_key": "$GOOGLE_FREE_API_KEY",
174
169
  "models": {
@@ -599,7 +594,6 @@
599
594
  "base_url": "https://api.anthropic.com",
600
595
  "api_key": "$ANTHROPIC_API_KEY",
601
596
  "models": {
602
- "claude-opus-4-1": "claude-opus-4-1",
603
597
  "claude-sonnet-4-5": "claude-sonnet-4-5",
604
598
  "claude-sonnet-4-0": "claude-sonnet-4-0",
605
599
  "claude-3-7-sonnet": "claude-3-7-sonnet-latest",
@@ -640,6 +634,25 @@
640
634
  "input": "0.00000025",
641
635
  "output": "0.00000125"
642
636
  }
637
+ },
638
+ "check": {
639
+ "messages": [
640
+ {
641
+ "role": "user",
642
+ "content": [
643
+ {
644
+ "type": "text",
645
+ "text": "1+1="
646
+ }
647
+ ]
648
+ }
649
+ ],
650
+ "max_completion_tokens": 512,
651
+ "reasoning": {
652
+ "max_tokens": 128,
653
+ "reasoning_effort": "low"
654
+ },
655
+ "stream": false
643
656
  }
644
657
  },
645
658
  "openai": {
@@ -735,21 +748,6 @@
735
748
  "input": "0.000003",
736
749
  "output": "0.000006"
737
750
  }
738
- },
739
- "check": {
740
- "messages": [
741
- {
742
- "role": "user",
743
- "content": [
744
- {
745
- "type": "text",
746
- "text": "1+1="
747
- }
748
- ]
749
- }
750
- ],
751
- "max_completion_tokens": 16,
752
- "stream": false
753
751
  }
754
752
  },
755
753
  "grok": {
llms/main.py CHANGED
@@ -22,7 +22,7 @@ from aiohttp import web
22
22
  from pathlib import Path
23
23
  from importlib import resources # Py≥3.9 (pip install importlib_resources for 3.7/3.8)
24
24
 
25
- VERSION = "2.0.16"
25
+ VERSION = "2.0.18"
26
26
  _ROOT = None
27
27
  g_config_path = None
28
28
  g_ui_path = None
llms/ui/Analytics.mjs CHANGED
@@ -380,7 +380,7 @@ export default {
380
380
  </div>
381
381
  </div>
382
382
  <div class="flex flex-col gap-2">
383
- <button type="button" v-if="request.threadId" @click="openThread(request.threadId)" class="flex-shrink-0 px-4 py-2 text-sm font-medium text-blue-600 hover:text-blue-800 border border-blue-300 rounded hover:bg-blue-50 transition-colors whitespace-nowrap">
383
+ <button type="button" v-if="threadExists(request.threadId)" @click="openThread(request.threadId)" class="flex-shrink-0 px-4 py-2 text-sm font-medium text-blue-600 hover:text-blue-800 border border-blue-300 rounded hover:bg-blue-50 transition-colors whitespace-nowrap">
384
384
  View<span class="hidden lg:inline"> Thread</span>
385
385
  </button>
386
386
  <button type="button" @click="deleteRequestLog(request.id)" class="flex-shrink-0 px-4 py-2 text-sm font-medium text-red-600 hover:text-red-800 border border-red-300 rounded hover:bg-red-50 transition-colors whitespace-nowrap">
@@ -525,6 +525,7 @@ export default {
525
525
  const activityHasMore = ref(true)
526
526
  const activityOffset = ref(0)
527
527
  const activityPageSize = 20
528
+ const existingThreadIds = ref(new Set())
528
529
 
529
530
  const selectedModel = ref('')
530
531
  const selectedProvider = ref('')
@@ -1234,11 +1235,43 @@ export default {
1234
1235
  }
1235
1236
  }
1236
1237
 
1238
+ const loadExistingThreadIds = async () => {
1239
+ try {
1240
+ // Calculate date range for selected month/year
1241
+ const startDate = new Date(selectedYear.value, selectedMonth.value - 1, 1)
1242
+ const endDate = new Date(selectedYear.value, selectedMonth.value, 0, 23, 59, 59)
1243
+
1244
+ // Convert to timestamp strings (threadId format)
1245
+ const startThreadId = startDate.getTime().toString()
1246
+ const endThreadId = endDate.getTime().toString()
1247
+
1248
+ const db = await initDB()
1249
+ const tx = db.transaction(['threads'], 'readonly')
1250
+ const store = tx.objectStore('threads')
1251
+
1252
+ // Use IDBKeyRange to only load threads within the month's timestamp range
1253
+ const range = IDBKeyRange.bound(startThreadId, endThreadId)
1254
+ const monthThreads = await store.getAll(range)
1255
+
1256
+ // Create a Set of existing thread IDs for the month
1257
+ existingThreadIds.value = new Set(monthThreads.map(thread => thread.id))
1258
+ } catch (error) {
1259
+ console.error('Failed to load existing thread IDs:', error)
1260
+ existingThreadIds.value = new Set()
1261
+ }
1262
+ }
1263
+
1264
+ const threadExists = (threadId) => {
1265
+ return threadId ? existingThreadIds.value.has(threadId) : false
1266
+ }
1267
+
1237
1268
  const loadActivityRequests = async (reset = false) => {
1238
1269
  if (reset) {
1239
1270
  activityOffset.value = 0
1240
1271
  activityRequests.value = []
1241
1272
  isActivityLoading.value = true
1273
+ // Load all existing thread IDs once when resetting
1274
+ await loadExistingThreadIds()
1242
1275
  } else {
1243
1276
  isActivityLoadingMore.value = true
1244
1277
  }
@@ -1474,6 +1507,7 @@ export default {
1474
1507
  onActivityScroll,
1475
1508
  clearActivityFilters,
1476
1509
  formatActivityDate,
1510
+ threadExists,
1477
1511
  openThread,
1478
1512
  deleteRequestLog,
1479
1513
  loadActivityFilterOptions,
llms/ui/Main.mjs CHANGED
@@ -187,7 +187,7 @@ export default {
187
187
  <!-- Edit and Redo buttons (shown on hover for user messages, outside bubble) -->
188
188
  <div v-if="message.role === 'user'" class="flex flex-col gap-2 opacity-0 group-hover:opacity-100 transition-opacity mt-1">
189
189
  <button type="button" @click.stop="editMessage(message)"
190
- class="text-xs px-2 py-1 rounded text-gray-400 hover:text-green-600 hover:bg-green-50 transition-all"
190
+ class="whitespace-nowrap text-xs px-2 py-1 rounded text-gray-400 hover:text-green-600 hover:bg-green-50 transition-all"
191
191
  title="Edit message">
192
192
  <svg class="size-4 inline mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
193
193
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"></path>
@@ -195,7 +195,7 @@ export default {
195
195
  Edit
196
196
  </button>
197
197
  <button type="button" @click.stop="redoMessage(message)"
198
- class="text-xs px-2 py-1 rounded text-gray-400 hover:text-blue-600 hover:bg-blue-50 transition-all"
198
+ class="whitespace-nowrap text-xs px-2 py-1 rounded text-gray-400 hover:text-blue-600 hover:bg-blue-50 transition-all"
199
199
  title="Redo message (clears all responses after this message and re-runs it)">
200
200
  <svg class="size-4 inline mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
201
201
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
llms/ui/ai.mjs CHANGED
@@ -6,7 +6,7 @@ const headers = { 'Accept': 'application/json' }
6
6
  const prefsKey = 'llms.prefs'
7
7
 
8
8
  export const o = {
9
- version: '2.0.16',
9
+ version: '2.0.18',
10
10
  base,
11
11
  prefsKey,
12
12
  welcome: 'Welcome to llms.py',
llms/ui/threadStore.mjs CHANGED
@@ -89,7 +89,7 @@ async function logRequest(threadId, model, request, response) {
89
89
  outputPrice,
90
90
  cost: (parseFloat(inputPrice) * inputTokens) + (parseFloat(outputPrice) * outputTokens),
91
91
  duration: metadata.duration ?? 0,
92
- created: subtractDays(response.created ?? Math.floor(Date.now() / 1000), 1),
92
+ created: response.created ?? Math.floor(Date.now() / 1000),
93
93
  finishReason,
94
94
  providerRef: response.provider,
95
95
  ref: response.id || undefined,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: llms-py
3
- Version: 2.0.16
3
+ Version: 2.0.18
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
@@ -1,8 +1,8 @@
1
1
  llms/__init__.py,sha256=Mk6eHi13yoUxLlzhwfZ6A1IjsfSQt9ShhOdbLXTvffU,53
2
2
  llms/__main__.py,sha256=hrBulHIt3lmPm1BCyAEVtB6DQ0Hvc3gnIddhHCmJasg,151
3
3
  llms/index.html,sha256=OA9mRmgh-dQrPqb0Z2Jv-cwEZ3YLPRxcWUN7ASjxO8s,2658
4
- llms/llms.json,sha256=CXl0SLqfL6cT9xUogPEHvTa6lhdoLsyPmEiqFbEpNQ8,40924
5
- llms/main.py,sha256=2KGZyqv6E2ZV1-guPegKmB0yQNJLEqimGDAXStfnQns,71376
4
+ llms/llms.json,sha256=jmk-86hHK--aW58vouZSQUGOsvuuiA29SRrryGzITL4,40844
5
+ llms/main.py,sha256=XsAxn0jGxRsZoqmnIc8op4JeqVu0NKaHlLBGEpUJXk8,71376
6
6
  llms/ui.json,sha256=iBOmpNeD5-o8AgUa51ymS-KemovJ7bm9J1fnL0nf8jk,134025
7
7
  llms/__pycache__/__init__.cpython-312.pyc,sha256=e6TG6e0PTRxM_LRg25eL4FvjQ0wBbfeahICORONYgDk,173
8
8
  llms/__pycache__/__init__.cpython-313.pyc,sha256=DvmykIYAjV4Xjv5NeC70BA0JIX8qtwEWP2dfzmOBrps,173
@@ -12,13 +12,13 @@ llms/__pycache__/__main__.cpython-314.pyc,sha256=IFxtGVpJq_3whKuM5Ln7YMweKFNbHVp
12
12
  llms/__pycache__/llms.cpython-312.pyc,sha256=S5dFI79JdUe2dQW4ogdB-CCNhudQeFaFGcfKxgJGBms,72080
13
13
  llms/__pycache__/main.cpython-312.pyc,sha256=pqZ-h6Itl6gNQpNwpp_npEYGl-cNxAYDmogr721XoeU,72085
14
14
  llms/__pycache__/main.cpython-313.pyc,sha256=6NQ__SJ2rC9ItFLKLHL5ewb5RqxLzZabwgczA9wZd-w,74814
15
- llms/__pycache__/main.cpython-314.pyc,sha256=WtfggYctsz-pwCdo4gGPO3UcFZAf6VQEK_Gy-fveeEg,89937
16
- llms/ui/Analytics.mjs,sha256=M3yumsGfmoVGtLDVrtVNBpR9zqKEfk4a09ko5R_H9Rk,67554
15
+ llms/__pycache__/main.cpython-314.pyc,sha256=gYqfS-Qm4QdN5l8ryAspQYh895vQWSlVAHaLY-uxUBU,89937
16
+ llms/ui/Analytics.mjs,sha256=mAS5AUQjpnEIMyzGzOGE6fZxwxoVyq5QCitYQSSCEpQ,69151
17
17
  llms/ui/App.mjs,sha256=hXtUjaL3GrcIHieEK3BzIG72OVzrorBBS4RkE1DOGc4,439
18
18
  llms/ui/Avatar.mjs,sha256=3rHpxe_LuCDiNP895F3FOjWx4j377JA9rD1FLluvtgA,851
19
19
  llms/ui/Brand.mjs,sha256=0NN2JBLUC0OWERuLz9myrimlcA7v7D5B_EMd0sQQVDo,1905
20
20
  llms/ui/ChatPrompt.mjs,sha256=85O_kLVKWbbUDOUlvkuAineam_jrd6lzrj4O00p1XOg,21172
21
- llms/ui/Main.mjs,sha256=pmFwN3Q2ccgmi2fFXyCaVZAmidzqA6RtXCit84Xvk4c,38088
21
+ llms/ui/Main.mjs,sha256=BatB0UZVhWrv0dYSTy5EGeVDAF_T_H2XEVPlWRExRvE,38124
22
22
  llms/ui/ModelSelector.mjs,sha256=ASLTUaqig3cDMiGup01rpubC2RrrZvPd8IFrYcK8GyQ,2565
23
23
  llms/ui/ProviderIcon.mjs,sha256=HTjlgtXEpekn8iNN_S0uswbbvL0iGb20N15-_lXdojk,9054
24
24
  llms/ui/ProviderStatus.mjs,sha256=qF_rPdhyt9GffKdPCJdU0yanrDJ3cw1HLPygFP_KjEs,5744
@@ -29,12 +29,12 @@ llms/ui/SignIn.mjs,sha256=df3b-7L3ZIneDGbJWUk93K9RGo40gVeuR5StzT1ZH9g,2324
29
29
  llms/ui/SystemPromptEditor.mjs,sha256=2CyIUvkIubqYPyIp5zC6_I8CMxvYINuYNjDxvMz4VRU,1265
30
30
  llms/ui/SystemPromptSelector.mjs,sha256=AuEtRwUf_RkGgene3nVA9bw8AeMb-b5_6ZLJCTWA8KQ,3051
31
31
  llms/ui/Welcome.mjs,sha256=QFAxN7sjWlhMvOIJCmHjNFCQcvpM_T-b4ze1ld9Hj7I,912
32
- llms/ui/ai.mjs,sha256=hdUrE6NCiIfFGt1pIYirOI1XZJTVMDdEnOm86yUOOcw,2346
32
+ llms/ui/ai.mjs,sha256=4jdRrVgCp6sS4TWoSqDLZ5biVNe8axLaS1WB4w-Y4L0,2346
33
33
  llms/ui/app.css,sha256=e81FHQ-K7TlS7Cr2x_CCHqrvmVvg9I-m0InLQHRT_Dg,98992
34
34
  llms/ui/fav.svg,sha256=_R6MFeXl6wBFT0lqcUxYQIDWgm246YH_3hSTW0oO8qw,734
35
35
  llms/ui/markdown.mjs,sha256=O5UspOeD8-E23rxOLWcS4eyy2YejMbPwszCYteVtuoU,6221
36
36
  llms/ui/tailwind.input.css,sha256=yo_3A50uyiVSUHUWeqAMorXMhCWpZoE5lTO6OJIFlYg,11974
37
- llms/ui/threadStore.mjs,sha256=lk4dDBzaVKnZ5bfhrAR8VWGLKGROLaD1DSzmenq6amU,15574
37
+ llms/ui/threadStore.mjs,sha256=JKimOl-9c4p9qQ9L93tZZktmKwuzpiudXiWb4N9Ca3U,15557
38
38
  llms/ui/typography.css,sha256=Z5Fe2IQWnh7bu1CMXniYt0SkaN2fXOFlOuniXUW8oGM,19325
39
39
  llms/ui/utils.mjs,sha256=cYrP17JwpQk7lLqTWNgVTOD_ZZAovbWnx2QSvKzeB24,5333
40
40
  llms/ui/lib/chart.js,sha256=dx8FdDX0Rv6OZtZjr9FQh5h-twFsKjfnb-FvFlQ--cU,196176
@@ -48,9 +48,9 @@ llms/ui/lib/servicestack-vue.mjs,sha256=r_-khYokisXJAIPDLh8Wq6YtcLAY6HNjtJlCZJjL
48
48
  llms/ui/lib/vue-router.min.mjs,sha256=fR30GHoXI1u81zyZ26YEU105pZgbbAKSXbpnzFKIxls,30418
49
49
  llms/ui/lib/vue.min.mjs,sha256=iXh97m5hotl0eFllb3aoasQTImvp7mQoRJ_0HoxmZkw,163811
50
50
  llms/ui/lib/vue.mjs,sha256=dS8LKOG01t9CvZ04i0tbFXHqFXOO_Ha4NmM3BytjQAs,537071
51
- llms_py-2.0.16.dist-info/licenses/LICENSE,sha256=rRryrddGfVftpde-rmAZpW0R8IJihqJ8t8wpfDXoKiQ,1549
52
- llms_py-2.0.16.dist-info/METADATA,sha256=42SARMz_sC34JypC97CxPyhdJrVgsl6QPeWDe10Kzb0,27902
53
- llms_py-2.0.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
54
- llms_py-2.0.16.dist-info/entry_points.txt,sha256=WswyE7PfnkZMIxboC-MS6flBD6wm-CYU7JSUnMhqMfM,40
55
- llms_py-2.0.16.dist-info/top_level.txt,sha256=gC7hk9BKSeog8gyg-EM_g2gxm1mKHwFRfK-10BxOsa4,5
56
- llms_py-2.0.16.dist-info/RECORD,,
51
+ llms_py-2.0.18.dist-info/licenses/LICENSE,sha256=rRryrddGfVftpde-rmAZpW0R8IJihqJ8t8wpfDXoKiQ,1549
52
+ llms_py-2.0.18.dist-info/METADATA,sha256=YVtfqjIpTAcT97A74KQahZkkcJeHNvNJzYWTjhmxdW0,27902
53
+ llms_py-2.0.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
54
+ llms_py-2.0.18.dist-info/entry_points.txt,sha256=WswyE7PfnkZMIxboC-MS6flBD6wm-CYU7JSUnMhqMfM,40
55
+ llms_py-2.0.18.dist-info/top_level.txt,sha256=gC7hk9BKSeog8gyg-EM_g2gxm1mKHwFRfK-10BxOsa4,5
56
+ llms_py-2.0.18.dist-info/RECORD,,