llms-py 3.0.0b1__py3-none-any.whl → 3.0.0b3__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/__pycache__/__init__.cpython-312.pyc +0 -0
- llms/__pycache__/__init__.cpython-313.pyc +0 -0
- llms/__pycache__/__init__.cpython-314.pyc +0 -0
- llms/__pycache__/__main__.cpython-312.pyc +0 -0
- llms/__pycache__/__main__.cpython-314.pyc +0 -0
- llms/__pycache__/llms.cpython-312.pyc +0 -0
- llms/__pycache__/main.cpython-312.pyc +0 -0
- llms/__pycache__/main.cpython-313.pyc +0 -0
- llms/__pycache__/main.cpython-314.pyc +0 -0
- llms/__pycache__/plugins.cpython-314.pyc +0 -0
- llms/index.html +27 -57
- llms/llms.json +48 -15
- llms/main.py +923 -624
- llms/providers/__pycache__/anthropic.cpython-314.pyc +0 -0
- llms/providers/__pycache__/chutes.cpython-314.pyc +0 -0
- llms/providers/__pycache__/google.cpython-314.pyc +0 -0
- llms/providers/__pycache__/nvidia.cpython-314.pyc +0 -0
- llms/providers/__pycache__/openai.cpython-314.pyc +0 -0
- llms/providers/__pycache__/openrouter.cpython-314.pyc +0 -0
- llms/providers/anthropic.py +189 -0
- llms/providers/chutes.py +152 -0
- llms/providers/google.py +306 -0
- llms/providers/nvidia.py +107 -0
- llms/providers/openai.py +159 -0
- llms/providers/openrouter.py +70 -0
- llms/providers-extra.json +356 -0
- llms/providers.json +1 -1
- llms/ui/App.mjs +150 -57
- llms/ui/ai.mjs +84 -50
- llms/ui/app.css +1 -4963
- llms/ui/ctx.mjs +196 -0
- llms/ui/index.mjs +117 -0
- llms/ui/lib/charts.mjs +9 -13
- llms/ui/markdown.mjs +6 -0
- llms/ui/{Analytics.mjs → modules/analytics.mjs} +76 -64
- llms/ui/{Main.mjs → modules/chat/ChatBody.mjs} +91 -179
- llms/ui/{SettingsDialog.mjs → modules/chat/SettingsDialog.mjs} +8 -8
- llms/ui/{ChatPrompt.mjs → modules/chat/index.mjs} +281 -96
- llms/ui/modules/layout.mjs +267 -0
- llms/ui/modules/model-selector.mjs +851 -0
- llms/ui/{Recents.mjs → modules/threads/Recents.mjs} +10 -11
- llms/ui/{Sidebar.mjs → modules/threads/index.mjs} +48 -45
- llms/ui/{threadStore.mjs → modules/threads/threadStore.mjs} +21 -7
- llms/ui/tailwind.input.css +441 -79
- llms/ui/utils.mjs +83 -123
- {llms_py-3.0.0b1.dist-info → llms_py-3.0.0b3.dist-info}/METADATA +1 -1
- llms_py-3.0.0b3.dist-info/RECORD +65 -0
- llms/ui/Avatar.mjs +0 -85
- llms/ui/Brand.mjs +0 -52
- llms/ui/ModelSelector.mjs +0 -693
- llms/ui/OAuthSignIn.mjs +0 -92
- llms/ui/ProviderIcon.mjs +0 -36
- llms/ui/ProviderStatus.mjs +0 -105
- llms/ui/SignIn.mjs +0 -64
- llms/ui/SystemPromptEditor.mjs +0 -31
- llms/ui/SystemPromptSelector.mjs +0 -56
- llms/ui/Welcome.mjs +0 -8
- llms/ui.json +0 -1069
- llms_py-3.0.0b1.dist-info/RECORD +0 -49
- {llms_py-3.0.0b1.dist-info → llms_py-3.0.0b3.dist-info}/WHEEL +0 -0
- {llms_py-3.0.0b1.dist-info → llms_py-3.0.0b3.dist-info}/entry_points.txt +0 -0
- {llms_py-3.0.0b1.dist-info → llms_py-3.0.0b3.dist-info}/licenses/LICENSE +0 -0
- {llms_py-3.0.0b1.dist-info → llms_py-3.0.0b3.dist-info}/top_level.txt +0 -0
llms/ui/ctx.mjs
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
|
|
2
|
+
import { reactive } from 'vue'
|
|
3
|
+
import { EventBus, humanize, combinePaths } from "@servicestack/client"
|
|
4
|
+
import { storageObject } from './utils.mjs'
|
|
5
|
+
|
|
6
|
+
export class ExtensionScope {
|
|
7
|
+
constructor(ctx, id) {
|
|
8
|
+
/**@type {AppContext} */
|
|
9
|
+
this.ctx = ctx
|
|
10
|
+
this.id = id
|
|
11
|
+
this.baseUrl = `${ctx.ai.base}/ext/${this.id}`
|
|
12
|
+
this.storageKey = `llms.${this.id}`
|
|
13
|
+
this.state = reactive({})
|
|
14
|
+
}
|
|
15
|
+
getPrefs() {
|
|
16
|
+
return storageObject(this.storageKey)
|
|
17
|
+
}
|
|
18
|
+
setPrefs(o) {
|
|
19
|
+
storageObject(this.storageKey, Object.assign(this.getPrefs(), o))
|
|
20
|
+
}
|
|
21
|
+
get(url, options) {
|
|
22
|
+
return this.ctx.ai.get(combinePaths(this.baseUrl, url), options)
|
|
23
|
+
}
|
|
24
|
+
async getJson(url, options) {
|
|
25
|
+
return this.ctx.ai.getJson(combinePaths(this.baseUrl, url), options)
|
|
26
|
+
}
|
|
27
|
+
post(url, options) {
|
|
28
|
+
return this.ctx.ai.post(combinePaths(this.baseUrl, url), options)
|
|
29
|
+
}
|
|
30
|
+
async postJson(url, options) {
|
|
31
|
+
return this.ctx.ai.postJson(combinePaths(this.baseUrl, url), options)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class AppContext {
|
|
36
|
+
constructor({ app, routes, ai, fmt, utils }) {
|
|
37
|
+
this.app = app
|
|
38
|
+
this.routes = routes
|
|
39
|
+
this.ai = ai
|
|
40
|
+
this.fmt = fmt
|
|
41
|
+
this.utils = utils
|
|
42
|
+
this._components = {}
|
|
43
|
+
|
|
44
|
+
this.state = reactive({})
|
|
45
|
+
this.events = new EventBus()
|
|
46
|
+
this.modalComponents = {}
|
|
47
|
+
this.extensions = []
|
|
48
|
+
this.layout = reactive(storageObject(`llms.layout`))
|
|
49
|
+
this.chatRequestFilters = []
|
|
50
|
+
this.chatResponseFilters = []
|
|
51
|
+
this.chatErrorFilters = []
|
|
52
|
+
this.createThreadFilters = []
|
|
53
|
+
this.updateThreadFilters = []
|
|
54
|
+
this.top = {}
|
|
55
|
+
this.left = {}
|
|
56
|
+
|
|
57
|
+
if (!Array.isArray(this.layout.hide)) {
|
|
58
|
+
this.layout.hide = []
|
|
59
|
+
}
|
|
60
|
+
Object.assign(app.config.globalProperties, {
|
|
61
|
+
$ctx: this,
|
|
62
|
+
$state: this.state,
|
|
63
|
+
$layout: this.layout,
|
|
64
|
+
$ai: ai,
|
|
65
|
+
$fmt: fmt,
|
|
66
|
+
$utils: utils,
|
|
67
|
+
})
|
|
68
|
+
Object.keys(app.config.globalProperties).forEach(key => {
|
|
69
|
+
globalThis[key] = app.config.globalProperties[key]
|
|
70
|
+
})
|
|
71
|
+
document.addEventListener('keydown', (e) => this.handleKeydown(e))
|
|
72
|
+
}
|
|
73
|
+
async init() {
|
|
74
|
+
Object.assign(this.state, await this.ai.init(this))
|
|
75
|
+
}
|
|
76
|
+
setGlobals(globals) {
|
|
77
|
+
Object.entries(globals).forEach(([name, global]) => {
|
|
78
|
+
const globalName = '$' + name
|
|
79
|
+
globalThis[globalName] = this.app.config.globalProperties[globalName] = global
|
|
80
|
+
this[name] = global
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
_validateIcons(icons) {
|
|
84
|
+
Object.entries(icons).forEach(([id, icon]) => {
|
|
85
|
+
if (!icon.component) {
|
|
86
|
+
console.error(`Icon ${id} is missing component property`)
|
|
87
|
+
}
|
|
88
|
+
icon.id = id
|
|
89
|
+
if (!icon.name) {
|
|
90
|
+
icon.name = humanize(id)
|
|
91
|
+
}
|
|
92
|
+
if (typeof icon.isActive != 'function') {
|
|
93
|
+
icon.isActive = () => false
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
return icons
|
|
97
|
+
}
|
|
98
|
+
setTopIcons(icons) {
|
|
99
|
+
Object.assign(this.top, this._validateIcons(icons))
|
|
100
|
+
}
|
|
101
|
+
setLeftIcons(icons) {
|
|
102
|
+
Object.assign(this.left, this._validateIcons(icons))
|
|
103
|
+
}
|
|
104
|
+
component(name, component) {
|
|
105
|
+
if (!name) return name
|
|
106
|
+
if (component) {
|
|
107
|
+
this._components[name] = component
|
|
108
|
+
}
|
|
109
|
+
return component || this._components[name] || this.app.component(name)
|
|
110
|
+
}
|
|
111
|
+
components(components) {
|
|
112
|
+
if (components) {
|
|
113
|
+
Object.keys(components).forEach(name => {
|
|
114
|
+
this._components[name] = components[name]
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
return this._components
|
|
118
|
+
}
|
|
119
|
+
scope(extension) {
|
|
120
|
+
return new ExtensionScope(this, extension)
|
|
121
|
+
}
|
|
122
|
+
modals(modals) {
|
|
123
|
+
Object.keys(modals).forEach(name => {
|
|
124
|
+
this.modalComponents[name] = modals[name]
|
|
125
|
+
this.component(name, modals[name])
|
|
126
|
+
})
|
|
127
|
+
}
|
|
128
|
+
openModal(name) {
|
|
129
|
+
const component = this.modalComponents[name]
|
|
130
|
+
if (!component) {
|
|
131
|
+
console.error(`Modal ${name} not found`)
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
console.debug('openModal', name)
|
|
135
|
+
this.router.push({ query: { open: name } })
|
|
136
|
+
this.events.publish('modal:open', name)
|
|
137
|
+
return component
|
|
138
|
+
}
|
|
139
|
+
closeModal(name) {
|
|
140
|
+
console.debug('closeModal', name)
|
|
141
|
+
this.router.push({ query: { open: undefined } })
|
|
142
|
+
this.events.publish('modal:close', name)
|
|
143
|
+
}
|
|
144
|
+
handleKeydown(e) {
|
|
145
|
+
if (e.key === 'Escape') {
|
|
146
|
+
const modal = this.router.currentRoute.value?.query?.open
|
|
147
|
+
if (modal) {
|
|
148
|
+
this.closeModal(modal)
|
|
149
|
+
}
|
|
150
|
+
this.events.publish(`keydown:Escape`, e)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
setState(o) {
|
|
154
|
+
Object.assign(this.state, o)
|
|
155
|
+
//this.events.publish('update:state', this.state)
|
|
156
|
+
}
|
|
157
|
+
setLayout(o) {
|
|
158
|
+
Object.assign(this.layout, o)
|
|
159
|
+
storageObject(`llms.layout`, this.layout)
|
|
160
|
+
}
|
|
161
|
+
toggleLayout(key, toggle = undefined) {
|
|
162
|
+
const hide = toggle == undefined
|
|
163
|
+
? !this.layout.hide.includes(key)
|
|
164
|
+
: !toggle
|
|
165
|
+
console.log('toggleLayout', key, hide)
|
|
166
|
+
if (hide) {
|
|
167
|
+
this.layout.hide.push(key)
|
|
168
|
+
} else {
|
|
169
|
+
this.layout.hide = this.layout.hide.filter(k => k != key)
|
|
170
|
+
}
|
|
171
|
+
storageObject(`llms.layout`, this.layout)
|
|
172
|
+
}
|
|
173
|
+
layoutVisible(key) {
|
|
174
|
+
return !this.layout.hide.includes(key)
|
|
175
|
+
}
|
|
176
|
+
getPrefs() {
|
|
177
|
+
return storageObject(this.ai.prefsKey)
|
|
178
|
+
}
|
|
179
|
+
setPrefs(o) {
|
|
180
|
+
storageObject(this.ai.prefsKey, Object.assign(this.getPrefs(), o))
|
|
181
|
+
}
|
|
182
|
+
toggleTop(name) {
|
|
183
|
+
console.log('toggleTop', name)
|
|
184
|
+
this.layout.top = this.layout.top == name ? undefined : name
|
|
185
|
+
storageObject(`llms.layout`, this.layout)
|
|
186
|
+
}
|
|
187
|
+
togglePath(path) {
|
|
188
|
+
const currentPath = this.router.currentRoute.value?.path
|
|
189
|
+
console.log('togglePath', path, currentPath)
|
|
190
|
+
if (currentPath == path) {
|
|
191
|
+
this.toggleLayout('left')
|
|
192
|
+
} else {
|
|
193
|
+
this.router.push({ path })
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
llms/ui/index.mjs
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
|
|
2
|
+
import { createApp } from 'vue'
|
|
3
|
+
import { createWebHistory, createRouter } from "vue-router"
|
|
4
|
+
import ServiceStackVue, { useFormatters } from "@servicestack/vue"
|
|
5
|
+
import App from './App.mjs'
|
|
6
|
+
import ai from './ai.mjs'
|
|
7
|
+
import LayoutModule from './modules/layout.mjs'
|
|
8
|
+
import ChatModule from './modules/chat/index.mjs'
|
|
9
|
+
import ThreadsModule from './modules/threads/index.mjs'
|
|
10
|
+
import ModelSelectorModule from './modules/model-selector.mjs'
|
|
11
|
+
import AnalyticsModule from './modules/analytics.mjs'
|
|
12
|
+
import { utilsFunctions, utilsFormatters } from './utils.mjs'
|
|
13
|
+
import { markdownFormatters } from './markdown.mjs'
|
|
14
|
+
import { AppContext } from './ctx.mjs'
|
|
15
|
+
|
|
16
|
+
const Components = {
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const BuiltInModules = {
|
|
20
|
+
LayoutModule,
|
|
21
|
+
ChatModule,
|
|
22
|
+
ThreadsModule,
|
|
23
|
+
ModelSelectorModule,
|
|
24
|
+
AnalyticsModule,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
export async function createContext() {
|
|
29
|
+
const app = createApp(App)
|
|
30
|
+
|
|
31
|
+
app.use(ServiceStackVue)
|
|
32
|
+
Object.keys(Components).forEach(name => {
|
|
33
|
+
app.component(name, Components[name])
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const fmt = Object.assign({}, useFormatters(), utilsFormatters(), markdownFormatters())
|
|
37
|
+
const utils = Object.assign({}, utilsFunctions())
|
|
38
|
+
const routes = []
|
|
39
|
+
|
|
40
|
+
const ctx = new AppContext({ app, routes, ai, fmt, utils })
|
|
41
|
+
app.provide('ctx', ctx)
|
|
42
|
+
await ctx.init()
|
|
43
|
+
|
|
44
|
+
// Load modules in parallel
|
|
45
|
+
const validExtensions = ctx.state.extensions.filter(x => x.path);
|
|
46
|
+
ctx.modules = await Promise.all(validExtensions.map(async extension => {
|
|
47
|
+
try {
|
|
48
|
+
const module = await import(extension.path)
|
|
49
|
+
return { extension, module }
|
|
50
|
+
} catch (e) {
|
|
51
|
+
console.error(`Failed to load extension module ${extension.name}:`, e)
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
// Install built-in modules sequentially
|
|
57
|
+
Object.entries(BuiltInModules).forEach(([name, module]) => {
|
|
58
|
+
try {
|
|
59
|
+
module.install(ctx)
|
|
60
|
+
console.log(`Installed built-in: ${name}`)
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.error(`Failed to install built-in ${name}:`, e)
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// Install extensions sequentially
|
|
67
|
+
for (const result of ctx.modules) {
|
|
68
|
+
if (result && result.module.default && result.module.default.install) {
|
|
69
|
+
try {
|
|
70
|
+
result.module.default.install(ctx)
|
|
71
|
+
console.log(`Installed extension: ${result.extension.id}`)
|
|
72
|
+
} catch (e) {
|
|
73
|
+
console.error(`Failed to install extension ${result.extension.id}:`, e)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Register all components with Vue
|
|
79
|
+
Object.entries(ctx._components).forEach(([name, component]) => {
|
|
80
|
+
app.component(name, component)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// Add fallback route and create router
|
|
84
|
+
routes.push({ path: '/:fallback(.*)*', component: ctx.component('Home') })
|
|
85
|
+
routes.forEach(r => r.path = ai.base + r.path)
|
|
86
|
+
ctx.router = createRouter({
|
|
87
|
+
history: createWebHistory(),
|
|
88
|
+
routes,
|
|
89
|
+
})
|
|
90
|
+
app.use(ctx.router)
|
|
91
|
+
|
|
92
|
+
ctx.router.beforeEach((to, from) => {
|
|
93
|
+
const title = to.meta.title || 'Chat'
|
|
94
|
+
console.log('beforeEach', to.path, title)
|
|
95
|
+
ctx.setLayout({ path: to.path })
|
|
96
|
+
ctx.setState({ title })
|
|
97
|
+
document.title = title
|
|
98
|
+
return true
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
if (ctx.layout.path && location.pathname === '/' && !location.search) {
|
|
102
|
+
console.log('redirecting to saved path: ', ctx.layout.path)
|
|
103
|
+
ctx.router.push({ path: ctx.layout.path })
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Load all extensions in parallel
|
|
107
|
+
await Promise.all(ctx.modules.filter(x => x.module.default && x.module.default.load).map(async result => {
|
|
108
|
+
try {
|
|
109
|
+
await result.module.default.load(ctx)
|
|
110
|
+
console.log(`Loaded extension: ${result.extension.id}`)
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.error(`Failed to load extension ${result.extension.id}:`, e)
|
|
113
|
+
}
|
|
114
|
+
}))
|
|
115
|
+
|
|
116
|
+
return ctx
|
|
117
|
+
}
|
llms/ui/lib/charts.mjs
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import { useFormatters, useUtils } from "@servicestack/vue"
|
|
2
1
|
import { Chart, registerables } from "chart.js"
|
|
3
2
|
Chart.register(...registerables)
|
|
4
3
|
|
|
5
|
-
const
|
|
6
|
-
const { delay } = useUtils()
|
|
7
|
-
|
|
8
|
-
export const resultLimits = [5,10,25,50,100]
|
|
4
|
+
export const resultLimits = [5, 10, 25, 50, 100]
|
|
9
5
|
export const colors = [
|
|
10
|
-
{ background: 'rgba(54, 162, 235, 0.2)',
|
|
11
|
-
{ background: 'rgba(255, 99, 132, 0.2)',
|
|
6
|
+
{ background: 'rgba(54, 162, 235, 0.2)', border: 'rgb(54, 162, 235)' }, //blue
|
|
7
|
+
{ background: 'rgba(255, 99, 132, 0.2)', border: 'rgb(255, 99, 132)' },
|
|
12
8
|
{ background: 'rgba(153, 102, 255, 0.2)', border: 'rgb(153, 102, 255)' },
|
|
13
|
-
{ background: 'rgba(54, 162, 235, 0.2)',
|
|
14
|
-
{ background: 'rgba(255, 159, 64, 0.2)',
|
|
15
|
-
{ background: 'rgba(67, 56, 202, 0.2)',
|
|
16
|
-
{ background: 'rgba(255, 99, 132, 0.2)',
|
|
17
|
-
{ background: 'rgba(14, 116, 144, 0.2)',
|
|
18
|
-
{ background: 'rgba(162, 28, 175, 0.2)',
|
|
9
|
+
{ background: 'rgba(54, 162, 235, 0.2)', border: 'rgb(54, 162, 235)' },
|
|
10
|
+
{ background: 'rgba(255, 159, 64, 0.2)', border: 'rgb(255, 159, 64)' },
|
|
11
|
+
{ background: 'rgba(67, 56, 202, 0.2)', border: 'rgb(67, 56, 202)' },
|
|
12
|
+
{ background: 'rgba(255, 99, 132, 0.2)', border: 'rgb(255, 99, 132)' },
|
|
13
|
+
{ background: 'rgba(14, 116, 144, 0.2)', border: 'rgb(14, 116, 144)' },
|
|
14
|
+
{ background: 'rgba(162, 28, 175, 0.2)', border: 'rgb(162, 28, 175)' },
|
|
19
15
|
{ background: 'rgba(201, 203, 207, 0.2)', border: 'rgb(201, 203, 207)' },
|
|
20
16
|
]
|