mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-12 16:02:56 +00:00
fix: keep named resource types first and list only related names on search failure
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
03d2459932
commit
985c08f78e
@@ -49,6 +49,23 @@ describe('searchResourceTypes', () => {
|
||||
|
||||
expect(resourceTypes).toEqual([])
|
||||
expect(note).toContain('postgresql')
|
||||
expect(note).not.toContain('type_0')
|
||||
})
|
||||
|
||||
it('keeps every type the query names ahead of the other matches', async () => {
|
||||
vi.spyOn(ResourceService, 'queryResourceTypes').mockResolvedValue(
|
||||
['a', 'b', 'c', 'd', 'stripe'].map((name) => ({ name, score: 0.8 }))
|
||||
)
|
||||
vi.spyOn(ResourceService, 'listResourceTypeNames').mockResolvedValue([
|
||||
...syncedNames,
|
||||
'stripe',
|
||||
'github'
|
||||
])
|
||||
vi.spyOn(ResourceService, 'getResourceType').mockResolvedValue({ name: 'github', schema: {} })
|
||||
|
||||
const { resourceTypes } = await searchResourceTypes('stripe github', 'ws', 5)
|
||||
|
||||
expect(resourceTypes.map((rt) => rt.name)).toEqual(['stripe', 'github', 'a', 'b', 'c'])
|
||||
})
|
||||
|
||||
it('notes an instance that never synced with the hub', async () => {
|
||||
|
||||
@@ -93,30 +93,37 @@ export async function searchResourceTypes(
|
||||
])
|
||||
|
||||
const normalized = query.trim().toLowerCase()
|
||||
const candidates = new Set([
|
||||
normalized.replace(/[\s-]+/g, '_'),
|
||||
...normalized.split(/[^a-z0-9_]+/)
|
||||
])
|
||||
const exactNames = [...candidates].filter(
|
||||
(name) => names?.has(name) && !similar.some((rt) => rt.name === name)
|
||||
)
|
||||
const words = normalized.split(/[^a-z0-9_]+/).filter((word) => word.length > 0)
|
||||
const candidates = new Set([normalized.replace(/[\s-]+/g, '_'), ...words])
|
||||
const exact = await Promise.all(
|
||||
exactNames
|
||||
[...candidates]
|
||||
.filter((name) => names?.has(name))
|
||||
.slice(0, limit)
|
||||
.map((name) =>
|
||||
ResourceService.getResourceType({ workspace, path: name }).catch(() => undefined)
|
||||
.map(
|
||||
(name) =>
|
||||
similar.find((rt) => rt.name === name) ??
|
||||
ResourceService.getResourceType({ workspace, path: name }).catch(() => undefined)
|
||||
)
|
||||
)
|
||||
const named = exact.flatMap((rt) => (rt ? [{ name: rt.name, schema: rt.schema }] : []))
|
||||
const resourceTypes = [
|
||||
...exact.flatMap((rt) => (rt ? [{ name: rt.name, schema: rt.schema }] : [])),
|
||||
...similar
|
||||
...named,
|
||||
...similar.filter((rt) => !named.some((n) => n.name === rt.name))
|
||||
].slice(0, limit)
|
||||
|
||||
// Without the similarity search, an empty result says nothing about whether a type exists,
|
||||
// so the model gets the names to search again with rather than concluding there is none.
|
||||
// so the model gets the names close to its query rather than concluding there is none.
|
||||
const related =
|
||||
similarityFailed && names
|
||||
? [...names]
|
||||
.filter((name) =>
|
||||
words.some((word) => word.length >= 3 && (name.includes(word) || word.includes(name)))
|
||||
)
|
||||
.slice(0, 30)
|
||||
: []
|
||||
const notes = [
|
||||
similarityFailed && names
|
||||
? `The similarity search is unavailable on this instance, so only a type named in the query can be found. Search again with one of the instance's resource types: ${[...names].join(', ')}.`
|
||||
? `The similarity search is unavailable on this instance, so only a type named in the query can be found. ${related.length > 0 ? `Resource types whose names share a word with the query: ${related.join(', ')}.` : "Search again with the service's name."}`
|
||||
: undefined,
|
||||
names && names.size < UNSYNCED_RESOURCE_TYPE_COUNT
|
||||
? `Only ${names.size} resource types exist on this instance, so it has most likely never synced with the Windmill Hub, which has types for most services. ${HUB_SYNC_INSTRUCTIONS}`
|
||||
|
||||
Reference in New Issue
Block a user