-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(providers): Z.ai Start Plan provider (OAuth login, in-process traceless captcha, gateway wire) #4647
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
feat(providers): Z.ai Start Plan provider (OAuth login, in-process traceless captcha, gateway wire) #4647
Changes from all commits
1c1fe0b
8ed2fc6
f533d19
eefbb72
9008be6
d23a140
85ffa5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {"touched":[],"bashMutation":true,"reportedFindings":[],"findingEvents":[],"baseline":null,"stateErrors":[],"omittedReportedFindings":0,"omittedFindingEvents":0,"processing":null,"updatedAt":"2026-09-14T17:03:07.070Z"} |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -157,6 +157,8 @@ export interface LogEntry extends LogFailureAttribution { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| timestamp: number; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| model: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| provider: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** Pool/account label the turn was served under (e.g. "p83fa8d", "main"); absent when unattributed. */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| accountLogLabel?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| surface?: LogSurface; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| conversationId?: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -575,6 +577,34 @@ export default function Logs({ apiBase }: { apiBase: string }) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| controller.abort(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [apiBase]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Opaque log labels → human attribution (email masked per proxy privacy settings). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Fetched once per page: labels are stable for the lifetime of an account. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [accountLabels, setAccountLabels] = useState<Map<string, string>>(new Map()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const controller = new AbortController(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let cancelled = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch(`${apiBase}/api/account-labels`, { signal: controller.signal }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .then(res => (res.ok ? res.json() as Promise<{ labels?: Array<{ label?: unknown; email?: unknown; plan?: unknown }> }> : null)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+583
to
+587
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a connected-client dashboard initially has no shared GUI session, opening the Logs page starts this request before pairing and receives a 401. Completing the pairing changes the session state but not Useful? React with 👍 / 👎. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .then(body => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (cancelled || !body?.labels) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const map = new Map<string, string>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const row of body.labels) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (typeof row.label !== "string" || !row.label) continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const parts: string[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (typeof row.email === "string" && row.email) parts.push(row.email); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (typeof row.plan === "string" && row.plan) parts.push(row.plan); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (parts.length > 0) map.set(row.label, parts.join(" · ")); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!cancelled) setAccountLabels(map); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .catch(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Older proxy without the endpoint: fall back to the raw opaque labels. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cancelled = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| controller.abort(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [apiBase]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+583
to
+607
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Add cleanup to the This effect creates an Two consequences follow:
The effect at lines 426-447 in this same file ( 🔧 Proposed fix to add cleanup and a stale-response guard const [accountLabels, setAccountLabels] = useState<Map<string, string>>(new Map());
useEffect(() => {
const controller = new AbortController();
+ let cancelled = false;
fetch(`${apiBase}/api/account-labels`, { signal: controller.signal })
.then(res => (res.ok ? res.json() as Promise<{ labels?: Array<{ label?: unknown; email?: unknown; plan?: unknown }> }> : null))
.then(body => {
- if (!body?.labels) return;
+ if (cancelled || !body?.labels) return;
const map = new Map<string, string>();
for (const row of body.labels) {
if (typeof row.label !== "string" || !row.label) continue;
const parts: string[] = [];
if (typeof row.email === "string" && row.email) parts.push(row.email);
if (typeof row.plan === "string" && row.plan) parts.push(row.plan);
if (parts.length > 0) map.set(row.label, parts.join(" · "));
}
setAccountLabels(map);
})
.catch(() => {
// Older proxy without the endpoint: fall back to the raw opaque labels.
});
+ return () => {
+ cancelled = true;
+ controller.abort();
+ };
}, [apiBase]);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // The hash is the source of truth for the active tab (#logs vs #logs/debug), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // so refresh/bookmark/back-forward keep the tab choice. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [tab, setTab] = useState<LogsTab>(readTabFromHash); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -884,6 +914,7 @@ export default function Logs({ apiBase }: { apiBase: string }) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-model" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-effort" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-provider" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-account" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-status" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-request" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <col className="logs-col-duration" /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -897,6 +928,7 @@ export default function Logs({ apiBase }: { apiBase: string }) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th className="log-col-model">{t("logs.col.model")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th>{t("logs.col.effort")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th>{t("logs.col.provider")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th>{t("logs.col.account")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th>{t("logs.col.status")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th>{t("logs.col.request")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <th className="num log-col-duration">{t("logs.col.duration")}</th> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -905,7 +937,7 @@ export default function Logs({ apiBase }: { apiBase: string }) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <tbody> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {paddingTop > 0 && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td colSpan={10} className="logs-virtual-spacer" style={{ height: paddingTop }} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td colSpan={11} className="logs-virtual-spacer" style={{ height: paddingTop }} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {virtualRows.map(virtualRow => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -991,6 +1023,7 @@ export default function Logs({ apiBase }: { apiBase: string }) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 9% column and painted over the provider cell. */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td className="mono log-reasoning-cell" title={reasoningWire}>{effortLabel(log)}</td> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td className="muted">{formatProviderDisplayName(log.provider, t)}</td> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td className="muted mono" title={log.accountLogLabel}>{accountLabels.get(log.accountLogLabel ?? "") ?? log.accountLogLabel ?? "—"}</td> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="log-status-cell"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <span className="mono font-semibold" style={{ color: statusColor(log.status) }}>{log.status}</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -1011,7 +1044,7 @@ export default function Logs({ apiBase }: { apiBase: string }) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {paddingBottom > 0 && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td colSpan={10} className="logs-virtual-spacer" style={{ height: paddingBottom }} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <td colSpan={11} className="logs-virtual-spacer" style={{ height: paddingBottom }} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </tr> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </tbody> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -80,6 +80,7 @@ | |
| "@modelcontextprotocol/sdk": "^1.30.0", | ||
| "@napi-rs/keyring": "1.3.0", | ||
| "bun": "1.4.0", | ||
| "happy-dom": "^20.11.6", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🤖 get_repo_knowledge executed:
Length of output: 17317 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- tracked manifest and likely security docs ---'
git ls-files | rg '(^|/)(package\.json|package-lock\.json|npm-shrinkwrap\.json|yarn\.lock|pnpm-lock\.yaml|SECURITY(\.md)?|CONTRIBUTING(\.md)?|README(\.md)?|.*security.*|.*dependency.*)$' | head -120
printf '%s\n' '--- package manifest ---'
cat -n package.json | sed -n '1,130p'
printf '%s\n' '--- happy-dom references ---'
rg -n -S --glob '!node_modules/**' --glob '!dist/**' 'happy-dom|captcha.?solver|captchaSolver|captcha' . | head -240
printf '%s\n' '--- dependency-related review evidence terms ---'
rg -n -i --glob '!node_modules/**' --glob '!dist/**' 'security review|dependency review|provenance|advisory|lifecycle.?script|isolation' . | head -240
printf '%s\n' '--- concise diff summary ---'
git diff --stat
git diff -- package.json | sed -n '1,180p'Repository: lidge-jun/opencodex Length of output: 50375 🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- exact dependency-review guidance ---'
sed -n '350,380p' AGENTS.md
sed -n '55,78p' MAINTAINERS.md
printf '%s\n' '--- package state and lockfile binding ---'
git status --short
git diff --stat
sed -n '1,28p' bun.lock
sed -n '205,225p' bun.lock
printf '%s\n' '--- narrow happy-dom review-evidence search ---'
rg -n -i --glob '!bun.lock' --glob '!gui/bun.lock' --glob '!gui/**' --glob '!node_modules/**' 'happy-dom|dependency security review|dependency review' AGENTS.md MAINTAINERS.md CONTRIBUTING.md SECURITY.md devlog docs scripts src package.json .github 2>/dev/null | head -220
printf '%s\n' '--- solver and host imports/entry flow ---'
sed -n '1,45p' src/adapters/zcode-start-plan/captcha-solver.ts
sed -n '1,125p' src/adapters/zcode-start-plan/captcha-host.ts
sed -n '175,215p' src/adapters/zcode-start-plan.tsRepository: lidge-jun/opencodex Length of output: 27652 Record the required security review for
🤖 Prompt for AI AgentsSource: Coding guidelines |
||
| "zod": "4.4.3" | ||
| }, | ||
| "devDependencies": { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 1500
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 6196
🏁 Script executed:
Repository: lidge-jun/opencodex
Length of output: 41357
Add
logs.col.accountto the Vietnamese catalog.vi.tsis a supported locale. Its catalog does not definelogs.col.account, while the other named locale files do. Add a Vietnamese translation togui/src/i18n/vi.ts.🤖 Prompt for AI Agents
Source: Learnings