mirror of
https://github.com/langgenius/dify.git
synced 2026-09-07 10:23:54 +08:00
148 lines
3.9 KiB
TypeScript
148 lines
3.9 KiB
TypeScript
import type { ServerVersionResponse } from '@dify/contracts/api/openapi/types.gen'
|
|
import type { CompatVerdict } from './compat.js'
|
|
import type { Channel } from './info.js'
|
|
import type { ActiveContext } from '@/auth/hosts'
|
|
import { META_PROBE_TIMEOUT_MS, MetaClient } from '@/api/meta'
|
|
import { Registry } from '@/auth/hosts'
|
|
import { createHttpClient } from '@/http/client'
|
|
import { arch, platform } from '@/sys/index'
|
|
import { activeHostInfo, openAPIBase } from '@/util/host'
|
|
import { difyCompat, evaluateCompat } from './compat.js'
|
|
import { versionInfo } from './info.js'
|
|
|
|
export type ClientBlock = {
|
|
readonly version: string
|
|
readonly commit: string
|
|
readonly buildDate: string
|
|
readonly channel: Channel
|
|
readonly platform: string
|
|
readonly arch: string
|
|
}
|
|
|
|
export type ServerBlock = {
|
|
readonly endpoint: string
|
|
readonly reachable: boolean
|
|
readonly version?: string
|
|
readonly edition?: ServerVersionResponse['edition']
|
|
}
|
|
|
|
export type CompatBlock = CompatVerdict & {
|
|
readonly minDify: string
|
|
readonly maxDify: string
|
|
}
|
|
|
|
export type VersionReport = {
|
|
readonly client: ClientBlock
|
|
readonly server: ServerBlock
|
|
readonly compat: CompatBlock
|
|
}
|
|
|
|
// /openapi/v1/_version is intentionally unauthenticated, so the probe does not
|
|
// take a bearer. Same signature shape as the auto-nudge probe — easy to swap.
|
|
export type MetaProbe = (endpoint: string) => Promise<ServerVersionResponse>
|
|
|
|
export type RunVersionProbeOptions = {
|
|
readonly skipServer: boolean
|
|
readonly loadActive?: () => Promise<ActiveContext | undefined>
|
|
readonly probe?: MetaProbe
|
|
}
|
|
|
|
const defaultLoadActive = async (): Promise<ActiveContext | undefined> => {
|
|
return (await Registry.load()).resolveActive()
|
|
}
|
|
|
|
function buildDefaultProbe(insecure: boolean): MetaProbe {
|
|
return async (endpoint) => {
|
|
const http = createHttpClient({
|
|
baseURL: openAPIBase(endpoint),
|
|
timeoutMs: META_PROBE_TIMEOUT_MS,
|
|
retryAttempts: 0,
|
|
insecure,
|
|
})
|
|
return new MetaClient(http).serverVersion()
|
|
}
|
|
}
|
|
|
|
function buildClientBlock(): ClientBlock {
|
|
return {
|
|
version: versionInfo.version,
|
|
commit: versionInfo.commit,
|
|
buildDate: versionInfo.buildDate,
|
|
channel: versionInfo.channel,
|
|
platform: platform(),
|
|
arch: arch(),
|
|
}
|
|
}
|
|
|
|
function unreachableServer(endpoint: string): ServerBlock {
|
|
return { endpoint, reachable: false }
|
|
}
|
|
|
|
function compatBlock(verdict: CompatVerdict): CompatBlock {
|
|
return {
|
|
minDify: difyCompat.minDify,
|
|
maxDify: difyCompat.maxDify,
|
|
status: verdict.status,
|
|
detail: verdict.detail,
|
|
}
|
|
}
|
|
|
|
export async function runVersionProbe(opts: RunVersionProbeOptions): Promise<VersionReport> {
|
|
const client = buildClientBlock()
|
|
|
|
if (opts.skipServer) {
|
|
return {
|
|
client,
|
|
server: { endpoint: '', reachable: false },
|
|
compat: compatBlock({ status: 'unknown', detail: 'server probe skipped' }),
|
|
}
|
|
}
|
|
|
|
const loadActive = opts.loadActive ?? defaultLoadActive
|
|
|
|
let active: ActiveContext | undefined
|
|
let loadFailed = false
|
|
try {
|
|
active = await loadActive()
|
|
} catch {
|
|
loadFailed = true
|
|
}
|
|
|
|
if (active === undefined || active.host === '') {
|
|
const detail = loadFailed ? 'hosts file unreadable' : 'no host configured'
|
|
return {
|
|
client,
|
|
server: { endpoint: '', reachable: false },
|
|
compat: compatBlock({ status: 'unknown', detail }),
|
|
}
|
|
}
|
|
|
|
const { host: endpoint, insecure } = activeHostInfo(active)
|
|
const probe = opts.probe ?? buildDefaultProbe(insecure)
|
|
|
|
let serverInfo: ServerVersionResponse | undefined
|
|
try {
|
|
serverInfo = await probe(endpoint)
|
|
} catch {
|
|
serverInfo = undefined
|
|
}
|
|
|
|
if (serverInfo === undefined)
|
|
return {
|
|
client,
|
|
server: unreachableServer(endpoint),
|
|
compat: compatBlock({ status: 'unknown', detail: 'server unreachable' }),
|
|
}
|
|
|
|
return {
|
|
client,
|
|
server: {
|
|
endpoint,
|
|
reachable: true,
|
|
version: serverInfo.version,
|
|
edition: serverInfo.edition,
|
|
},
|
|
compat: compatBlock(evaluateCompat(serverInfo.version)),
|
|
}
|
|
}
|