mirror of
https://github.com/moeru-ai/airi.git
synced 2026-08-14 08:52:42 +00:00
fix(plugin-sdk): trim negotiated compatibility versions (#1305)
--- Co-authored-by-agent: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -449,6 +449,46 @@ describe('for PluginHost', () => {
|
||||
]))
|
||||
})
|
||||
|
||||
it('should trim whitespace in supported compatibility versions before negotiating', async () => {
|
||||
const host = new PluginHost({
|
||||
runtime: 'electron',
|
||||
transport: { kind: 'in-memory' },
|
||||
protocolVersion: 'v2',
|
||||
apiVersion: 'v2',
|
||||
supportedProtocolVersions: [' v1 '],
|
||||
supportedApiVersions: [' v1 '],
|
||||
})
|
||||
reportPluginCapability(host, {
|
||||
key: providersCapability,
|
||||
state: 'ready',
|
||||
metadata: { source: 'test' },
|
||||
})
|
||||
|
||||
const session = await host.load(testManifest, { cwd: '' })
|
||||
const compatibilityEvents: Array<{ body?: Record<string, unknown> }> = []
|
||||
session.channels.host.on(moduleCompatibilityResult, (payload) => {
|
||||
compatibilityEvents.push(payload as unknown as { body?: Record<string, unknown> })
|
||||
})
|
||||
|
||||
const initialized = await host.init(session.id, {
|
||||
compatibility: {
|
||||
supportedProtocolVersions: [' v1 '],
|
||||
supportedApiVersions: [' v1 '],
|
||||
},
|
||||
})
|
||||
|
||||
expect(initialized.phase).toBe('ready')
|
||||
expect(compatibilityEvents).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
body: expect.objectContaining({
|
||||
protocolVersion: 'v1',
|
||||
apiVersion: 'v1',
|
||||
mode: 'downgraded',
|
||||
}),
|
||||
}),
|
||||
]))
|
||||
})
|
||||
|
||||
it('should reject initialization when compatibility has no overlap', async () => {
|
||||
const host = new PluginHost({
|
||||
runtime: 'electron',
|
||||
|
||||
@@ -350,35 +350,45 @@ function createModuleIdentity(name: string, index: number): ModuleIdentity {
|
||||
}
|
||||
|
||||
// TODO: Maybe support more complex version formats.
|
||||
function normalizeVersionList(versions: string[]) {
|
||||
return [...new Set(versions.map(version => version.trim()).filter(Boolean))]
|
||||
}
|
||||
|
||||
function resolveSupportedVersions(preferredVersion: string, supportedVersions?: string[]) {
|
||||
const list = [preferredVersion, ...(supportedVersions ?? [])]
|
||||
return [...new Set(list)]
|
||||
return normalizeVersionList([preferredVersion, ...(supportedVersions ?? [])])
|
||||
}
|
||||
|
||||
function resolveNegotiatedVersion(preferredVersion: string, hostSupportedVersions: string[], peerSupportedVersions?: string[]) {
|
||||
if (!peerSupportedVersions?.length) {
|
||||
if (hostSupportedVersions.includes(preferredVersion)) {
|
||||
const normalizedPreferredVersion = preferredVersion.trim()
|
||||
const normalizedHostSupportedVersions = normalizeVersionList(hostSupportedVersions)
|
||||
const normalizedPeerSupportedVersions = peerSupportedVersions && peerSupportedVersions.length > 0
|
||||
? normalizeVersionList(peerSupportedVersions)
|
||||
: undefined
|
||||
|
||||
if (!normalizedPeerSupportedVersions?.length) {
|
||||
if (normalizedHostSupportedVersions.includes(normalizedPreferredVersion)) {
|
||||
return {
|
||||
acceptedVersion: preferredVersion,
|
||||
acceptedVersion: normalizedPreferredVersion,
|
||||
exact: true,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
exact: false,
|
||||
reason: `Host does not support preferred version "${preferredVersion}".`,
|
||||
reason: `Host does not support preferred version "${normalizedPreferredVersion}".`,
|
||||
}
|
||||
}
|
||||
|
||||
if (peerSupportedVersions.includes(preferredVersion) && hostSupportedVersions.includes(preferredVersion)) {
|
||||
if (normalizedPeerSupportedVersions.includes(normalizedPreferredVersion)
|
||||
&& normalizedHostSupportedVersions.includes(normalizedPreferredVersion)) {
|
||||
return {
|
||||
acceptedVersion: preferredVersion,
|
||||
acceptedVersion: normalizedPreferredVersion,
|
||||
exact: true,
|
||||
}
|
||||
}
|
||||
|
||||
for (const version of hostSupportedVersions) {
|
||||
if (peerSupportedVersions.includes(version)) {
|
||||
for (const version of normalizedHostSupportedVersions) {
|
||||
if (normalizedPeerSupportedVersions.includes(version)) {
|
||||
return {
|
||||
acceptedVersion: version,
|
||||
exact: false,
|
||||
@@ -388,7 +398,7 @@ function resolveNegotiatedVersion(preferredVersion: string, hostSupportedVersion
|
||||
|
||||
return {
|
||||
exact: false,
|
||||
reason: `No overlapping supported versions. host=[${hostSupportedVersions.join(', ')}]; peer=[${peerSupportedVersions.join(', ')}].`,
|
||||
reason: `No overlapping supported versions. host=[${normalizedHostSupportedVersions.join(', ')}]; peer=[${normalizedPeerSupportedVersions.join(', ')}].`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user