mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
feat(compaction): support SubAPI native remote compaction
- support sub-api/openai-responses through the public Responses endpoint - preserve explicit Authorization and support header-only authentication - retain Codex JWT requirements and native compaction failure fallback - restore SubAPI checkpoints and preserve portable model-switching summaries - add provider, authentication and checkpoint lifecycle regression tests - document compatibility requirements and the Sub2API protocol reference
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import {
|
||||
buildCodexHeaders,
|
||||
isJsonObject,
|
||||
isOpenAICodexModel,
|
||||
mergeFeatureHeader,
|
||||
resolveCodexResponsesUrl,
|
||||
type Model,
|
||||
} from "./native-compaction.js";
|
||||
|
||||
export function isNativeCompactionModel(model: unknown): model is Model<any> {
|
||||
return isOpenAICodexModel(model) || (
|
||||
isJsonObject(model) && model.provider === "sub-api" && model.api === "openai-responses"
|
||||
);
|
||||
}
|
||||
|
||||
export function buildNativeCompactionTransport(params: {
|
||||
model: Pick<Model<any>, "provider" | "api" | "baseUrl">;
|
||||
apiKey?: string;
|
||||
headers?: Record<string, string>;
|
||||
sessionId: string;
|
||||
}): { url: string; headers: Headers } {
|
||||
if (isOpenAICodexModel(params.model)) {
|
||||
if (!params.apiKey) throw new Error("Codex native compaction authentication requires an API key.");
|
||||
return {
|
||||
url: resolveCodexResponsesUrl(params.model.baseUrl),
|
||||
headers: buildCodexHeaders({ ...params, apiKey: params.apiKey }),
|
||||
};
|
||||
}
|
||||
if (!isNativeCompactionModel(params.model)) {
|
||||
throw new Error("Native compaction is not supported for this provider and API.");
|
||||
}
|
||||
if (!params.model.baseUrl?.trim()) {
|
||||
throw new Error("SubAPI native compaction requires an explicit baseUrl.");
|
||||
}
|
||||
let url: URL;
|
||||
try {
|
||||
url = new URL(params.model.baseUrl.trim());
|
||||
} catch {
|
||||
throw new Error("SubAPI native compaction requires a valid HTTP(S) baseUrl.");
|
||||
}
|
||||
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password || url.hash) {
|
||||
throw new Error("SubAPI native compaction requires an HTTP(S) baseUrl without credentials or a fragment.");
|
||||
}
|
||||
const path = url.pathname.replace(/\/+$/, "");
|
||||
url.pathname = path.endsWith("/responses") ? path : `${path}/responses`;
|
||||
|
||||
// Sub2API accepts native compaction v2 through its public Responses endpoint.
|
||||
// The gateway owns upstream Codex credentials; honor the client's resolved authentication.
|
||||
const headers = new Headers(params.headers);
|
||||
if (!headers.get("authorization")?.trim()) {
|
||||
if (params.apiKey?.trim()) {
|
||||
headers.set("authorization", `Bearer ${params.apiKey}`);
|
||||
} else if (!headers.get("cf-aig-authorization")?.trim()) {
|
||||
throw new Error("SubAPI native compaction authentication requires an API key or a non-empty Authorization or cf-aig-authorization header.");
|
||||
}
|
||||
}
|
||||
headers.set("content-type", "application/json");
|
||||
headers.set("accept", "text/event-stream");
|
||||
headers.set("OpenAI-Beta", "responses=experimental");
|
||||
headers.set("originator", "pi");
|
||||
headers.set("user-agent", "pi-compaction");
|
||||
headers.set("session-id", params.sessionId);
|
||||
headers.set("x-client-request-id", params.sessionId);
|
||||
headers.set("x-codex-beta-features", mergeFeatureHeader(headers.get("x-codex-beta-features")));
|
||||
return { url: url.toString(), headers };
|
||||
}
|
||||
Reference in New Issue
Block a user