mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-14 19:22:32 +03:00
* feat(providers): add Conol web support
* fix(conol): preserve sessions and image turns
* fix(conol): pin session model and effort via /model endpoint
Conol ignores agentModel/agentEffort on POST /api/sessions, so every
session silently ran on the downgraded account default (the create
response reports modelDowngraded: true / effectiveModel).
Sessions are now created empty and configured out-of-band against
POST /api/sessions/{id}/model before the first turn is submitted, in the
order the web client uses: modelPreset, then agentModel, then agentEffort.
The ordering is load-bearing because the model call resets agentEffort to
null server-side.
Effort now defaults to xhigh when the caller does not pin one via the
-<effort> model suffix, and is clamped onto the ladder each model actually
advertises, so xhigh degrades to high on claude-sonnet-5 and is skipped
entirely for models without an effort ladder such as openrouter/fusion.
Model and effort are also dropped from the session binding key so switching
models re-pins the existing session instead of stranding it and losing the
conversation history. Re-pinning only happens on an actual change, so
steady-state follow-ups cost no extra round trips.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
export const CONOL_SESSION_COOKIE_NAME = "__Secure-better-auth.session_token";
|
|
|
|
export interface ConolCredentialInput {
|
|
apiKey?: unknown;
|
|
accessToken?: unknown;
|
|
cookie?: unknown;
|
|
providerSpecificData?: unknown;
|
|
}
|
|
|
|
function readString(value: unknown): string {
|
|
return typeof value === "string" ? value.trim() : "";
|
|
}
|
|
|
|
function readStoredValue(value: unknown): string {
|
|
const raw = readString(value);
|
|
if (!raw || !raw.startsWith("{")) return raw;
|
|
try {
|
|
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
|
return (
|
|
readString(parsed.cookie) ||
|
|
readString(parsed[CONOL_SESSION_COOKIE_NAME]) ||
|
|
readString(parsed.sessionToken)
|
|
);
|
|
} catch {
|
|
return raw;
|
|
}
|
|
}
|
|
|
|
export function normalizeConolCookie(rawValue: string): string {
|
|
const raw = readStoredValue(rawValue).replace(/^Cookie:\s*/i, "").trim();
|
|
if (!raw) return "";
|
|
if (raw.includes("=")) return raw;
|
|
return `${CONOL_SESSION_COOKIE_NAME}=${raw}`;
|
|
}
|
|
|
|
export function resolveConolCredentials(credentials?: ConolCredentialInput): {
|
|
cookie: string;
|
|
} {
|
|
const providerData =
|
|
credentials?.providerSpecificData &&
|
|
typeof credentials.providerSpecificData === "object" &&
|
|
!Array.isArray(credentials.providerSpecificData)
|
|
? (credentials.providerSpecificData as Record<string, unknown>)
|
|
: {};
|
|
|
|
const raw =
|
|
readStoredValue(providerData.cookie) ||
|
|
readStoredValue(providerData[CONOL_SESSION_COOKIE_NAME]) ||
|
|
readStoredValue(providerData.sessionToken) ||
|
|
readStoredValue(credentials?.cookie) ||
|
|
readStoredValue(credentials?.apiKey) ||
|
|
readStoredValue(credentials?.accessToken);
|
|
|
|
return { cookie: normalizeConolCookie(raw) };
|
|
}
|