feat: add verified desktop ChatGPT subscription connection

This commit is contained in:
amosblomqvist
2026-10-24 12:17:08 +03:00
parent ae2fad56c4
commit 0fc6d4ab94
53 changed files with 2557 additions and 140 deletions
+51
View File
@@ -674,6 +674,57 @@ export function endsInDismissal(messages: readonly LhMessage[]): boolean {
return last !== undefined && isDismissedResult(last);
}
export type RequestCause = "foreground" | "background";
export type ReconstructedCause = RequestCause | "ambiguous";
export type NativeInputCause = "learner" | "automatic" | "neutral" | "unrecognizable";
/** Native causes only: flattened user roles, IDs' prefixes and prose confer no permission. */
export function nativeInputCause(message: AgentMessage, history: readonly AgentMessage[]): NativeInputCause {
if (message.role === "user") return "learner";
if (message.role === "system" || message.role === "assistant") return "neutral";
if (message.role === "custom") {
if (["probe-handoff", "subagent-steer", "subagent-abort"].includes(message.customType)) return "automatic";
if (["practice-thinking", "practice-next"].includes(message.customType)) return "learner";
return ["graph-context", "plan-block", "problem-dismissed", "compaction"].includes(message.customType) ? "neutral" : "unrecognizable";
}
if (message.role === "toolResult") {
if (!(QUESTION_TOOLS as readonly string[]).includes(message.toolName) || message.isError || message.details == null || (message.details as { dismissed?: boolean }).dismissed) return "neutral";
const details = message.details as Partial<QuestionAnswerData>;
if (!["quiz", "ask", "explain"].includes(details.kind ?? "") || typeof details.questionText !== "string" || typeof details.dontKnow !== "boolean" || !Array.isArray(details.answers) || typeof details.answeredAt !== "string") return "unrecognizable";
const calls = history.flatMap((m) => m.role === "assistant" ? m.content.filter((b) => b.type === "toolCall" && b.id === message.toolCallId) : []);
return calls.length === 1 && calls[0]?.type === "toolCall" && calls[0].name === message.toolName ? "learner" : "unrecognizable";
}
return "unrecognizable";
}
/** Full persisted native record, including pre-compaction causes. Never guessed foreground. */
export function reconstructRequestCause(messages: readonly LhMessage[]): ReconstructedCause {
let inherited: ReconstructedCause = "ambiguous";
let triggers: NativeInputCause[] = [];
const seen = new Map<string, string>();
const history: AgentMessage[] = [];
const resolve = (): ReconstructedCause => {
if (triggers.includes("unrecognizable")) return "ambiguous";
const lastLearner = triggers.lastIndexOf("learner"), lastAutomatic = triggers.lastIndexOf("automatic");
if (lastLearner < 0 && lastAutomatic < 0) return inherited;
if (lastAutomatic < 0) return "foreground";
if (lastLearner < lastAutomatic) return "background";
return "ambiguous";
};
for (const message of messages) {
const cause = nativeInputCause(message, history);
const id = (message as { id?: string }).id;
if (id) {
const value = JSON.stringify(message);
if (seen.has(id)) { if (seen.get(id) !== value) triggers.push("unrecognizable"); continue; }
seen.set(id, value);
} else if (cause !== "neutral") triggers.push("unrecognizable");
if (message.role === "assistant" && !(message.provider === "synthetic" && message.api === "faux" && message.model === "synthetic-conclude" && message.content.some((b) => b.type === "toolCall" && b.name === "conclude" && b.arguments?.outcome === "dismissed"))) {
inherited = resolve(); triggers = [];
} else if (cause !== "neutral") triggers.push(cause);
history.push(message);
}
return resolve();
}
export function needsContinuation(messages: readonly LhMessage[]): boolean {
const last = messages[messages.length - 1];
if (!last || (last as { role?: string }).role !== "toolResult") return false;