llms-py 3.0.10__py3-none-any.whl → 3.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.
- llms/extensions/app/__init__.py +0 -1
- llms/extensions/app/db.py +7 -3
- llms/extensions/app/ui/threadStore.mjs +10 -3
- llms/extensions/computer/README.md +96 -0
- llms/extensions/computer/__init__.py +59 -0
- llms/extensions/computer/base.py +80 -0
- llms/extensions/computer/bash.py +185 -0
- llms/extensions/computer/computer.py +523 -0
- llms/extensions/computer/edit.py +299 -0
- llms/extensions/computer/filesystem.py +542 -0
- llms/extensions/computer/platform.py +461 -0
- llms/extensions/computer/run.py +37 -0
- llms/extensions/core_tools/__init__.py +0 -38
- llms/extensions/providers/anthropic.py +28 -1
- llms/extensions/providers/cerebras.py +0 -1
- llms/extensions/providers/google.py +112 -34
- llms/extensions/skills/LICENSE +202 -0
- llms/extensions/skills/__init__.py +130 -0
- llms/extensions/skills/errors.py +25 -0
- llms/extensions/skills/models.py +39 -0
- llms/extensions/skills/parser.py +178 -0
- llms/extensions/skills/ui/index.mjs +376 -0
- llms/extensions/skills/ui/skills/create-plan/SKILL.md +74 -0
- llms/extensions/skills/validator.py +177 -0
- llms/extensions/system_prompts/ui/index.mjs +6 -10
- llms/extensions/tools/__init__.py +5 -82
- llms/extensions/tools/ui/index.mjs +194 -63
- llms/main.py +502 -146
- llms/ui/ai.mjs +1 -1
- llms/ui/app.css +530 -0
- llms/ui/ctx.mjs +53 -6
- llms/ui/modules/chat/ChatBody.mjs +200 -20
- llms/ui/modules/chat/index.mjs +108 -104
- llms/ui/tailwind.input.css +10 -0
- llms/ui/utils.mjs +25 -1
- {llms_py-3.0.10.dist-info → llms_py-3.0.18.dist-info}/METADATA +2 -2
- {llms_py-3.0.10.dist-info → llms_py-3.0.18.dist-info}/RECORD +41 -24
- {llms_py-3.0.10.dist-info → llms_py-3.0.18.dist-info}/WHEEL +1 -1
- {llms_py-3.0.10.dist-info → llms_py-3.0.18.dist-info}/entry_points.txt +0 -0
- {llms_py-3.0.10.dist-info → llms_py-3.0.18.dist-info}/licenses/LICENSE +0 -0
- {llms_py-3.0.10.dist-info → llms_py-3.0.18.dist-info}/top_level.txt +0 -0
|
@@ -2,6 +2,86 @@ import { inject, computed, ref, onMounted } from "vue"
|
|
|
2
2
|
|
|
3
3
|
let ext
|
|
4
4
|
|
|
5
|
+
function useTools(ctx) {
|
|
6
|
+
|
|
7
|
+
const availableTools = computed(() => ctx.state.tool.definitions.filter(x => x.function))
|
|
8
|
+
const toolPageHeaders = {}
|
|
9
|
+
|
|
10
|
+
function setToolPageHeaders(components) {
|
|
11
|
+
Object.assign(toolPageHeaders, components)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function selectTool({ group, tool }) {
|
|
15
|
+
ext.setPrefs({ selectedGroup: group, selectedTool: tool })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getToolDefinition(name) {
|
|
19
|
+
return ctx.state.tool.definitions.find(d => d.function?.name === name)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isToolEnabled(name) {
|
|
23
|
+
const toolDef = getToolDefinition(name)
|
|
24
|
+
if (!toolDef) return false
|
|
25
|
+
const onlyTools = ctx.prefs.onlyTools
|
|
26
|
+
if (onlyTools == null) return true
|
|
27
|
+
return Array.isArray(onlyTools) && onlyTools.includes(name)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function enableTool(name) {
|
|
31
|
+
let onlyTools = ctx.prefs.onlyTools
|
|
32
|
+
if (onlyTools == null) return // All tools are enabled
|
|
33
|
+
|
|
34
|
+
if (!Array.isArray(onlyTools)) {
|
|
35
|
+
onlyTools = [onlyTools]
|
|
36
|
+
}
|
|
37
|
+
else if (!onlyTools.includes(name)) {
|
|
38
|
+
onlyTools.push(name)
|
|
39
|
+
} else {
|
|
40
|
+
return // Already enabled
|
|
41
|
+
}
|
|
42
|
+
ctx.setPrefs({ onlyTools })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function disableTool(name) {
|
|
46
|
+
let onlyTools = ctx.prefs.onlyTools
|
|
47
|
+
if (onlyTools == null) {
|
|
48
|
+
// If currently 'All', clicking a tool means we enter custom mode with all OTHER tools selected
|
|
49
|
+
onlyTools = availableTools.value.map(t => t.function.name).filter(t => t !== name)
|
|
50
|
+
} else if (!Array.isArray(onlyTools)) {
|
|
51
|
+
onlyTools = []
|
|
52
|
+
} else {
|
|
53
|
+
onlyTools = onlyTools.filter(t => t !== name)
|
|
54
|
+
}
|
|
55
|
+
ctx.setPrefs({ onlyTools })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function toggleTool(name, enable = null) {
|
|
59
|
+
if (enable == null) {
|
|
60
|
+
enable = !isToolEnabled(name)
|
|
61
|
+
}
|
|
62
|
+
if (enable) {
|
|
63
|
+
enableTool(name)
|
|
64
|
+
} else {
|
|
65
|
+
disableTool(name)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
availableTools,
|
|
71
|
+
toolPageHeaders,
|
|
72
|
+
setToolPageHeaders,
|
|
73
|
+
selectTool,
|
|
74
|
+
getToolDefinition,
|
|
75
|
+
isToolEnabled,
|
|
76
|
+
enableTool,
|
|
77
|
+
disableTool,
|
|
78
|
+
toggleTool,
|
|
79
|
+
get selectedGroup() { return ext.prefs.selectedGroup },
|
|
80
|
+
get selectedTool() { return ext.prefs.selectedTool },
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
5
85
|
const ToolResult = {
|
|
6
86
|
template: `
|
|
7
87
|
<div>
|
|
@@ -18,10 +98,10 @@ const ToolResult = {
|
|
|
18
98
|
preview
|
|
19
99
|
</span>
|
|
20
100
|
</div>
|
|
21
|
-
<div class="not-prose
|
|
101
|
+
<div class="not-prose py-2">
|
|
22
102
|
<pre v-if="ext.prefs.toolFormat !== 'preview'" class="tool-output">{{ origResult }}</pre>
|
|
23
103
|
<div v-else>
|
|
24
|
-
<ViewTypes v-if="Array.isArray(result)" :results="result" />
|
|
104
|
+
<ViewTypes v-if="Array.isArray(result) && result[0]?.type" :results="result" />
|
|
25
105
|
<ViewType v-else :result="result" />
|
|
26
106
|
</div>
|
|
27
107
|
</div>
|
|
@@ -76,10 +156,92 @@ const ToolResult = {
|
|
|
76
156
|
}
|
|
77
157
|
}
|
|
78
158
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
159
|
+
const JsonInput = {
|
|
160
|
+
template: `
|
|
161
|
+
<div class="flex flex-col gap-1">
|
|
162
|
+
<div class="relative">
|
|
163
|
+
<textarea
|
|
164
|
+
v-model="localJson"
|
|
165
|
+
@input="validate"
|
|
166
|
+
rows="5"
|
|
167
|
+
class="w-full p-2 font-mono text-xs border rounded-md resize-y focus:outline-none focus:ring-2 transition-colors"
|
|
168
|
+
:class="error
|
|
169
|
+
? 'border-red-300 dark:border-red-700 bg-red-50 dark:bg-red-900/10 focus:ring-red-500'
|
|
170
|
+
: 'border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 focus:ring-blue-500'"
|
|
171
|
+
spellcheck="false"
|
|
172
|
+
></textarea>
|
|
173
|
+
<div v-if="isValid" class="absolute bottom-2 right-2 text-green-500 bg-white dark:bg-gray-800 rounded-full p-1 shadow-sm">
|
|
174
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor">
|
|
175
|
+
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
|
176
|
+
</svg>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
<div v-if="error" class="text-xs text-red-600 dark:text-red-400 font-medium px-1">
|
|
180
|
+
{{ error }}
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
`,
|
|
184
|
+
props: {
|
|
185
|
+
modelValue: {
|
|
186
|
+
required: true
|
|
187
|
+
}
|
|
82
188
|
},
|
|
189
|
+
emits: ['update:modelValue'],
|
|
190
|
+
setup(props, { emit }) {
|
|
191
|
+
// Initialize with formatted JSON
|
|
192
|
+
const localJson = ref(
|
|
193
|
+
props.modelValue !== undefined
|
|
194
|
+
? JSON.stringify(props.modelValue, null, 4)
|
|
195
|
+
: ''
|
|
196
|
+
)
|
|
197
|
+
const error = ref(null)
|
|
198
|
+
const isValid = ref(true)
|
|
199
|
+
|
|
200
|
+
function validate() {
|
|
201
|
+
try {
|
|
202
|
+
if (!localJson.value.trim()) {
|
|
203
|
+
// Decide if empty string is valid object/array or undefined
|
|
204
|
+
// For now, let's say empty is NOT valid if the prop expects object
|
|
205
|
+
// But maybe we can treat it as valid undefined/null?
|
|
206
|
+
// Let's enforce valid JSON.
|
|
207
|
+
if (localJson.value === '') {
|
|
208
|
+
error.value = null
|
|
209
|
+
isValid.value = true
|
|
210
|
+
emit('update:modelValue', undefined)
|
|
211
|
+
return
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const parsed = JSON.parse(localJson.value)
|
|
216
|
+
error.value = null
|
|
217
|
+
isValid.value = true
|
|
218
|
+
emit('update:modelValue', parsed)
|
|
219
|
+
} catch (e) {
|
|
220
|
+
error.value = e.message
|
|
221
|
+
isValid.value = false
|
|
222
|
+
// Do not emit invalid values
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Watch external changes only if they differ significantly from local
|
|
227
|
+
/*
|
|
228
|
+
Note: two-way binding with text representation is tricky.
|
|
229
|
+
If we watch props.modelValue, we might re-format user's in-progress typing if we aren't careful.
|
|
230
|
+
Usually better to only update localJson if the prop changes "from outside".
|
|
231
|
+
For this simple tool, initial value is likely enough, or we can watch with a deep compare check.
|
|
232
|
+
For now, let's stick to initial + internal validation.
|
|
233
|
+
*/
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
localJson,
|
|
237
|
+
error,
|
|
238
|
+
isValid,
|
|
239
|
+
validate
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const Tools = {
|
|
83
245
|
template: `
|
|
84
246
|
<div class="p-4 md:p-6 max-w-7xl mx-auto w-full relative">
|
|
85
247
|
<div v-if="Object.keys($ctx.tools.toolPageHeaders).length">
|
|
@@ -153,6 +315,10 @@ const Tools = {
|
|
|
153
315
|
</select>
|
|
154
316
|
</div>
|
|
155
317
|
|
|
318
|
+
<div v-else-if="prop.type === 'object' || prop.type === 'array'">
|
|
319
|
+
<JsonInput v-model="execForm[name]" />
|
|
320
|
+
</div>
|
|
321
|
+
|
|
156
322
|
<div v-else>
|
|
157
323
|
<input :type="prop.type === 'integer' || prop.type === 'number' ? 'number' : 'text'"
|
|
158
324
|
v-model="execForm[name]"
|
|
@@ -191,7 +357,7 @@ const Tools = {
|
|
|
191
357
|
</div>
|
|
192
358
|
|
|
193
359
|
<div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
|
|
194
|
-
<div v-for="tool in filteredTools" :key="tool.function.name"
|
|
360
|
+
<div v-for="tool in filteredTools" :key="tool.function.name" :id="'tool-' + tool.function.name"
|
|
195
361
|
class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col">
|
|
196
362
|
|
|
197
363
|
<div class="p-4 border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 flex justify-between items-center">
|
|
@@ -262,7 +428,6 @@ const Tools = {
|
|
|
262
428
|
const ctx = inject('ctx')
|
|
263
429
|
|
|
264
430
|
// Execution State
|
|
265
|
-
const executingTool = ref(null)
|
|
266
431
|
const execForm = ref({})
|
|
267
432
|
const execResult = ref(null)
|
|
268
433
|
const execError = ref(null)
|
|
@@ -270,6 +435,12 @@ const Tools = {
|
|
|
270
435
|
const refForm = ref()
|
|
271
436
|
const refTop = ref()
|
|
272
437
|
|
|
438
|
+
const executingTool = computed(() => {
|
|
439
|
+
const tool = ext.prefs.selectedTool
|
|
440
|
+
if (!tool) return null
|
|
441
|
+
return ctx.state.tool.definitions.find(x => x.function.name === tool)
|
|
442
|
+
})
|
|
443
|
+
|
|
273
444
|
// UI State
|
|
274
445
|
const expandedDescriptions = ref({})
|
|
275
446
|
|
|
@@ -284,7 +455,7 @@ const Tools = {
|
|
|
284
455
|
})
|
|
285
456
|
|
|
286
457
|
function startExec(tool) {
|
|
287
|
-
|
|
458
|
+
ext.setPrefs({ selectedTool: tool.function.name })
|
|
288
459
|
execForm.value = {}
|
|
289
460
|
execResult.value = null
|
|
290
461
|
execError.value = null
|
|
@@ -309,7 +480,7 @@ const Tools = {
|
|
|
309
480
|
}
|
|
310
481
|
|
|
311
482
|
function closeExec() {
|
|
312
|
-
|
|
483
|
+
ext.setPrefs({ selectedTool: null })
|
|
313
484
|
execForm.value = {}
|
|
314
485
|
execResult.value = null
|
|
315
486
|
execError.value = null
|
|
@@ -396,14 +567,14 @@ const ToolSelector = {
|
|
|
396
567
|
<div class="flex items-center gap-2">
|
|
397
568
|
<button @click="$ctx.setPrefs({ onlyTools: null })"
|
|
398
569
|
class="px-3 py-1 rounded-md text-xs font-medium border transition-colors select-none"
|
|
399
|
-
:class="
|
|
570
|
+
:class="prefs.onlyTools == null
|
|
400
571
|
? 'bg-green-100 dark:bg-green-900/40 text-green-800 dark:text-green-300 border-green-300 dark:border-green-800'
|
|
401
572
|
: 'cursor-pointer bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'">
|
|
402
573
|
All Tools
|
|
403
574
|
</button>
|
|
404
575
|
<button @click="$ctx.setPrefs({ onlyTools:[] })"
|
|
405
576
|
class="px-3 py-1 rounded-md text-xs font-medium border transition-colors select-none"
|
|
406
|
-
:class="
|
|
577
|
+
:class="prefs.onlyTools?.length === 0
|
|
407
578
|
? 'bg-fuchsia-100 dark:bg-fuchsia-900/40 text-fuchsia-800 dark:text-fuchsia-300 border-fuchsia-200 dark:border-fuchsia-800'
|
|
408
579
|
: 'cursor-pointer bg-white dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'">
|
|
409
580
|
No Tools
|
|
@@ -456,10 +627,10 @@ const ToolSelector = {
|
|
|
456
627
|
<div v-show="!isCollapsed(group.name)" class="p-3 bg-white dark:bg-gray-900 border-t border-gray-100 dark:border-gray-800">
|
|
457
628
|
<div class="flex flex-wrap gap-2">
|
|
458
629
|
<button v-for="tool in group.tools" :key="tool.function.name" type="button"
|
|
459
|
-
@click="toggleTool(tool.function.name)"
|
|
630
|
+
@click="$tools.toggleTool(tool.function.name)"
|
|
460
631
|
:title="tool.function.description"
|
|
461
632
|
class="px-2.5 py-1 rounded-full text-xs font-medium border transition-colors select-none text-left truncate max-w-[200px]"
|
|
462
|
-
:class="
|
|
633
|
+
:class="$tools.isToolEnabled(tool.function.name)
|
|
463
634
|
? 'bg-blue-100 dark:bg-blue-900/40 text-blue-800 dark:text-blue-300 border-blue-200 dark:border-blue-800'
|
|
464
635
|
: 'bg-gray-50 dark:bg-gray-800 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600'">
|
|
465
636
|
{{ tool.function.name }}
|
|
@@ -474,10 +645,10 @@ const ToolSelector = {
|
|
|
474
645
|
const ctx = inject('ctx')
|
|
475
646
|
const collapsedState = ref({})
|
|
476
647
|
|
|
477
|
-
const
|
|
648
|
+
const prefs = computed(() => ctx.prefs)
|
|
478
649
|
|
|
479
650
|
const toolGroups = computed(() => {
|
|
480
|
-
const defs = availableTools.value
|
|
651
|
+
const defs = ctx.tools.availableTools.value
|
|
481
652
|
const groups = ctx.state.tool.groups || {}
|
|
482
653
|
|
|
483
654
|
const definedGroups = []
|
|
@@ -500,33 +671,6 @@ const ToolSelector = {
|
|
|
500
671
|
return definedGroups
|
|
501
672
|
})
|
|
502
673
|
|
|
503
|
-
function isToolActive(name) {
|
|
504
|
-
const only = ctx.prefs.onlyTools
|
|
505
|
-
if (only == null) return true
|
|
506
|
-
if (Array.isArray(only)) {
|
|
507
|
-
return only.includes(name)
|
|
508
|
-
}
|
|
509
|
-
return false
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
function toggleTool(name) {
|
|
513
|
-
let onlyTools = ctx.prefs.onlyTools
|
|
514
|
-
|
|
515
|
-
// If currently 'All', clicking a tool means we enter custom mode with all OTHER tools selected (deselecting clicked)
|
|
516
|
-
if (onlyTools == null) {
|
|
517
|
-
onlyTools = availableTools.value.map(t => t.function.name).filter(t => t !== name)
|
|
518
|
-
} else {
|
|
519
|
-
// Currently Custom or None
|
|
520
|
-
if (onlyTools.includes(name)) {
|
|
521
|
-
onlyTools = onlyTools.filter(t => t !== name)
|
|
522
|
-
} else {
|
|
523
|
-
onlyTools = [...onlyTools, name]
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
ctx.setPrefs({ onlyTools })
|
|
528
|
-
}
|
|
529
|
-
|
|
530
674
|
function toggleCollapse(groupName) {
|
|
531
675
|
const key = groupName || '_other_'
|
|
532
676
|
collapsedState.value[key] = !collapsedState.value[key]
|
|
@@ -539,19 +683,19 @@ const ToolSelector = {
|
|
|
539
683
|
|
|
540
684
|
function setGroupTools(group, enable) {
|
|
541
685
|
const groupToolNames = group.tools.map(t => t.function.name)
|
|
542
|
-
let onlyTools =
|
|
686
|
+
let onlyTools = prefs.value.onlyTools
|
|
543
687
|
|
|
544
688
|
if (enable) {
|
|
545
689
|
if (onlyTools == null) return
|
|
546
690
|
const newSet = new Set(onlyTools)
|
|
547
691
|
groupToolNames.forEach(n => newSet.add(n))
|
|
548
692
|
onlyTools = Array.from(newSet)
|
|
549
|
-
if (onlyTools.length === availableTools.value.length) {
|
|
693
|
+
if (onlyTools.length === ctx.tools.availableTools.value.length) {
|
|
550
694
|
onlyTools = null
|
|
551
695
|
}
|
|
552
696
|
} else {
|
|
553
697
|
if (onlyTools == null) {
|
|
554
|
-
onlyTools = availableTools.value
|
|
698
|
+
onlyTools = ctx.tools.availableTools.value
|
|
555
699
|
.map(t => t.function.name)
|
|
556
700
|
.filter(n => !groupToolNames.includes(n))
|
|
557
701
|
} else {
|
|
@@ -563,16 +707,14 @@ const ToolSelector = {
|
|
|
563
707
|
}
|
|
564
708
|
|
|
565
709
|
function getActiveCount(group) {
|
|
566
|
-
const onlyTools =
|
|
710
|
+
const onlyTools = prefs.value.onlyTools
|
|
567
711
|
if (onlyTools == null) return group.tools.length
|
|
568
712
|
return group.tools.filter(t => onlyTools.includes(t.function.name)).length
|
|
569
713
|
}
|
|
570
714
|
|
|
571
715
|
return {
|
|
572
|
-
|
|
716
|
+
prefs,
|
|
573
717
|
toolGroups,
|
|
574
|
-
isToolActive,
|
|
575
|
-
toggleTool,
|
|
576
718
|
toggleCollapse,
|
|
577
719
|
isCollapsed,
|
|
578
720
|
setGroupTools,
|
|
@@ -581,19 +723,6 @@ const ToolSelector = {
|
|
|
581
723
|
}
|
|
582
724
|
}
|
|
583
725
|
|
|
584
|
-
function useTools(ctx) {
|
|
585
|
-
const toolPageHeaders = {}
|
|
586
|
-
|
|
587
|
-
function setToolPageHeaders(components) {
|
|
588
|
-
Object.assign(toolPageHeaders, components)
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
return {
|
|
592
|
-
toolPageHeaders,
|
|
593
|
-
setToolPageHeaders,
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
|
|
597
726
|
export default {
|
|
598
727
|
order: 10 - 100,
|
|
599
728
|
|
|
@@ -603,6 +732,8 @@ export default {
|
|
|
603
732
|
ctx.components({
|
|
604
733
|
Tools,
|
|
605
734
|
ToolSelector,
|
|
735
|
+
ToolResult,
|
|
736
|
+
JsonInput,
|
|
606
737
|
})
|
|
607
738
|
|
|
608
739
|
ctx.setGlobals({
|
|
@@ -644,7 +775,7 @@ export default {
|
|
|
644
775
|
}
|
|
645
776
|
})
|
|
646
777
|
|
|
647
|
-
ctx.chatRequestFilters.push(({ request, thread }) => {
|
|
778
|
+
ctx.chatRequestFilters.push(({ request, thread, context }) => {
|
|
648
779
|
// Tool Preferences
|
|
649
780
|
const prefs = ctx.prefs
|
|
650
781
|
if (prefs.onlyTools != null) {
|