feat(ai): added pi-native auth-gateway transport

- Added POST /v1/pi/stream endpoint that accepts canonical Context directly, skipping wire-format translation layers.
- Added client-side streamPiNative dispatch activated via Model.transport = "pi-native".
- Propagated transport field through model registry, provider overrides, and models.yml schema.
- Refactored deriveSessionId to accept explicit arguments instead of ParsedFormatRequest.
This commit is contained in:
can1357
2026-05-17 03:05:57 +02:00
parent dc3d39df9e
commit cb05764eac
11 changed files with 1285 additions and 12 deletions
@@ -333,8 +333,45 @@ function selectBestOfficialCandidate(candidates: readonly string[]): string | un
if (candidates.length === 0) {
return undefined;
}
const ranked = [...new Set(candidates)].sort(compareCandidatePreference);
return ranked[0];
const seen = new Set<string>();
let bestCandidate: string | undefined;
let bestPenalty = 0;
let bestLength = 0;
for (const candidate of candidates) {
if (seen.has(candidate)) {
continue;
}
seen.add(candidate);
const penalty = getCandidatePenalty(candidate);
const length = candidate.length;
if (bestCandidate === undefined) {
bestCandidate = candidate;
bestPenalty = penalty;
bestLength = length;
continue;
}
if (penalty < bestPenalty) {
bestCandidate = candidate;
bestPenalty = penalty;
bestLength = length;
continue;
}
if (penalty > bestPenalty) {
continue;
}
if (length < bestLength) {
bestCandidate = candidate;
bestLength = length;
continue;
}
if (length > bestLength) {
continue;
}
if (candidate.localeCompare(bestCandidate) < 0) {
bestCandidate = candidate;
}
}
return bestCandidate;
}
function getWrapperCanonicalCandidates(candidate: string): string[] {
@@ -242,13 +242,14 @@ export const ModelsConfigFile = new ConfigFile<ModelsConfig>("models", ModelsCon
},
);
/** Provider override config (baseUrl, headers, apiKey, compat) without custom models */
/** Provider override config (baseUrl, headers, apiKey, compat, transport) without custom models */
interface ProviderOverride {
baseUrl?: string;
headers?: Record<string, string>;
apiKey?: string;
authHeader?: boolean;
compat?: Model<Api>["compat"];
transport?: Model<Api>["transport"];
}
interface DiscoveryProviderConfig {
@@ -1085,14 +1086,15 @@ export class ModelRegistry {
const configuredProviders = new Set(Object.keys(value.providers ?? {}));
for (const [providerName, providerConfig] of providerEntries) {
// Always set overrides when baseUrl/headers/apiKey/authHeader/compat/disableStrictTools are present
// Always set overrides when baseUrl/headers/apiKey/authHeader/compat/disableStrictTools/transport are present
if (
providerConfig.baseUrl ||
providerConfig.headers ||
providerConfig.apiKey ||
providerConfig.authHeader !== undefined ||
providerConfig.compat ||
providerConfig.disableStrictTools
providerConfig.disableStrictTools ||
providerConfig.transport
) {
const disableStrictCompat = providerConfig.disableStrictTools ? { disableStrictTools: true } : undefined;
overrides.set(providerName, {
@@ -1101,6 +1103,7 @@ export class ModelRegistry {
apiKey: providerConfig.apiKey,
authHeader: providerConfig.authHeader,
compat: mergeCompat(providerConfig.compat, disableStrictCompat),
transport: providerConfig.transport,
});
}
@@ -1192,6 +1195,9 @@ export class ModelRegistry {
headers: providerOverride.headers
? { ...model.headers, ...providerOverride.headers }
: model.headers,
...(providerOverride.transport !== undefined
? { transport: providerOverride.transport }
: {}),
}
: model;
}),
@@ -1693,11 +1699,12 @@ export class ModelRegistry {
authHeader: override.authHeader ?? baseOverride?.authHeader,
headers: override.headers ? { ...(baseOverride?.headers ?? {}), ...override.headers } : baseOverride?.headers,
compat: override.compat ? mergeCompat(baseOverride?.compat, override.compat) : baseOverride?.compat,
transport: override.transport ?? baseOverride?.transport,
};
}
#applyProviderTransportOverride<T extends { baseUrl?: string; headers?: Record<string, string> }>(
entry: T,
override: Pick<ProviderOverride, "baseUrl" | "headers" | "authHeader" | "apiKey">,
override: Pick<ProviderOverride, "baseUrl" | "headers" | "authHeader" | "apiKey" | "transport">,
): T {
const headers = mergeAuthHeader(
override.headers ? { ...entry.headers, ...override.headers } : entry.headers,
@@ -1708,6 +1715,9 @@ export class ModelRegistry {
...entry,
baseUrl: override.baseUrl ?? entry.baseUrl,
headers,
// Preserve the model's existing transport when the override omits one;
// providers without a `transport` field keep the default per-API dispatch.
...(override.transport !== undefined ? { transport: override.transport } : {}),
};
}
#applyRuntimeProviderOverrides(models: Model<Api>[]): Model<Api>[] {
@@ -2182,12 +2192,19 @@ export class ModelRegistry {
return;
}
if (config.baseUrl || config.headers || config.apiKey || config.authHeader !== undefined) {
if (
config.baseUrl ||
config.headers ||
config.apiKey ||
config.authHeader !== undefined ||
config.transport !== undefined
) {
const transportOverride = {
baseUrl: config.baseUrl,
headers: config.headers,
apiKey: config.apiKey,
authHeader: config.authHeader,
transport: config.transport,
};
const nextRuntimeOverride = this.#mergeProviderOverride(
this.#runtimeProviderOverrides.get(providerName),
@@ -2235,6 +2252,8 @@ export interface ProviderConfigInput {
headers?: Record<string, string>;
compat?: Model<Api>["compat"];
authHeader?: boolean;
/** Streaming transport override — see {@link Model.transport}. */
transport?: Model<Api>["transport"];
oauth?: {
name: string;
login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials | string>;
@@ -151,6 +151,14 @@ const ProviderConfigSchema = z.object({
models: z.array(ModelDefinitionSchema).optional(),
modelOverrides: z.record(z.string(), ModelOverrideSchema).optional(),
disableStrictTools: z.boolean().optional(),
/**
* Streaming transport override. When set to `"pi-native"`, omp dispatches
* every model under this provider via the auth-gateway's
* `POST /v1/pi/stream` endpoint instead of the per-provider SDK. The
* provider's `baseUrl` must point at a compatible `omp auth-gateway`
* and `apiKey` must carry the gateway bearer.
*/
transport: z.literal("pi-native").optional(),
});
const EquivalenceConfigSchema = z.object({
@@ -121,6 +121,10 @@ export async function startCpuProfile(): Promise<ProfilerSession> {
session.connect();
await session.post("Profiler.enable");
// Default CDP interval is 1ms, which mis-attributes await-resumption samples
// to the line after `await` (one sparse sample inherits the entire wait). 100µs
// scatters samples enough to keep CPU vs. async-wait attribution honest.
await session.post("Profiler.setSamplingInterval", { interval: 100 });
await session.post("Profiler.start");
return {