llms-py 2.0.18__py3-none-any.whl → 2.0.33__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.
Files changed (41) hide show
  1. llms/index.html +17 -1
  2. llms/llms.json +1132 -1075
  3. llms/main.py +561 -103
  4. llms/ui/Analytics.mjs +115 -104
  5. llms/ui/App.mjs +81 -4
  6. llms/ui/Avatar.mjs +61 -4
  7. llms/ui/Brand.mjs +29 -11
  8. llms/ui/ChatPrompt.mjs +163 -16
  9. llms/ui/Main.mjs +177 -94
  10. llms/ui/ModelSelector.mjs +28 -10
  11. llms/ui/OAuthSignIn.mjs +92 -0
  12. llms/ui/ProviderStatus.mjs +12 -12
  13. llms/ui/Recents.mjs +13 -13
  14. llms/ui/SettingsDialog.mjs +65 -65
  15. llms/ui/Sidebar.mjs +24 -19
  16. llms/ui/SystemPromptEditor.mjs +5 -5
  17. llms/ui/SystemPromptSelector.mjs +26 -6
  18. llms/ui/Welcome.mjs +2 -2
  19. llms/ui/ai.mjs +69 -5
  20. llms/ui/app.css +548 -34
  21. llms/ui/lib/servicestack-vue.mjs +9 -9
  22. llms/ui/markdown.mjs +8 -8
  23. llms/ui/tailwind.input.css +2 -0
  24. llms/ui/threadStore.mjs +39 -0
  25. llms/ui/typography.css +54 -36
  26. {llms_py-2.0.18.dist-info → llms_py-2.0.33.dist-info}/METADATA +403 -47
  27. llms_py-2.0.33.dist-info/RECORD +48 -0
  28. {llms_py-2.0.18.dist-info → llms_py-2.0.33.dist-info}/licenses/LICENSE +1 -2
  29. llms/__pycache__/__init__.cpython-312.pyc +0 -0
  30. llms/__pycache__/__init__.cpython-313.pyc +0 -0
  31. llms/__pycache__/__init__.cpython-314.pyc +0 -0
  32. llms/__pycache__/__main__.cpython-312.pyc +0 -0
  33. llms/__pycache__/__main__.cpython-314.pyc +0 -0
  34. llms/__pycache__/llms.cpython-312.pyc +0 -0
  35. llms/__pycache__/main.cpython-312.pyc +0 -0
  36. llms/__pycache__/main.cpython-313.pyc +0 -0
  37. llms/__pycache__/main.cpython-314.pyc +0 -0
  38. llms_py-2.0.18.dist-info/RECORD +0 -56
  39. {llms_py-2.0.18.dist-info → llms_py-2.0.33.dist-info}/WHEEL +0 -0
  40. {llms_py-2.0.18.dist-info → llms_py-2.0.33.dist-info}/entry_points.txt +0 -0
  41. {llms_py-2.0.18.dist-info → llms_py-2.0.33.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,92 @@
1
+ import { inject, ref, onMounted } from "vue"
2
+ import Welcome from './Welcome.mjs'
3
+
4
+ export default {
5
+ components: {
6
+ Welcome,
7
+ },
8
+ template: `
9
+ <div class="min-h-full -mt-36 flex flex-col justify-center sm:px-6 lg:px-8">
10
+ <div class="sm:mx-auto sm:w-full sm:max-w-md text-center">
11
+ <Welcome />
12
+ </div>
13
+ <div class="sm:mx-auto sm:w-full sm:max-w-md">
14
+ <div v-if="errorMessage" class="mb-3 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 text-red-800 dark:text-red-200 rounded-lg px-4 py-3">
15
+ <div class="flex items-start space-x-2">
16
+ <div class="flex-1">
17
+ <div class="text-base font-medium">{{ errorMessage }}</div>
18
+ </div>
19
+ <button type="button"
20
+ @click="errorMessage = null"
21
+ class="text-red-400 dark:text-red-300 hover:text-red-600 dark:hover:text-red-100 flex-shrink-0"
22
+ >
23
+ <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
24
+ <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"></path>
25
+ </svg>
26
+ </button>
27
+ </div>
28
+ </div>
29
+ <div class="py-8 px-4 sm:px-10">
30
+ <div class="space-y-4">
31
+ <button
32
+ type="button"
33
+ @click="signInWithGitHub"
34
+ class="w-full inline-flex items-center justify-center px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-base font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-colors"
35
+ >
36
+ <svg class="w-6 h-6 mr-3" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true">
37
+ <path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd" />
38
+ </svg>
39
+ Sign in with GitHub
40
+ </button>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ `,
46
+ emits: ['done'],
47
+ setup(props, { emit }) {
48
+ const ai = inject('ai')
49
+ const errorMessage = ref(null)
50
+
51
+ function signInWithGitHub() {
52
+ // Redirect to GitHub OAuth endpoint
53
+ window.location.href = '/auth/github'
54
+ }
55
+
56
+ // Check for session token in URL (after OAuth callback redirect)
57
+ onMounted(async () => {
58
+ const urlParams = new URLSearchParams(window.location.search)
59
+ const sessionToken = urlParams.get('session')
60
+
61
+ if (sessionToken) {
62
+ try {
63
+ // Validate session with server
64
+ const response = await ai.get(`/auth/session?session=${sessionToken}`)
65
+
66
+ if (response.ok) {
67
+ const sessionData = await response.json()
68
+
69
+ // Clean up URL
70
+ const url = new URL(window.location.href)
71
+ url.searchParams.delete('session')
72
+ window.history.replaceState({}, '', url.toString())
73
+
74
+ // Emit done event with session data
75
+ emit('done', sessionData)
76
+ } else {
77
+ errorMessage.value = 'Failed to validate session'
78
+ }
79
+ } catch (error) {
80
+ console.error('Session validation error:', error)
81
+ errorMessage.value = 'Failed to validate session'
82
+ }
83
+ }
84
+ })
85
+
86
+ return {
87
+ signInWithGitHub,
88
+ errorMessage,
89
+ }
90
+ }
91
+ }
92
+
@@ -3,25 +3,25 @@ import { ref, computed, inject, onMounted, onUnmounted } from "vue"
3
3
  export default {
4
4
  template:`
5
5
  <div v-if="$ai.isAdmin" ref="triggerRef" class="relative" :key="renderKey">
6
- <button type="button" @click="togglePopover"
7
- class="mt-1 flex space-x-2 items-center text-sm font-semibold select-none rounded-sm py-2 px-3 border border-transparent hover:bg-gray-50 hover:shadow hover:border-gray-200">
8
- <span class="text-gray-600" :title="models.length + ' models from ' + (config.status.enabled||[]).length + ' enabled providers'">{{models.length}}</span>
6
+ <button type="button" @click="togglePopover"
7
+ class="mt-1 flex space-x-2 items-center text-sm font-semibold select-none rounded-sm py-2 px-3 border border-transparent hover:bg-gray-50 dark:hover:bg-gray-700 hover:shadow hover:border-gray-200 dark:hover:border-gray-600">
8
+ <span class="text-gray-600 dark:text-gray-400" :title="models.length + ' models from ' + (config.status.enabled||[]).length + ' enabled providers'">{{models.length}}</span>
9
9
  <div class="cursor-pointer flex items-center" :title="'Enabled:\\n' + (config.status.enabled||[]).map(x => ' ' + x).join('\\n')">
10
- <svg class="size-4 text-green-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="currentColor"/></svg>
11
- <span class="text-green-700">{{(config.status.enabled||[]).length}}</span>
10
+ <svg class="size-4 text-green-400 dark:text-green-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="currentColor"/></svg>
11
+ <span class="text-green-700 dark:text-green-400">{{(config.status.enabled||[]).length}}</span>
12
12
  </div>
13
13
  <div class="cursor-pointer flex items-center" :title="'Disabled:\\n' + (config.status.disabled||[]).map(x => ' ' + x).join('\\n')">
14
- <svg class="size-4 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="currentColor"/></svg>
15
- <span class="text-red-700">{{(config.status.disabled||[]).length}}</span>
14
+ <svg class="size-4 text-red-400 dark:text-red-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="currentColor"/></svg>
15
+ <span class="text-red-700 dark:text-red-400">{{(config.status.disabled||[]).length}}</span>
16
16
  </div>
17
17
  </button>
18
- <div v-if="showPopover" ref="popoverRef" class="absolute right-0 mt-2 w-72 max-h-120 overflow-y-auto bg-white border border-gray-200 rounded-md shadow-lg z-10">
19
- <div class="divide-y divide-gray-100">
18
+ <div v-if="showPopover" ref="popoverRef" class="absolute right-0 mt-2 w-72 max-h-120 overflow-y-auto bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg z-10">
19
+ <div class="divide-y divide-gray-100 dark:divide-gray-700">
20
20
  <div v-for="p in allProviders" :key="p" class="flex items-center justify-between px-3 py-2">
21
- <label :for="'chk_' + p" class="cursor-pointer text-sm text-gray-900 truncate mr-2" :title="p">{{ p }}</label>
21
+ <label :for="'chk_' + p" class="cursor-pointer text-sm text-gray-900 dark:text-gray-100 truncate mr-2" :title="p">{{ p }}</label>
22
22
  <div @click="onToggle(p, !isEnabled(p))" class="cursor-pointer group relative inline-flex h-5 w-10 shrink-0 items-center justify-center rounded-full outline-offset-2 outline-green-600 has-focus-visible:outline-2">
23
- <span class="absolute mx-auto h-4 w-9 rounded-full bg-gray-200 inset-ring inset-ring-gray-900/5 transition-colors duration-200 ease-in-out group-has-checked:bg-green-600" />
24
- <span class="absolute left-0 size-5 rounded-full border border-gray-300 bg-white shadow-xs transition-transform duration-200 ease-in-out group-has-checked:translate-x-5" />
23
+ <span class="absolute mx-auto h-4 w-9 rounded-full bg-gray-200 dark:bg-gray-700 inset-ring inset-ring-gray-900/5 dark:inset-ring-gray-100/5 transition-colors duration-200 ease-in-out group-has-checked:bg-green-600 dark:group-has-checked:bg-green-500" />
24
+ <span class="absolute left-0 size-5 rounded-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-200 shadow-xs transition-transform duration-200 ease-in-out group-has-checked:translate-x-5" />
25
25
  <input :id="'chk_' + p" type="checkbox" :checked="isEnabled(p)" class="switch cursor-pointer absolute inset-0 appearance-none focus:outline-hidden" aria-label="Use setting" name="setting" />
26
26
  </div>
27
27
  </div>
llms/ui/Recents.mjs CHANGED
@@ -7,33 +7,33 @@ const RecentResults = {
7
7
  template:`
8
8
  <div class="flex-1 overflow-y-auto" @scroll="onScroll">
9
9
  <div class="mx-auto max-w-6xl px-4 py-4">
10
- <div class="text-sm text-gray-600 mb-3" v-if="threads.length">
10
+ <div class="text-sm text-gray-600 dark:text-gray-400 mb-3" v-if="threads.length">
11
11
  <span v-if="q">{{ filtered.length }} result{{ filtered.length===1?'':'s' }}</span>
12
12
  <span v-else>Searching {{ threads.length }} conversation{{ threads.length===1?'':'s' }}</span>
13
13
  </div>
14
14
 
15
- <div v-if="!threads.length" class="text-gray-500">No conversations yet.</div>
15
+ <div v-if="!threads.length" class="text-gray-500 dark:text-gray-400">No conversations yet.</div>
16
16
 
17
17
  <table class="w-full">
18
18
  <tbody>
19
- <tr v-for="t in displayed" :key="t.id" class="hover:bg-gray-50">
20
- <td class="py-3 px-1 border-b border-gray-200 max-w-3xl">
19
+ <tr v-for="t in displayed" :key="t.id" class="hover:bg-gray-50 dark:hover:bg-gray-800">
20
+ <td class="py-3 px-1 border-b border-gray-200 dark:border-gray-700 max-w-3xl">
21
21
  <button type="button" @click="open(t.id)" class="w-full text-left">
22
22
  <div class="flex items-start justify-between gap-3">
23
23
  <div class="min-w-0 flex-1">
24
- <div class="font-medium text-gray-900 truncate" :title="t.title">{{ t.title || 'Untitled chat' }}</div>
25
- <div class="mt-1 text-sm text-gray-600 line-clamp-2">
24
+ <div class="font-medium text-gray-900 dark:text-gray-100 truncate" :title="t.title">{{ t.title || 'Untitled chat' }}</div>
25
+ <div class="mt-1 text-sm text-gray-600 dark:text-gray-400 line-clamp-2">
26
26
  <div v-html="snippet(t)"></div>
27
27
  </div>
28
28
  </div>
29
29
  </div>
30
30
  </button>
31
31
  </td>
32
- <td class="py-3 px-1 border-b border-gray-200">
32
+ <td class="py-3 px-1 border-b border-gray-200 dark:border-gray-700">
33
33
  <div class="text-right whitespace-nowrap">
34
- <div class="text-xs text-gray-500">{{ formatDate(t.updatedAt || t.createdAt) }}</div>
35
- <div class="text-[11px] text-gray-500/80">{{ (t.messages?.length || 0) }} messages</div>
36
- <div v-if="t.model" class="text-[11px] text-blue-600">{{ t.model }}</div>
34
+ <div class="text-xs text-gray-500 dark:text-gray-400">{{ formatDate(t.updatedAt || t.createdAt) }}</div>
35
+ <div class="text-[11px] text-gray-500/80 dark:text-gray-400/80">{{ (t.messages?.length || 0) }} messages</div>
36
+ <div v-if="t.model" class="text-[11px] text-blue-600 dark:text-blue-400">{{ t.model }}</div>
37
37
  </div>
38
38
  </td>
39
39
  </tr>
@@ -152,16 +152,16 @@ export default {
152
152
  template: `
153
153
  <div class="flex flex-col h-full w-full">
154
154
  <!-- Header -->
155
- <div class="border-b border-gray-200 bg-white px-4 py-3 min-h-16">
155
+ <div class="border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 px-4 py-3 min-h-16">
156
156
  <div class="max-w-6xl mx-auto flex items-center justify-between gap-3">
157
- <h2 class="text-lg font-semibold text-gray-900">Search Chats</h2>
157
+ <h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Search Chats</h2>
158
158
  <div class="flex-1 flex items-center gap-2">
159
159
  <input
160
160
  v-model="q"
161
161
  type="search"
162
162
  placeholder="Search titles and messages..."
163
163
  spellcheck="false"
164
- class="w-full rounded-md border border-gray-300 px-3 py-2 text-sm placeholder-gray-500 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
164
+ class="w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm placeholder-gray-500 dark:placeholder-gray-400 focus:border-blue-500 dark:focus:border-blue-400 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:focus:ring-blue-400"
165
165
  />
166
166
  </div>
167
167
  </div>
@@ -113,11 +113,11 @@ export default {
113
113
  <div class="fixed inset-0 bg-black/40 transition-opacity" @click="close"></div>
114
114
 
115
115
  <!-- Dialog -->
116
- <div class="relative bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-hidden">
116
+ <div class="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-hidden">
117
117
  <!-- Header -->
118
- <div class="flex items-center justify-between px-6 py-4 border-b border-gray-200">
119
- <h2 class="text-xl font-semibold text-gray-900">Chat Request Settings</h2>
120
- <button type="button" @click="close" class="text-gray-400 hover:text-gray-600">
118
+ <div class="flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700">
119
+ <h2 class="text-xl font-semibold text-gray-900 dark:text-gray-100">Chat Request Settings</h2>
120
+ <button type="button" @click="close" class="text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-300">
121
121
  <svg class="size-6" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
122
122
  <path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z"/>
123
123
  </svg>
@@ -126,201 +126,201 @@ export default {
126
126
 
127
127
  <!-- Content -->
128
128
  <form class="px-6 py-4 overflow-y-auto max-h-[calc(90vh-140px)]" @submit.prevent="save">
129
- <p class="text-sm text-gray-600 mb-4">
129
+ <p class="text-sm text-gray-600 dark:text-gray-400 mb-4">
130
130
  Configure default values for chat request options. Leave empty to use model defaults.
131
131
  </p>
132
132
 
133
133
  <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
134
134
  <!-- Temperature -->
135
135
  <div>
136
- <label class="block text-sm font-medium text-gray-700 mb-1">
136
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
137
137
  Temperature
138
- <span class="text-gray-500 font-normal">(0-2)</span>
138
+ <span class="text-gray-500 dark:text-gray-400 font-normal">(0-2)</span>
139
139
  </label>
140
- <input type="number" v-model="localSettings.temperature"
140
+ <input type="number" v-model="localSettings.temperature"
141
141
  step="0.1" min="0" max="2"
142
142
  placeholder="e.g., 0.7"
143
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
144
- <p class="mt-1 text-xs text-gray-500">Higher values more random, lower for more focus</p>
143
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
144
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Higher values more random, lower for more focus</p>
145
145
  </div>
146
146
 
147
147
  <!-- Max Completion Tokens -->
148
148
  <div>
149
- <label class="block text-sm font-medium text-gray-700 mb-1">
149
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
150
150
  Max Completion Tokens
151
151
  </label>
152
- <input type="number" v-model="localSettings.max_completion_tokens"
152
+ <input type="number" v-model="localSettings.max_completion_tokens"
153
153
  step="1" min="1"
154
154
  placeholder="e.g., 2048"
155
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
156
- <p class="mt-1 text-xs text-gray-500">Max tokens for completion (inc. reasoning tokens)</p>
155
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
156
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Max tokens for completion (inc. reasoning tokens)</p>
157
157
  </div>
158
158
 
159
159
  <!-- Seed -->
160
160
  <div>
161
- <label class="block text-sm font-medium text-gray-700 mb-1">
161
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
162
162
  Seed
163
163
  </label>
164
- <input type="number" v-model="localSettings.seed"
164
+ <input type="number" v-model="localSettings.seed"
165
165
  step="1"
166
166
  placeholder="e.g., 42"
167
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
168
- <p class="mt-1 text-xs text-gray-500">For deterministic sampling (Beta feature)</p>
167
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
168
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">For deterministic sampling (Beta feature)</p>
169
169
  </div>
170
170
 
171
171
  <!-- Top P -->
172
172
  <div>
173
- <label class="block text-sm font-medium text-gray-700 mb-1">
173
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
174
174
  Top P
175
- <span class="text-gray-500 font-normal">(0-1)</span>
175
+ <span class="text-gray-500 dark:text-gray-400 font-normal">(0-1)</span>
176
176
  </label>
177
- <input type="number" v-model="localSettings.top_p"
177
+ <input type="number" v-model="localSettings.top_p"
178
178
  step="0.1" min="0" max="1"
179
179
  placeholder="e.g., 0.9"
180
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
181
- <p class="mt-1 text-xs text-gray-500">Nucleus sampling - alternative to temperature</p>
180
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
181
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Nucleus sampling - alternative to temperature</p>
182
182
  </div>
183
183
 
184
184
  <!-- Frequency Penalty -->
185
185
  <div>
186
- <label class="block text-sm font-medium text-gray-700 mb-1">
186
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
187
187
  Frequency Penalty
188
- <span class="text-gray-500 font-normal">(-2.0 to 2.0)</span>
188
+ <span class="text-gray-500 dark:text-gray-400 font-normal">(-2.0 to 2.0)</span>
189
189
  </label>
190
- <input type="number" v-model="localSettings.frequency_penalty"
190
+ <input type="number" v-model="localSettings.frequency_penalty"
191
191
  step="0.1" min="-2" max="2"
192
192
  placeholder="e.g., 0.5"
193
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
194
- <p class="mt-1 text-xs text-gray-500">Penalize tokens based on frequency in text</p>
193
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
194
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Penalize tokens based on frequency in text</p>
195
195
  </div>
196
196
 
197
197
  <!-- Presence Penalty -->
198
198
  <div>
199
- <label class="block text-sm font-medium text-gray-700 mb-1">
199
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
200
200
  Presence Penalty
201
- <span class="text-gray-500 font-normal">(-2.0 to 2.0)</span>
201
+ <span class="text-gray-500 dark:text-gray-400 font-normal">(-2.0 to 2.0)</span>
202
202
  </label>
203
- <input type="number" v-model="localSettings.presence_penalty"
203
+ <input type="number" v-model="localSettings.presence_penalty"
204
204
  step="0.1" min="-2" max="2"
205
205
  placeholder="e.g., 0.5"
206
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
207
- <p class="mt-1 text-xs text-gray-500">Penalize tokens based on presence in text</p>
206
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
207
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Penalize tokens based on presence in text</p>
208
208
  </div>
209
209
 
210
210
  <!-- Stop Sequences -->
211
211
  <div>
212
- <label for="stop" class="block text-sm font-medium text-gray-700 mb-1">
212
+ <label for="stop" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
213
213
  Stop Sequences
214
214
  </label>
215
215
  <TagInput id="stop" inputClass="h-[37px] !shadow-none"
216
216
  v-model="localSettings.stop"
217
- placeholder=""
217
+ placeholder=""
218
218
  label=""
219
219
  />
220
- <p class="mt-1 text-xs text-gray-500">Up to 4 sequences where API stops generating</p>
220
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Up to 4 sequences where API stops generating</p>
221
221
  </div>
222
222
 
223
223
  <!-- Reasoning Effort -->
224
224
  <div>
225
- <label class="block text-sm font-medium text-gray-700 mb-1">
225
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
226
226
  Reasoning Effort
227
227
  </label>
228
228
  <select v-model="localSettings.reasoning_effort"
229
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
229
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
230
230
  <option value="">Default</option>
231
231
  <option value="minimal">Minimal</option>
232
232
  <option value="low">Low</option>
233
233
  <option value="medium">Medium</option>
234
234
  <option value="high">High</option>
235
235
  </select>
236
- <p class="mt-1 text-xs text-gray-500">Constrains effort on reasoning for reasoning models</p>
236
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Constrains effort on reasoning for reasoning models</p>
237
237
  </div>
238
238
 
239
239
  <!-- Verbosity -->
240
240
  <div>
241
- <label class="block text-sm font-medium text-gray-700 mb-1">
241
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
242
242
  Verbosity
243
243
  </label>
244
244
  <select v-model="localSettings.verbosity"
245
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
245
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500">
246
246
  <option value="">Default</option>
247
247
  <option value="low">Low</option>
248
248
  <option value="medium">Medium</option>
249
249
  <option value="high">High</option>
250
250
  </select>
251
- <p class="mt-1 text-xs text-gray-500">Constrains verbosity of model's response</p>
251
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Constrains verbosity of model's response</p>
252
252
  </div>
253
253
 
254
254
  <!-- Service Tier -->
255
255
  <div>
256
- <label class="block text-sm font-medium text-gray-700 mb-1">
256
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
257
257
  Service Tier
258
258
  </label>
259
- <input type="text" v-model="localSettings.service_tier"
259
+ <input type="text" v-model="localSettings.service_tier"
260
260
  placeholder="e.g., auto, default"
261
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
262
- <p class="mt-1 text-xs text-gray-500">Processing type for serving the request</p>
261
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
262
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Processing type for serving the request</p>
263
263
  </div>
264
264
 
265
265
  <!-- Top Logprobs -->
266
266
  <div>
267
- <label class="block text-sm font-medium text-gray-700 mb-1">
267
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
268
268
  Top Logprobs
269
- <span class="text-gray-500 font-normal">(0-20)</span>
269
+ <span class="text-gray-500 dark:text-gray-400 font-normal">(0-20)</span>
270
270
  </label>
271
- <input type="number" v-model="localSettings.top_logprobs"
271
+ <input type="number" v-model="localSettings.top_logprobs"
272
272
  step="1" min="0" max="20"
273
273
  placeholder="e.g., 5"
274
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
275
- <p class="mt-1 text-xs text-gray-500">Number of most likely tokens to return with log probs</p>
274
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
275
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Number of most likely tokens to return with log probs</p>
276
276
  </div>
277
277
 
278
278
  <!-- Safety Identifier -->
279
279
  <div>
280
- <label class="block text-sm font-medium text-gray-700 mb-1">
280
+ <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
281
281
  Safety Identifier
282
282
  </label>
283
- <input type="text" v-model="localSettings.safety_identifier"
283
+ <input type="text" v-model="localSettings.safety_identifier"
284
284
  placeholder="Unique user identifier"
285
- class="block w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
286
- <p class="mt-1 text-xs text-gray-500">Identifier to help detect policy violations</p>
285
+ class="block w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" />
286
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Identifier to help detect policy violations</p>
287
287
  </div>
288
288
 
289
289
  <!-- Store -->
290
290
  <div>
291
291
  <label class="flex items-center">
292
292
  <input type="checkbox" v-model="localSettings.store"
293
- class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
294
- <span class="ml-2 text-sm font-medium text-gray-700">Store Output</span>
293
+ class="rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500" />
294
+ <span class="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300">Store Output</span>
295
295
  </label>
296
- <p class="mt-1 text-xs text-gray-500">Store output for model distillation or evals</p>
296
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Store output for model distillation or evals</p>
297
297
  </div>
298
298
 
299
299
  <!-- Enable Thinking -->
300
300
  <div>
301
301
  <label class="flex items-center">
302
302
  <input type="checkbox" v-model="localSettings.enable_thinking"
303
- class="rounded border-gray-300 text-blue-600 focus:ring-blue-500" />
304
- <span class="ml-2 text-sm font-medium text-gray-700">Enable Thinking</span>
303
+ class="rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500" />
304
+ <span class="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300">Enable Thinking</span>
305
305
  </label>
306
- <p class="mt-1 text-xs text-gray-500">Enable thinking mode for supported models (Qwen)</p>
306
+ <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">Enable thinking mode for supported models (Qwen)</p>
307
307
  </div>
308
308
  </div>
309
309
  </form>
310
310
 
311
311
  <!-- Footer -->
312
- <div class="flex items-center justify-between px-6 py-4 border-t border-gray-200 bg-gray-50">
312
+ <div class="flex items-center justify-between px-6 py-4 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800">
313
313
  <button type="button" @click="reset"
314
- class="px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-900">
314
+ class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100">
315
315
  Reset to Defaults
316
316
  </button>
317
317
  <div class="flex space-x-3">
318
318
  <button type="button" @click="close"
319
- class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50">
319
+ class="px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700">
320
320
  Cancel
321
321
  </button>
322
322
  <button type="submit" @click="save"
323
- class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700">
323
+ class="px-4 py-2 text-sm font-medium text-white bg-blue-600 dark:bg-blue-500 rounded-md hover:bg-blue-700 dark:hover:bg-blue-600">
324
324
  Save Settings
325
325
  </button>
326
326
  </div>