fix: align workspace diagnostic contracts

This commit is contained in:
2026-08-04 00:37:57 +02:00
parent f6494fd8ef
commit 565e93a456
12 changed files with 346 additions and 42 deletions
+19 -9
View File
@@ -131,7 +131,9 @@ export interface WriteDiagnosticRecordRequest {
credentialFile?: string;
tlsCaFile?: string;
baseUrl?: string;
diagnostic?: RestDiagnosticRequest;
diagnostic?: RestDiagnosticRequest & {
response: { operation: string };
};
}
export interface DirectProtocolFactory {
@@ -145,7 +147,7 @@ export interface DatabaseDiagnosticClient {
export interface DatabaseDiagnosticClientFactory {
connect(request: {
host: string; port: number; database: string; user: string; credentialFile: string; tlsCaFile: string; signal: AbortSignal;
host: string; port: number; database: string; user: string; credentialFile: string; tlsCaFile?: string; signal: AbortSignal;
}): Promise<DatabaseDiagnosticClient>;
}
@@ -296,11 +298,13 @@ export function createConcreteDiagnosticAdapters(
},
};
const databaseClient = dependencies.databaseClient ?? {
async connect(request: { host: string; port: number; database: string; user: string; credentialFile: string; tlsCaFile: string; signal: AbortSignal }) {
async connect(request: { host: string; port: number; database: string; user: string; credentialFile: string; tlsCaFile?: string; signal: AbortSignal }) {
const client = new Client({
host: request.host, port: request.port, database: request.database, user: request.user,
password: (await readFile(request.credentialFile, "utf8")).trim(),
ssl: { ca: await readFile(request.tlsCaFile, "utf8"), rejectUnauthorized: true },
ssl: request.tlsCaFile
? { ca: await readFile(request.tlsCaFile, "utf8"), rejectUnauthorized: true }
: { rejectUnauthorized: true },
connectionTimeoutMillis: 5_000,
});
const abort = () => { void client.end(); };
@@ -317,7 +321,7 @@ export function createConcreteDiagnosticAdapters(
};
const directProtocol = dependencies.directProtocol ?? {
async probe(request: ConnectorDiagnosticRequest): Promise<ConnectorDiagnosticResult> {
if (!request.host || !request.port || !request.user || !request.credentialFile || !request.tlsCaFile
if (!request.host || !request.port || !request.user || !request.credentialFile
|| !(await secretPresent(request.credentialFile))) {
throw new Error("direct probe failed");
}
@@ -388,7 +392,7 @@ export function createConcreteDiagnosticAdapters(
async inspectVector(request) {
if (request.transport === "pgvector_direct" || request.transport === "ssh_tunnel") {
const resource = request.resource;
if (!request.host || !request.port || !request.user || !request.credentialFile || !request.tlsCaFile
if (!request.host || !request.port || !request.user || !request.credentialFile
|| !resource?.database || !resource.schema || !(await secretPresent(request.credentialFile))) {
throw new Error("vector metadata adapter is unavailable");
}
@@ -454,7 +458,10 @@ export function createConcreteDiagnosticAdapters(
signal: request.signal,
redirect: "error",
});
if (!response.ok) throw new Error("vector write adapter is unavailable");
const payload = await response.json().catch(() => undefined) as Record<string, unknown> | undefined;
if (!response.ok || !payload || payload[request.diagnostic.response.operation] !== "create") {
throw new Error("vector write adapter is unavailable");
}
},
async removeDiagnosticRecord(request) {
if (!request.baseUrl || !request.diagnostic || request.tlsCaFile) throw new Error("vector write adapter is unavailable");
@@ -468,7 +475,10 @@ export function createConcreteDiagnosticAdapters(
signal: request.signal,
redirect: "error",
});
if (!response.ok) throw new Error("vector write adapter is unavailable");
const payload = await response.json().catch(() => undefined) as Record<string, unknown> | undefined;
if (!response.ok || !payload || payload[request.diagnostic.response.operation] !== "remove") {
throw new Error("vector write adapter is unavailable");
}
},
};
}
@@ -789,7 +799,7 @@ export function createWorkspaceDiagnoser(
&& bindings.vector.transport === "rest_api"
&& !diagnostics.some((diagnostic) => diagnostic.level === "error")
) {
const credentialFile = bindings.vector.values[bindingName(canonical, "VECTOR_WRITER", "API_KEY_FILE")];
const credentialFile = bindings.vectorWriter.values[bindingName(canonical, "VECTOR_WRITER", "API_KEY_FILE")];
if (!credentialFile) return { activatable: true, diagnostics };
const readerCredentialFile = bindings.vector.values[bindingName(canonical, "VECTOR", "API_KEY_FILE")];
if (readerCredentialFile && await sameSecretFile(credentialFile, readerCredentialFile)) {