dsh-codex-subscription 3.0.0-beta.3 → 3.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +13 -2
- package/README.md +13 -2
- package/lib/client.js +955 -216
- package/lib/index.js +2043 -224
- package/package.json +9 -2
package/lib/client.js
CHANGED
|
@@ -1075,6 +1075,8 @@ window.__ModuleLoader__.load({
|
|
|
1075
1075
|
"account/select",
|
|
1076
1076
|
"account/remove",
|
|
1077
1077
|
"usage",
|
|
1078
|
+
"usage/history",
|
|
1079
|
+
"usage/profile",
|
|
1078
1080
|
"diagnostics",
|
|
1079
1081
|
"preferences/status",
|
|
1080
1082
|
"preferences/models",
|
|
@@ -1091,6 +1093,8 @@ window.__ModuleLoader__.load({
|
|
|
1091
1093
|
"remote/enable",
|
|
1092
1094
|
"remote/disable",
|
|
1093
1095
|
"remote/pair",
|
|
1096
|
+
"remote/clients",
|
|
1097
|
+
"remote/revoke",
|
|
1094
1098
|
"reset-credit/inspect",
|
|
1095
1099
|
"reset-credit/prepare",
|
|
1096
1100
|
"reset-credit/consume",
|
|
@@ -5676,6 +5680,24 @@ window.__ModuleLoader__.load({
|
|
|
5676
5680
|
inputImageDetail_low: "低",
|
|
5677
5681
|
inputImageDetail_high: "高",
|
|
5678
5682
|
inputImageDetail_original: "原图",
|
|
5683
|
+
connectors: "ChatGPT 连接器",
|
|
5684
|
+
connectorsHint: "让 DSH 里的任何模型使用你在 ChatGPT 网页里已连接的应用(GitHub、Gmail、Google 云端硬盘、日历等)。只读:模型只能读取;允许写入:发邮件、改文件等写操作每次都要你批准。应用返回的内容来自第三方,模型不会照其中的指令行事。需先在 ChatGPT 里连接应用。",
|
|
5685
|
+
connectors_off: "关闭",
|
|
5686
|
+
connectors_read: "只读",
|
|
5687
|
+
connectors_ask: "允许写入(每次审批)",
|
|
5688
|
+
reasoningSummary: "推理摘要",
|
|
5689
|
+
reasoningSummaryHint: "让模型在会话的“思考”部分给出推理摘要。自动由模型决定;简洁更短;详细更完整;关闭则不要摘要。",
|
|
5690
|
+
retryPolicy: "请求重试",
|
|
5691
|
+
retryPolicyHint: "请求因网络或服务端错误失败时的自动重试次数。默认沿用 DSH 的标准重试;无限会一直重试直到成功或手动停止。",
|
|
5692
|
+
retryPolicy_default: "默认",
|
|
5693
|
+
retryPolicy_off: "不重试",
|
|
5694
|
+
retryPolicy_10: "10 次",
|
|
5695
|
+
retryPolicy_20: "20 次",
|
|
5696
|
+
retryPolicy_unlimited: "无限",
|
|
5697
|
+
reasoningSummary_auto: "自动",
|
|
5698
|
+
reasoningSummary_concise: "简洁",
|
|
5699
|
+
reasoningSummary_detailed: "详细",
|
|
5700
|
+
reasoningSummary_none: "关闭",
|
|
5679
5701
|
subagentBackendTitle: "独立子任务",
|
|
5680
5702
|
subagentBackend_dsh: "DSH",
|
|
5681
5703
|
subagentBackend_codex: "Codex",
|
|
@@ -5688,6 +5710,11 @@ window.__ModuleLoader__.load({
|
|
|
5688
5710
|
remoteConnecting: "正在连接",
|
|
5689
5711
|
remoteError: "连接失败,会自动重试",
|
|
5690
5712
|
remoteStopped: "已停止",
|
|
5713
|
+
remotePaired: "已配对的手机",
|
|
5714
|
+
remoteNoPhones: "还没有手机配对。",
|
|
5715
|
+
remoteRevoke: "移除",
|
|
5716
|
+
remoteLastSeen: "最近 {date}",
|
|
5717
|
+
remotePhoneUnknown: "未命名手机",
|
|
5691
5718
|
remotePhones: "{count} 个手机连接",
|
|
5692
5719
|
remotePair: "显示配对码",
|
|
5693
5720
|
remotePairAgain: "重新生成配对码",
|
|
@@ -5697,7 +5724,7 @@ window.__ModuleLoader__.load({
|
|
|
5697
5724
|
remoteQrLabel: "配对二维码",
|
|
5698
5725
|
remoteExpires: "约 {minutes} 分钟内有效",
|
|
5699
5726
|
remoteExpired: "配对码已过期,请重新生成。",
|
|
5700
|
-
remoteLimits: "手机上可以查看和继续 DSH
|
|
5727
|
+
remoteLimits: "手机上可以查看和继续 DSH 里的对话、新建对话、发图片、切换模型、选择权限并审批,也能查看改动。手机不能在电脑上执行其他命令。",
|
|
5701
5728
|
reviewModelTitle: "Auto review 审查模型",
|
|
5702
5729
|
reviewModel_session: "当前模型",
|
|
5703
5730
|
reviewModel_official: "Codex 官方审查模型",
|
|
@@ -5965,6 +5992,10 @@ window.__ModuleLoader__.load({
|
|
|
5965
5992
|
deviceHint: "在登录页输入此设备代码:",
|
|
5966
5993
|
waiting: "正在等待登录完成…",
|
|
5967
5994
|
failed: "登录失败,请重试。",
|
|
5995
|
+
failed_account_claim: "登录已授权,但这个账号的令牌里没有 ChatGPT 账号 ID(常见于只用手机号注册的账号)。请改用邮箱账号登录,或先在 ChatGPT 里为账号绑定邮箱后重试。",
|
|
5996
|
+
failed_network: "登录时网络连接失败。请检查网络或代理后重试。",
|
|
5997
|
+
failed_token_exchange: "授权已完成,但换取令牌失败。请重试;反复出现时请检查网络或代理。",
|
|
5998
|
+
failed_callback: "没有收到浏览器的授权回调。请重试,或改用设备码登录。",
|
|
5968
5999
|
accountRetry: "重试",
|
|
5969
6000
|
accountRetrying: "正在重试账户状态…",
|
|
5970
6001
|
accountCredentialUnavailable: "登录凭据暂时不可用。请重试;不会删除已保存的登录信息。",
|
|
@@ -5997,6 +6028,45 @@ window.__ModuleLoader__.load({
|
|
|
5997
6028
|
refresh: "刷新",
|
|
5998
6029
|
refreshing: "刷新中…",
|
|
5999
6030
|
noUsage: "登录后可读取 ChatGPT 返回的额度窗口。",
|
|
6031
|
+
overviewTitle: "使用概览",
|
|
6032
|
+
overviewLoading: "正在读取使用统计…",
|
|
6033
|
+
overviewUnavailable: "当前账户没有提供使用统计。",
|
|
6034
|
+
overviewHeatmap: "最近半年每天的 token 用量",
|
|
6035
|
+
overviewNoUse: "没有使用",
|
|
6036
|
+
overviewTokens: "{value} token",
|
|
6037
|
+
overviewDays: "{value} 天",
|
|
6038
|
+
overviewLifetime: "累计 token",
|
|
6039
|
+
overviewPeak: "单日最高",
|
|
6040
|
+
overviewStreak: "连续使用",
|
|
6041
|
+
overviewLongestStreak: "最长连续",
|
|
6042
|
+
overviewThreads: "会话总数",
|
|
6043
|
+
overviewEffort: "最常用推理档",
|
|
6044
|
+
overviewFast: "快速模式占比",
|
|
6045
|
+
overviewLongestTurn: "最长单轮",
|
|
6046
|
+
settingsRestartRequired: "设置已保存,但运行中的 DSH 没有应用它(宿主无法热更新这项设置)。请重启 DSH 后生效。",
|
|
6047
|
+
historyTitle: "额度去向(每周)",
|
|
6048
|
+
historyLoading: "正在读取用量历史…",
|
|
6049
|
+
historyUnavailable: "当前账户没有提供用量历史。",
|
|
6050
|
+
historyEmpty: "还没有已统计完成的额度周期。官方统计有延迟,过一两天再看。",
|
|
6051
|
+
historyPeriods: "额度周期",
|
|
6052
|
+
historyUsed: "这个周期已用 {value}% 的周额度",
|
|
6053
|
+
historyPartial: "(统计尚未完成)",
|
|
6054
|
+
historyApproximate: "数据来自官方用量报告,是近似值,可能有一两天延迟。",
|
|
6055
|
+
historyBy_model: "按模型",
|
|
6056
|
+
historyBy_surface: "按入口",
|
|
6057
|
+
historyBy_thread_source: "按来源",
|
|
6058
|
+
historyBy_turn_trigger: "按触发方式",
|
|
6059
|
+
historyDesktopApp: "桌面应用",
|
|
6060
|
+
historyCli: "命令行",
|
|
6061
|
+
historyIde: "IDE 扩展",
|
|
6062
|
+
historyWeb: "网页",
|
|
6063
|
+
historyMobile: "手机",
|
|
6064
|
+
historyUser: "你的对话",
|
|
6065
|
+
historySubagent: "子任务",
|
|
6066
|
+
historyMemory: "记忆整理",
|
|
6067
|
+
historyReview: "审查",
|
|
6068
|
+
historyComposer: "输入框发送",
|
|
6069
|
+
historyAutomation: "自动任务",
|
|
6000
6070
|
usageLoading: "正在读取额度…",
|
|
6001
6071
|
usageEmpty: "当前账户没有返回可显示的额度窗口。请稍后刷新;这不代表额度为零。",
|
|
6002
6072
|
usageUpdated: "更新于 {value}",
|
|
@@ -6126,6 +6196,8 @@ window.__ModuleLoader__.load({
|
|
|
6126
6196
|
effortLabel: "推理等级",
|
|
6127
6197
|
providerDefault: "默认",
|
|
6128
6198
|
selectModel: "选择模型",
|
|
6199
|
+
modelSearch: "搜索模型",
|
|
6200
|
+
modelNoMatch: "没有匹配的模型。",
|
|
6129
6201
|
modelsLoading: "正在读取模型…",
|
|
6130
6202
|
modelsEmpty: "没有可用模型;请先登录,并确认网络可用。",
|
|
6131
6203
|
modelsHidden: "所有模型都已从列表中隐藏;可在设置中重新显示。",
|
|
@@ -6281,6 +6353,24 @@ window.__ModuleLoader__.load({
|
|
|
6281
6353
|
inputImageDetail_low: "Low",
|
|
6282
6354
|
inputImageDetail_high: "High",
|
|
6283
6355
|
inputImageDetail_original: "Original",
|
|
6356
|
+
connectors: "ChatGPT connectors",
|
|
6357
|
+
connectorsHint: "Lets any model in DSH use the apps you have connected in ChatGPT (GitHub, Gmail, Google Drive, Calendar and more). Read-only: models can only read. Allow writes: anything that changes data, such as sending mail or editing files, asks for your approval every time. What apps return is third-party content and models do not follow instructions inside it. Connect the apps in ChatGPT first.",
|
|
6358
|
+
connectors_off: "Off",
|
|
6359
|
+
connectors_read: "Read-only",
|
|
6360
|
+
connectors_ask: "Allow writes (ask each time)",
|
|
6361
|
+
reasoningSummary: "Reasoning summary",
|
|
6362
|
+
reasoningSummaryHint: "Shows a summary of the reasoning in the Thinking section of the conversation. Auto lets the model decide; concise is shorter; detailed is fuller; off asks for none.",
|
|
6363
|
+
retryPolicy: "Request retries",
|
|
6364
|
+
retryPolicyHint: "How many times a request is retried after a network or server error. Default keeps the standard DSH retries; Unlimited keeps retrying until it succeeds or you stop it.",
|
|
6365
|
+
retryPolicy_default: "Default",
|
|
6366
|
+
retryPolicy_off: "No retries",
|
|
6367
|
+
retryPolicy_10: "10",
|
|
6368
|
+
retryPolicy_20: "20",
|
|
6369
|
+
retryPolicy_unlimited: "Unlimited",
|
|
6370
|
+
reasoningSummary_auto: "Auto",
|
|
6371
|
+
reasoningSummary_concise: "Concise",
|
|
6372
|
+
reasoningSummary_detailed: "Detailed",
|
|
6373
|
+
reasoningSummary_none: "Off",
|
|
6284
6374
|
subagentBackendTitle: "Independent subtasks",
|
|
6285
6375
|
subagentBackend_dsh: "DSH",
|
|
6286
6376
|
subagentBackend_codex: "Codex",
|
|
@@ -6293,6 +6383,11 @@ window.__ModuleLoader__.load({
|
|
|
6293
6383
|
remoteConnecting: "Connecting",
|
|
6294
6384
|
remoteError: "Connection failed, retrying",
|
|
6295
6385
|
remoteStopped: "Stopped",
|
|
6386
|
+
remotePaired: "Paired phones",
|
|
6387
|
+
remoteNoPhones: "No phone is paired yet.",
|
|
6388
|
+
remoteRevoke: "Remove",
|
|
6389
|
+
remoteLastSeen: "last seen {date}",
|
|
6390
|
+
remotePhoneUnknown: "Unnamed phone",
|
|
6296
6391
|
remotePhones: "{count} phone(s) connected",
|
|
6297
6392
|
remotePair: "Show pairing code",
|
|
6298
6393
|
remotePairAgain: "New pairing code",
|
|
@@ -6302,7 +6397,7 @@ window.__ModuleLoader__.load({
|
|
|
6302
6397
|
remoteQrLabel: "Pairing QR code",
|
|
6303
6398
|
remoteExpires: "Valid for about {minutes} minute(s)",
|
|
6304
6399
|
remoteExpired: "The pairing code expired. Create a new one.",
|
|
6305
|
-
remoteLimits: "From the phone you can follow and continue DSH conversations, start new ones, switch models, choose permissions and
|
|
6400
|
+
remoteLimits: "From the phone you can follow and continue DSH conversations, start new ones, send photos, switch models, choose permissions, approve actions and view changes. The phone cannot run other commands on the computer.",
|
|
6306
6401
|
reviewModelTitle: "Auto review model",
|
|
6307
6402
|
reviewModel_session: "Current model",
|
|
6308
6403
|
reviewModel_official: "Codex reviewer",
|
|
@@ -6570,6 +6665,10 @@ window.__ModuleLoader__.load({
|
|
|
6570
6665
|
deviceHint: "Enter this device code on the sign-in page:",
|
|
6571
6666
|
waiting: "Waiting for sign-in to finish…",
|
|
6572
6667
|
failed: "Sign-in failed. Try again.",
|
|
6668
|
+
failed_account_claim: "Sign-in was authorized, but the token of this account has no ChatGPT account ID (common for accounts created with only a phone number). Sign in with an email account, or add an email to the account in ChatGPT first, then try again.",
|
|
6669
|
+
failed_network: "The network connection failed during sign-in. Check the network or proxy and try again.",
|
|
6670
|
+
failed_token_exchange: "Authorization finished, but exchanging it for a token failed. Try again; if it keeps happening, check the network or proxy.",
|
|
6671
|
+
failed_callback: "The browser did not send the authorization back. Try again, or use device code sign-in.",
|
|
6573
6672
|
accountRetry: "Retry",
|
|
6574
6673
|
accountRetrying: "Retrying account status…",
|
|
6575
6674
|
accountCredentialUnavailable: "The saved sign-in credentials are temporarily unavailable. Retry; saved sign-in information will not be deleted.",
|
|
@@ -6602,6 +6701,45 @@ window.__ModuleLoader__.load({
|
|
|
6602
6701
|
refresh: "Refresh",
|
|
6603
6702
|
refreshing: "Refreshing…",
|
|
6604
6703
|
noUsage: "Sign in to read quota windows reported by ChatGPT.",
|
|
6704
|
+
overviewTitle: "Usage overview",
|
|
6705
|
+
overviewLoading: "Reading usage statistics…",
|
|
6706
|
+
overviewUnavailable: "This account does not provide usage statistics.",
|
|
6707
|
+
overviewHeatmap: "Daily token use over the last half year",
|
|
6708
|
+
overviewNoUse: "no use",
|
|
6709
|
+
overviewTokens: "{value} tokens",
|
|
6710
|
+
overviewDays: "{value} days",
|
|
6711
|
+
overviewLifetime: "Lifetime tokens",
|
|
6712
|
+
overviewPeak: "Busiest day",
|
|
6713
|
+
overviewStreak: "Current streak",
|
|
6714
|
+
overviewLongestStreak: "Longest streak",
|
|
6715
|
+
overviewThreads: "Conversations",
|
|
6716
|
+
overviewEffort: "Most used reasoning",
|
|
6717
|
+
overviewFast: "Fast mode share",
|
|
6718
|
+
overviewLongestTurn: "Longest turn",
|
|
6719
|
+
settingsRestartRequired: "The setting was saved, but the running DSH did not apply it (the host cannot update it live). Restart DSH to apply it.",
|
|
6720
|
+
historyTitle: "Where the allowance went (weekly)",
|
|
6721
|
+
historyLoading: "Reading usage history…",
|
|
6722
|
+
historyUnavailable: "This account does not provide a usage history.",
|
|
6723
|
+
historyEmpty: "No allowance period has been counted yet. The official report lags; check again in a day or two.",
|
|
6724
|
+
historyPeriods: "Allowance periods",
|
|
6725
|
+
historyUsed: "{value}% of this period's weekly allowance used",
|
|
6726
|
+
historyPartial: "(still being counted)",
|
|
6727
|
+
historyApproximate: "From the official usage report; values are approximate and may lag by a day or two.",
|
|
6728
|
+
historyBy_model: "By model",
|
|
6729
|
+
historyBy_surface: "By surface",
|
|
6730
|
+
historyBy_thread_source: "By source",
|
|
6731
|
+
historyBy_turn_trigger: "By trigger",
|
|
6732
|
+
historyDesktopApp: "Desktop app",
|
|
6733
|
+
historyCli: "CLI",
|
|
6734
|
+
historyIde: "IDE extension",
|
|
6735
|
+
historyWeb: "Web",
|
|
6736
|
+
historyMobile: "Mobile",
|
|
6737
|
+
historyUser: "Your chats",
|
|
6738
|
+
historySubagent: "Subtasks",
|
|
6739
|
+
historyMemory: "Memory upkeep",
|
|
6740
|
+
historyReview: "Review",
|
|
6741
|
+
historyComposer: "Composer",
|
|
6742
|
+
historyAutomation: "Automations",
|
|
6605
6743
|
usageLoading: "Reading quota…",
|
|
6606
6744
|
usageEmpty: "This account returned no displayable quota windows. Refresh later; this does not mean zero quota.",
|
|
6607
6745
|
usageUpdated: "Updated {value}",
|
|
@@ -6731,6 +6869,8 @@ window.__ModuleLoader__.load({
|
|
|
6731
6869
|
effortLabel: "Effort",
|
|
6732
6870
|
providerDefault: "Default",
|
|
6733
6871
|
selectModel: "Select model",
|
|
6872
|
+
modelSearch: "Search models",
|
|
6873
|
+
modelNoMatch: "No matching models.",
|
|
6734
6874
|
modelsLoading: "Loading models…",
|
|
6735
6875
|
modelsEmpty: "No models available. Sign in and make sure the network is reachable.",
|
|
6736
6876
|
modelsHidden: "All models are hidden from this list. Show one in settings.",
|
|
@@ -6878,6 +7018,28 @@ window.__ModuleLoader__.load({
|
|
|
6878
7018
|
.codexSubscriptionRefresh{flex:0 0 auto;min-width:72px;width:max-content;white-space:nowrap!important;word-break:keep-all!important;overflow-wrap:normal!important;writing-mode:horizontal-tb!important}
|
|
6879
7019
|
.codexSubscriptionRefresh *{white-space:nowrap!important;word-break:keep-all!important;writing-mode:horizontal-tb!important}
|
|
6880
7020
|
.codexSubscriptionEmpty{padding:18px;border:1px dashed var(--dsw-alias-border-l3);border-radius:10px;text-align:center;font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary)}
|
|
7021
|
+
.codexSubscriptionHistory{margin-top:10px;border-top:1px solid var(--dsw-alias-border-l3);padding-top:8px}
|
|
7022
|
+
.codexSubscriptionHistory>summary{cursor:pointer;font-size:13px;font-weight:500;color:var(--dsw-alias-label-secondary)}
|
|
7023
|
+
.codexSubscriptionHistoryPeriods{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0}
|
|
7024
|
+
.codexSubscriptionHistoryPeriods button{height:26px;padding:0 10px;border:1px solid var(--dsw-alias-border-l3);border-radius:13px;background:transparent;color:inherit;font-size:12px;cursor:pointer}
|
|
7025
|
+
.codexSubscriptionHistoryPeriods button[aria-pressed=true]{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-inverted)}
|
|
7026
|
+
.codexSubscriptionHistorySummary{margin:4px 0 8px;font-size:13px}
|
|
7027
|
+
.codexSubscriptionHistoryGroup{margin:8px 0}
|
|
7028
|
+
.codexSubscriptionHistoryGroup h4{margin:0 0 4px;font-size:12px;font-weight:500;color:var(--dsw-alias-label-tertiary)}
|
|
7029
|
+
.codexSubscriptionOverviewStats{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:8px;margin:10px 0}
|
|
7030
|
+
.codexSubscriptionOverviewStats div{padding:8px 10px;border-radius:10px;background:var(--dsw-alias-bg-layer-3,rgba(127,127,127,.08))}
|
|
7031
|
+
.codexSubscriptionOverviewStats dt{margin:0;font-size:11px;color:var(--dsw-alias-label-tertiary)}
|
|
7032
|
+
.codexSubscriptionOverviewStats dd{margin:2px 0 0;font-size:15px;font-weight:600}
|
|
7033
|
+
.codexSubscriptionHeatmap{display:block;width:100%;max-width:520px;margin:6px 0 4px}
|
|
7034
|
+
.codexSubscriptionHeatmap rect{fill:var(--dsw-alias-border-l3,rgba(127,127,127,.25))}
|
|
7035
|
+
.codexSubscriptionHeatmap rect[data-level="1"]{fill:#0a84ff;fill-opacity:.3}
|
|
7036
|
+
.codexSubscriptionHeatmap rect[data-level="2"]{fill:#0a84ff;fill-opacity:.5}
|
|
7037
|
+
.codexSubscriptionHeatmap rect[data-level="3"]{fill:#0a84ff;fill-opacity:.75}
|
|
7038
|
+
.codexSubscriptionHeatmap rect[data-level="4"]{fill:#0a84ff}
|
|
7039
|
+
.codexSubscriptionHistoryRow{display:grid;grid-template-columns:minmax(80px,32%) 1fr 52px;align-items:center;gap:8px;font-size:12px;line-height:20px}
|
|
7040
|
+
.codexSubscriptionHistoryKey{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
7041
|
+
.codexSubscriptionHistoryRow progress{width:100%;height:6px}
|
|
7042
|
+
.codexSubscriptionHistoryRow strong{text-align:right;font-weight:500}
|
|
6881
7043
|
.codexSubscriptionLimits{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:6px}
|
|
6882
7044
|
.codexSubscriptionLimit{min-width:0;border-radius:10px;padding:9px 12px;background:var(--dsw-alias-bg-module-platform);display:flex;flex-direction:column;gap:6px}
|
|
6883
7045
|
.codexSubscriptionLimitTop{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
|
|
@@ -6979,13 +7141,17 @@ window.__ModuleLoader__.load({
|
|
|
6979
7141
|
.codexModelSelectMenu,.codexModelSelectSubmenu{position:absolute;z-index:30;box-sizing:border-box;width:max-content;min-width:min(240px,calc(100vw - 32px));max-width:min(420px,calc(100vw - 32px));max-height:min(360px,calc(100vh - 96px));padding:4px;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary);overflow:hidden}
|
|
6980
7142
|
.codexModelSelectMenu{right:0;bottom:calc(100% + 8px)}
|
|
6981
7143
|
.codexModelSelectSubmenu{right:calc(100% + 8px);bottom:0;min-width:min(230px,calc(100vw - 32px))}
|
|
7144
|
+
/* Keep search outside the scroll viewport; let the model list fit the bounded menu. */
|
|
7145
|
+
.codexModelSelectModelMenu{display:flex;flex-direction:column}
|
|
6982
7146
|
.codexModelSelectCell{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;height:40px;box-sizing:border-box;padding:0 10px;border:0;border-radius:10px;background:transparent;color:inherit;font-size:14px;line-height:22px;text-align:left;cursor:pointer}
|
|
6983
7147
|
.codexModelSelectCell:hover,.codexModelSelectCell:focus-visible,.codexModelSelectCell[data-open=true]{background:var(--dsw-alias-interactive-bg-hover);outline:0}
|
|
6984
7148
|
.codexModelSelectCell:disabled{color:var(--dsw-alias-label-dimmed);cursor:default}
|
|
6985
7149
|
.codexModelSelectCellLabel{flex:none;white-space:nowrap}
|
|
6986
7150
|
.codexModelSelectCellValue{flex:auto;min-width:0;overflow:hidden;color:var(--dsw-alias-label-tertiary);text-align:right;text-overflow:ellipsis;white-space:nowrap}
|
|
6987
7151
|
.codexModelSelectCellChevron{flex:none;color:var(--dsw-alias-label-tertiary)}
|
|
6988
|
-
.
|
|
7152
|
+
.codexModelSelectSearch{display:block;flex-shrink:0;width:100%;box-sizing:border-box;height:32px;margin:0 0 4px;padding:0 10px;border:1px solid var(--dsw-alias-border-l3);border-radius:8px;outline:0;background:transparent;color:inherit;font:inherit;font-size:13px}
|
|
7153
|
+
.codexModelSelectSearch:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3)}
|
|
7154
|
+
.codexModelSelectGroups{flex:1 1 auto;min-height:0;overflow-y:auto}
|
|
6989
7155
|
.codexModelSelectGroup+.codexModelSelectGroup{margin-top:4px}
|
|
6990
7156
|
.codexModelSelectGroupTitle{position:sticky;top:0;z-index:1;padding:5px 8px 3px;background:var(--dsw-alias-bg-layer-2,#2c2c2e);color:var(--dsw-alias-label-tertiary);font-size:12px;font-weight:500;line-height:18px}
|
|
6991
7157
|
.codexModelSelectOption{display:flex;align-items:center;gap:8px;width:100%;min-width:100%;min-height:38px;box-sizing:border-box;padding:6px 8px;border:0;border-radius:10px;outline:0;background:transparent;color:inherit;text-align:left;cursor:pointer}
|
|
@@ -8407,6 +8573,29 @@ window.__ModuleLoader__.load({
|
|
|
8407
8573
|
const OUTPUT_VERBOSITY_MEDIUM = "medium";
|
|
8408
8574
|
const OUTPUT_VERBOSITY_HIGH = "high";
|
|
8409
8575
|
const DEFAULT_OUTPUT_VERBOSITY = OUTPUT_VERBOSITY_DEFAULT;
|
|
8576
|
+
const REASONING_SUMMARY_FIELD = "reasoningSummary";
|
|
8577
|
+
const REASONING_SUMMARIES = Object.freeze([
|
|
8578
|
+
"auto",
|
|
8579
|
+
"concise",
|
|
8580
|
+
"detailed",
|
|
8581
|
+
"none"
|
|
8582
|
+
]);
|
|
8583
|
+
const DEFAULT_REASONING_SUMMARY = "auto";
|
|
8584
|
+
const RETRY_POLICY_FIELD = "retryPolicy";
|
|
8585
|
+
const RETRY_POLICIES = Object.freeze([
|
|
8586
|
+
"default",
|
|
8587
|
+
"off",
|
|
8588
|
+
"10",
|
|
8589
|
+
"20",
|
|
8590
|
+
"unlimited"
|
|
8591
|
+
]);
|
|
8592
|
+
const DEFAULT_RETRY_POLICY = "default";
|
|
8593
|
+
const CONNECTORS_FIELD = "connectors";
|
|
8594
|
+
const CONNECTOR_MODES = Object.freeze([
|
|
8595
|
+
"off",
|
|
8596
|
+
"read",
|
|
8597
|
+
"ask"
|
|
8598
|
+
]);
|
|
8410
8599
|
const INPUT_IMAGE_DETAIL_FIELD = "inputImageDetail";
|
|
8411
8600
|
const INPUT_IMAGE_DETAILS = Object.freeze([
|
|
8412
8601
|
"low",
|
|
@@ -8466,6 +8655,9 @@ window.__ModuleLoader__.load({
|
|
|
8466
8655
|
"medium",
|
|
8467
8656
|
"high"
|
|
8468
8657
|
].includes(value) ? value : DEFAULT_OUTPUT_VERBOSITY;
|
|
8658
|
+
const normalizeReasoningSummary = (value) => REASONING_SUMMARIES.includes(value) ? value : DEFAULT_REASONING_SUMMARY;
|
|
8659
|
+
const normalizeRetryPolicy = (value) => RETRY_POLICIES.includes(value) ? value : DEFAULT_RETRY_POLICY;
|
|
8660
|
+
const normalizeConnectorMode = (value) => CONNECTOR_MODES.includes(value) ? value : "off";
|
|
8469
8661
|
const normalizeInputImageDetail = (value) => INPUT_IMAGE_DETAILS.includes(value) ? value : DEFAULT_INPUT_IMAGE_DETAIL;
|
|
8470
8662
|
const normalizeStreamIdleTimeoutMinutes = (value) => STREAM_IDLE_TIMEOUT_MINUTES.includes(value) ? value : 10;
|
|
8471
8663
|
const normalizeSpeedMode = (value) => [
|
|
@@ -8520,6 +8712,7 @@ window.__ModuleLoader__.load({
|
|
|
8520
8712
|
let disposed = false;
|
|
8521
8713
|
let subagentBackendAvailable = false;
|
|
8522
8714
|
let subagentRuntimeInstalled = false;
|
|
8715
|
+
let restartRequired = false;
|
|
8523
8716
|
const sameModels = (left, right) => left.length === right.length && left.every((model, index) => JSON.stringify(model) === JSON.stringify(right[index]));
|
|
8524
8717
|
const read = () => {
|
|
8525
8718
|
const current = fallback ?? { status: "unavailable" };
|
|
@@ -8544,6 +8737,9 @@ window.__ModuleLoader__.load({
|
|
|
8544
8737
|
speedMode: normalizeSpeedMode(value?.[SPEED_MODE_FIELD]),
|
|
8545
8738
|
outputVerbosity: normalizeOutputVerbosity(value?.[OUTPUT_VERBOSITY_FIELD]),
|
|
8546
8739
|
inputImageDetail: normalizeInputImageDetail(value?.[INPUT_IMAGE_DETAIL_FIELD]),
|
|
8740
|
+
reasoningSummary: normalizeReasoningSummary(value?.[REASONING_SUMMARY_FIELD]),
|
|
8741
|
+
retryPolicy: normalizeRetryPolicy(value?.[RETRY_POLICY_FIELD]),
|
|
8742
|
+
connectors: normalizeConnectorMode(value?.[CONNECTORS_FIELD]),
|
|
8547
8743
|
streamIdleTimeoutMinutes: normalizeStreamIdleTimeoutMinutes(value?.[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]),
|
|
8548
8744
|
contextMode: normalizeContextMode(value?.[CONTEXT_MODE_FIELD]),
|
|
8549
8745
|
customContextWindow: normalizeCustomContextWindow(value?.[CUSTOM_CONTEXT_WINDOW_FIELD]),
|
|
@@ -8562,6 +8758,7 @@ window.__ModuleLoader__.load({
|
|
|
8562
8758
|
modelError,
|
|
8563
8759
|
writable: !updating && current.status === "ready" && current.writable === true,
|
|
8564
8760
|
saving: updating,
|
|
8761
|
+
restartRequired,
|
|
8565
8762
|
error
|
|
8566
8763
|
});
|
|
8567
8764
|
};
|
|
@@ -8572,6 +8769,7 @@ window.__ModuleLoader__.load({
|
|
|
8572
8769
|
for (const listener of listeners) listener();
|
|
8573
8770
|
};
|
|
8574
8771
|
const acceptFallback = (value) => {
|
|
8772
|
+
if (value?.liveSynced === false) restartRequired = true;
|
|
8575
8773
|
subagentBackendAvailable = value?.subagentBackendAvailable === true;
|
|
8576
8774
|
subagentRuntimeInstalled = value?.subagentRuntimeInstalled === true;
|
|
8577
8775
|
if (!modelRefreshStarted) {
|
|
@@ -8598,6 +8796,9 @@ window.__ModuleLoader__.load({
|
|
|
8598
8796
|
[SPEED_MODE_FIELD]: normalizeSpeedMode(value?.[SPEED_MODE_FIELD]),
|
|
8599
8797
|
[OUTPUT_VERBOSITY_FIELD]: normalizeOutputVerbosity(value?.[OUTPUT_VERBOSITY_FIELD]),
|
|
8600
8798
|
[INPUT_IMAGE_DETAIL_FIELD]: normalizeInputImageDetail(value?.[INPUT_IMAGE_DETAIL_FIELD]),
|
|
8799
|
+
[REASONING_SUMMARY_FIELD]: normalizeReasoningSummary(value?.[REASONING_SUMMARY_FIELD]),
|
|
8800
|
+
[RETRY_POLICY_FIELD]: normalizeRetryPolicy(value?.[RETRY_POLICY_FIELD]),
|
|
8801
|
+
[CONNECTORS_FIELD]: normalizeConnectorMode(value?.[CONNECTORS_FIELD]),
|
|
8601
8802
|
[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]: normalizeStreamIdleTimeoutMinutes(value?.[STREAM_IDLE_TIMEOUT_MINUTES_FIELD]),
|
|
8602
8803
|
[CONTEXT_MODE_FIELD]: normalizeContextMode(value?.[CONTEXT_MODE_FIELD]),
|
|
8603
8804
|
[CUSTOM_CONTEXT_WINDOW_FIELD]: normalizeCustomContextWindow(value?.[CUSTOM_CONTEXT_WINDOW_FIELD]),
|
|
@@ -8986,7 +9187,6 @@ window.__ModuleLoader__.load({
|
|
|
8986
9187
|
const NS = "settings.codexSubscription";
|
|
8987
9188
|
const SUPPORT_ISSUE_URL = "https://github.com/WSL043/dsh-codex-subscription/issues/new?template=install-problem.yml";
|
|
8988
9189
|
const QUICK_QUOTA_REFRESH_EVENT = "dsh-codex-subscription:refresh-quick-quota";
|
|
8989
|
-
const QUICK_QUOTA_REFRESH_MS = 6e4;
|
|
8990
9190
|
const accountStatusErrorText = (error, t) => {
|
|
8991
9191
|
const key = {
|
|
8992
9192
|
"credential-unavailable": "accountCredentialUnavailable",
|
|
@@ -9004,7 +9204,7 @@ window.__ModuleLoader__.load({
|
|
|
9004
9204
|
if (local.length <= 2) return `${local.slice(0, 1)}••@${domain}`;
|
|
9005
9205
|
return `${local[0]}•••${local.at(-1)}@${domain}`;
|
|
9006
9206
|
};
|
|
9007
|
-
const hours = (seconds) => Math.round(seconds / 3600 * 10) / 10;
|
|
9207
|
+
const hours$1 = (seconds) => Math.round(seconds / 3600 * 10) / 10;
|
|
9008
9208
|
const percent = (value) => Number(value).toLocaleString(void 0, { maximumFractionDigits: 1 });
|
|
9009
9209
|
const isApproximateWindow = (seconds, expected) => seconds >= expected * .95 && seconds <= expected * 1.05;
|
|
9010
9210
|
const windowLabel = (seconds, t) => {
|
|
@@ -9013,7 +9213,7 @@ window.__ModuleLoader__.load({
|
|
|
9013
9213
|
if (isApproximateWindow(seconds, 604800)) return t("windowWeekly");
|
|
9014
9214
|
if (isApproximateWindow(seconds, 2592e3)) return t("windowMonthly");
|
|
9015
9215
|
if (isApproximateWindow(seconds, 31536e3)) return t("windowAnnual");
|
|
9016
|
-
return seconds >= 86400 && seconds % 86400 === 0 ? fill(t("windowDays"), { value: seconds / 86400 }) : fill(t("windowHours"), { value: hours(seconds) });
|
|
9216
|
+
return seconds >= 86400 && seconds % 86400 === 0 ? fill(t("windowDays"), { value: seconds / 86400 }) : fill(t("windowHours"), { value: hours$1(seconds) });
|
|
9017
9217
|
};
|
|
9018
9218
|
const validDate = (value) => {
|
|
9019
9219
|
const date = new Date(value);
|
|
@@ -9082,7 +9282,7 @@ window.__ModuleLoader__.load({
|
|
|
9082
9282
|
}
|
|
9083
9283
|
//#endregion
|
|
9084
9284
|
//#region src/version.js
|
|
9085
|
-
const PACKAGE_VERSION = "3.0.0-beta.
|
|
9285
|
+
const PACKAGE_VERSION = "3.0.0-beta.5";
|
|
9086
9286
|
//#endregion
|
|
9087
9287
|
//#region src/client-recovery.js
|
|
9088
9288
|
async function recoveryCall(rpc, endpoint, payload = {}, timeoutMs = 1e4) {
|
|
@@ -9110,6 +9310,21 @@ window.__ModuleLoader__.load({
|
|
|
9110
9310
|
};
|
|
9111
9311
|
}
|
|
9112
9312
|
//#endregion
|
|
9313
|
+
//#region src/quota-cadence.js
|
|
9314
|
+
/** Milliseconds until the next quota read, from the highest used percentage of the windows that matter. */
|
|
9315
|
+
function quotaRefreshMs(percent) {
|
|
9316
|
+
if (!Number.isFinite(percent)) return 6e4;
|
|
9317
|
+
if (percent >= 99) return 5e3;
|
|
9318
|
+
if (percent >= 90) return 15e3;
|
|
9319
|
+
if (percent >= 75) return 3e4;
|
|
9320
|
+
return 6e4;
|
|
9321
|
+
}
|
|
9322
|
+
/** Highest used percentage among windows (objects with usedPercent), or undefined when there are none. */
|
|
9323
|
+
function highestUsed(windows) {
|
|
9324
|
+
const values = (Array.isArray(windows) ? windows : []).map((window) => window?.usedPercent).filter(Number.isFinite);
|
|
9325
|
+
return values.length === 0 ? void 0 : Math.max(...values);
|
|
9326
|
+
}
|
|
9327
|
+
//#endregion
|
|
9113
9328
|
//#region src/client-quota.jsx
|
|
9114
9329
|
function useQuickQuota(rpc, enabled, model) {
|
|
9115
9330
|
const [quota, setQuota] = (0, react.useState)();
|
|
@@ -9121,6 +9336,8 @@ window.__ModuleLoader__.load({
|
|
|
9121
9336
|
setQuota(void 0);
|
|
9122
9337
|
let live = true;
|
|
9123
9338
|
let loading = false;
|
|
9339
|
+
let timer;
|
|
9340
|
+
let latest;
|
|
9124
9341
|
const load = async () => {
|
|
9125
9342
|
if (loading) return;
|
|
9126
9343
|
loading = true;
|
|
@@ -9132,25 +9349,31 @@ window.__ModuleLoader__.load({
|
|
|
9132
9349
|
return;
|
|
9133
9350
|
}
|
|
9134
9351
|
const usage = await recoveryCall(rpc, "usage", { force: false });
|
|
9135
|
-
|
|
9352
|
+
const windows = selectModelQuotaWindows(usage, model)?.map((window) => ({
|
|
9136
9353
|
...window,
|
|
9137
9354
|
fetchedAt: usage.fetchedAt
|
|
9138
|
-
}))
|
|
9355
|
+
}));
|
|
9356
|
+
latest = windows;
|
|
9357
|
+
if (live) setQuota(windows);
|
|
9139
9358
|
} catch {
|
|
9359
|
+
latest = void 0;
|
|
9140
9360
|
if (live) setQuota(void 0);
|
|
9141
9361
|
} finally {
|
|
9142
9362
|
loading = false;
|
|
9363
|
+
if (live) {
|
|
9364
|
+
window.clearTimeout(timer);
|
|
9365
|
+
timer = window.setTimeout(refresh, quotaRefreshMs(highestUsed(latest)));
|
|
9366
|
+
}
|
|
9143
9367
|
}
|
|
9144
9368
|
};
|
|
9145
9369
|
const refresh = () => {
|
|
9146
9370
|
load();
|
|
9147
9371
|
};
|
|
9148
9372
|
load();
|
|
9149
|
-
const timer = window.setInterval(refresh, QUICK_QUOTA_REFRESH_MS);
|
|
9150
9373
|
window.addEventListener(QUICK_QUOTA_REFRESH_EVENT, refresh);
|
|
9151
9374
|
return () => {
|
|
9152
9375
|
live = false;
|
|
9153
|
-
window.
|
|
9376
|
+
window.clearTimeout(timer);
|
|
9154
9377
|
window.removeEventListener(QUICK_QUOTA_REFRESH_EVENT, refresh);
|
|
9155
9378
|
};
|
|
9156
9379
|
}, [
|
|
@@ -9335,6 +9558,7 @@ window.__ModuleLoader__.load({
|
|
|
9335
9558
|
const preferenceSnapshot = usePreferenceSnapshot(preference);
|
|
9336
9559
|
const [open, setOpen] = (0, react.useState)(false);
|
|
9337
9560
|
const [pane, setPane] = (0, react.useState)("root");
|
|
9561
|
+
const [query, setQuery] = (0, react.useState)("");
|
|
9338
9562
|
const rootRef = (0, react.useRef)(null);
|
|
9339
9563
|
const triggerRef = (0, react.useRef)(null);
|
|
9340
9564
|
const id = (0, react.useId)();
|
|
@@ -9370,6 +9594,17 @@ window.__ModuleLoader__.load({
|
|
|
9370
9594
|
...effort.description === void 0 ? {} : { description: effort.description }
|
|
9371
9595
|
}))], [reasoning, t]);
|
|
9372
9596
|
const modelLabel = currentChoice?.model.name ?? t("selectModel");
|
|
9597
|
+
const searchable = visibleGroups.reduce((total, group) => total + group.models.length, 0) > 4;
|
|
9598
|
+
const needle = searchable ? query.trim().toLocaleLowerCase() : "";
|
|
9599
|
+
const shownGroups = needle === "" ? visibleGroups : visibleGroups.map((group) => ({
|
|
9600
|
+
...group,
|
|
9601
|
+
models: group.models.filter((model) => [
|
|
9602
|
+
model.name,
|
|
9603
|
+
model.id,
|
|
9604
|
+
model.description,
|
|
9605
|
+
group.name
|
|
9606
|
+
].some((text) => typeof text === "string" && text.toLocaleLowerCase().includes(needle)))
|
|
9607
|
+
})).filter((group) => group.models.length > 0);
|
|
9373
9608
|
const speedSupported = state.current?.provider === "openai-codex" && (preferenceSnapshot.fastModels?.includes(state.current?.model) ?? supportsCodexFastMode(state.current?.model));
|
|
9374
9609
|
const speedWritable = preferenceSnapshot.status === "ready" && preferenceSnapshot.writable === true;
|
|
9375
9610
|
const ultrafastSupported = state.current?.provider === "openai-codex" && (preferenceSnapshot.ultrafastModels ?? []).includes(state.current?.model);
|
|
@@ -9411,11 +9646,15 @@ window.__ModuleLoader__.load({
|
|
|
9411
9646
|
if (!rootRef.current?.contains(event.target)) {
|
|
9412
9647
|
setOpen(false);
|
|
9413
9648
|
setPane("root");
|
|
9649
|
+
setQuery("");
|
|
9414
9650
|
}
|
|
9415
9651
|
};
|
|
9416
9652
|
document.addEventListener("mousedown", closeOutside);
|
|
9417
9653
|
return () => document.removeEventListener("mousedown", closeOutside);
|
|
9418
9654
|
}, [open]);
|
|
9655
|
+
(0, react.useEffect)(() => {
|
|
9656
|
+
if (pane !== "model") setQuery("");
|
|
9657
|
+
}, [pane]);
|
|
9419
9658
|
(0, react.useEffect)(() => {
|
|
9420
9659
|
if (!speedSupported && pane === "speed") setPane("root");
|
|
9421
9660
|
if (!verbositySupported && pane === "verbosity") setPane("root");
|
|
@@ -9428,6 +9667,7 @@ window.__ModuleLoader__.load({
|
|
|
9428
9667
|
const close = (restoreFocus = false) => {
|
|
9429
9668
|
setOpen(false);
|
|
9430
9669
|
setPane("root");
|
|
9670
|
+
setQuery("");
|
|
9431
9671
|
if (restoreFocus) queueMicrotask(() => triggerRef.current?.focus());
|
|
9432
9672
|
};
|
|
9433
9673
|
const settleSelection = (accepted) => {
|
|
@@ -9503,7 +9743,7 @@ window.__ModuleLoader__.load({
|
|
|
9503
9743
|
});
|
|
9504
9744
|
let submenu = null;
|
|
9505
9745
|
if (pane === "model") submenu = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9506
|
-
className: "codexModelSelectSubmenu",
|
|
9746
|
+
className: "codexModelSelectSubmenu codexModelSelectModelMenu",
|
|
9507
9747
|
role: "menu",
|
|
9508
9748
|
"aria-label": t("modelLabel"),
|
|
9509
9749
|
children: [
|
|
@@ -9527,9 +9767,18 @@ window.__ModuleLoader__.load({
|
|
|
9527
9767
|
value: failure.message
|
|
9528
9768
|
})
|
|
9529
9769
|
}, failure.id)),
|
|
9770
|
+
searchable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
9771
|
+
className: "codexModelSelectSearch",
|
|
9772
|
+
type: "search",
|
|
9773
|
+
value: query,
|
|
9774
|
+
autoFocus: true,
|
|
9775
|
+
placeholder: t("modelSearch"),
|
|
9776
|
+
"aria-label": t("modelSearch"),
|
|
9777
|
+
onChange: (event) => setQuery(event.target.value)
|
|
9778
|
+
}) : null,
|
|
9530
9779
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9531
9780
|
className: "codexModelSelectGroups scrollable",
|
|
9532
|
-
children:
|
|
9781
|
+
children: shownGroups.map((group) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
9533
9782
|
className: "codexModelSelectGroup",
|
|
9534
9783
|
role: "group",
|
|
9535
9784
|
"aria-labelledby": `${id}-${group.id}`,
|
|
@@ -9560,6 +9809,10 @@ window.__ModuleLoader__.load({
|
|
|
9560
9809
|
state.status === "ready" && visibleGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9561
9810
|
className: "codexModelSelectEmpty",
|
|
9562
9811
|
children: t(choices.length === 0 ? "modelsEmpty" : "modelsHidden")
|
|
9812
|
+
}) : null,
|
|
9813
|
+
state.status === "ready" && visibleGroups.length > 0 && shownGroups.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9814
|
+
className: "codexModelSelectEmpty",
|
|
9815
|
+
children: t("modelNoMatch")
|
|
9563
9816
|
}) : null
|
|
9564
9817
|
]
|
|
9565
9818
|
});
|
|
@@ -12422,6 +12675,8 @@ window.__ModuleLoader__.load({
|
|
|
12422
12675
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
12423
12676
|
const [failed, setFailed] = (0, react.useState)(false);
|
|
12424
12677
|
const [now, setNow] = (0, react.useState)(Date.now());
|
|
12678
|
+
const [clients, setClients] = (0, react.useState)();
|
|
12679
|
+
const [removing, setRemoving] = (0, react.useState)();
|
|
12425
12680
|
const alive = (0, react.useRef)(false);
|
|
12426
12681
|
const on = snapshot.remoteControl === "on";
|
|
12427
12682
|
const read = async () => {
|
|
@@ -12430,12 +12685,49 @@ window.__ModuleLoader__.load({
|
|
|
12430
12685
|
if (alive.current && result.ok) setState(result.value);
|
|
12431
12686
|
} catch {}
|
|
12432
12687
|
};
|
|
12688
|
+
const readClients = async () => {
|
|
12689
|
+
try {
|
|
12690
|
+
const result = await rpc.call(CHANNEL, "remote/clients", {});
|
|
12691
|
+
if (alive.current && result.ok) setClients(result.value);
|
|
12692
|
+
} catch {}
|
|
12693
|
+
};
|
|
12433
12694
|
(0, react.useEffect)(() => {
|
|
12434
12695
|
alive.current = true;
|
|
12435
12696
|
return () => {
|
|
12436
12697
|
alive.current = false;
|
|
12437
12698
|
};
|
|
12438
12699
|
}, []);
|
|
12700
|
+
(0, react.useEffect)(() => {
|
|
12701
|
+
if (!on) {
|
|
12702
|
+
setClients(void 0);
|
|
12703
|
+
return;
|
|
12704
|
+
}
|
|
12705
|
+
let stopped = false, timer;
|
|
12706
|
+
const poll = async () => {
|
|
12707
|
+
await readClients();
|
|
12708
|
+
if (!stopped) timer = setTimeout(poll, 2e4);
|
|
12709
|
+
};
|
|
12710
|
+
poll();
|
|
12711
|
+
return () => {
|
|
12712
|
+
stopped = true;
|
|
12713
|
+
clearTimeout(timer);
|
|
12714
|
+
};
|
|
12715
|
+
}, [on, rpc]);
|
|
12716
|
+
const remove = async (client) => {
|
|
12717
|
+
if (removing) return;
|
|
12718
|
+
setRemoving(client.clientId);
|
|
12719
|
+
setFailed(false);
|
|
12720
|
+
try {
|
|
12721
|
+
const result = await rpc.call(CHANNEL, "remote/revoke", { clientId: client.clientId });
|
|
12722
|
+
if (!alive.current) return;
|
|
12723
|
+
if (result.ok) setClients(result.value);
|
|
12724
|
+
else setFailed(true);
|
|
12725
|
+
} catch {
|
|
12726
|
+
if (alive.current) setFailed(true);
|
|
12727
|
+
} finally {
|
|
12728
|
+
if (alive.current) setRemoving(void 0);
|
|
12729
|
+
}
|
|
12730
|
+
};
|
|
12439
12731
|
(0, react.useEffect)(() => {
|
|
12440
12732
|
if (!on) {
|
|
12441
12733
|
setState(void 0);
|
|
@@ -12567,6 +12859,34 @@ window.__ModuleLoader__.load({
|
|
|
12567
12859
|
className: "codexSubscriptionHelp",
|
|
12568
12860
|
children: t("remoteExpired")
|
|
12569
12861
|
}) : null,
|
|
12862
|
+
clients ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12863
|
+
className: "codexSubscriptionRemoteClients",
|
|
12864
|
+
role: "list",
|
|
12865
|
+
"aria-label": t("remotePaired"),
|
|
12866
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
12867
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
12868
|
+
children: t("remotePaired")
|
|
12869
|
+
}), clients.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
12870
|
+
className: "codexSubscriptionHelp",
|
|
12871
|
+
children: t("remoteNoPhones")
|
|
12872
|
+
}) : clients.map((client) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12873
|
+
role: "listitem",
|
|
12874
|
+
className: "codexSubscriptionPreference",
|
|
12875
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: [
|
|
12876
|
+
client.name ?? t("remotePhoneUnknown"),
|
|
12877
|
+
client.platform,
|
|
12878
|
+
client.lastSeenAt ? t("remoteLastSeen").replace("{date}", new Date(client.lastSeenAt).toLocaleString()) : null
|
|
12879
|
+
].filter(Boolean).join(" · ") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
12880
|
+
type: "button",
|
|
12881
|
+
variant: "outline",
|
|
12882
|
+
disabled: Boolean(removing),
|
|
12883
|
+
onClick: () => {
|
|
12884
|
+
remove(client);
|
|
12885
|
+
},
|
|
12886
|
+
children: t("remoteRevoke")
|
|
12887
|
+
})]
|
|
12888
|
+
}, client.clientId))]
|
|
12889
|
+
}) : null,
|
|
12570
12890
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
12571
12891
|
className: "codexSubscriptionHelp",
|
|
12572
12892
|
children: t("remoteLimits")
|
|
@@ -12760,6 +13080,115 @@ window.__ModuleLoader__.load({
|
|
|
12760
13080
|
})]
|
|
12761
13081
|
});
|
|
12762
13082
|
}
|
|
13083
|
+
function ReasoningSummaryPreference({ preference, t }) {
|
|
13084
|
+
const snapshot = usePreferenceSnapshot(preference);
|
|
13085
|
+
const writable = snapshot.status === "ready" && snapshot.writable === true;
|
|
13086
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13087
|
+
className: "codexSubscriptionPreference",
|
|
13088
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13089
|
+
className: "codexSubscriptionPreferenceCopy",
|
|
13090
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13091
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
13092
|
+
children: t("reasoningSummary")
|
|
13093
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13094
|
+
className: "codexSubscriptionPreferenceHint",
|
|
13095
|
+
children: t("reasoningSummaryHint")
|
|
13096
|
+
})]
|
|
13097
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13098
|
+
className: "codexSubscriptionQuotaModes",
|
|
13099
|
+
"data-saving": snapshot.saving || void 0,
|
|
13100
|
+
"aria-busy": snapshot.saving || void 0,
|
|
13101
|
+
role: "radiogroup",
|
|
13102
|
+
"aria-label": t("reasoningSummary"),
|
|
13103
|
+
children: REASONING_SUMMARIES.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13104
|
+
className: "codexSubscriptionQuotaMode",
|
|
13105
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13106
|
+
type: "radio",
|
|
13107
|
+
name: "codex-reasoning-summary",
|
|
13108
|
+
checked: snapshot.reasoningSummary === value,
|
|
13109
|
+
disabled: !writable,
|
|
13110
|
+
onChange: () => {
|
|
13111
|
+
preference.set({ [REASONING_SUMMARY_FIELD]: value });
|
|
13112
|
+
}
|
|
13113
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`reasoningSummary_${value}`) })]
|
|
13114
|
+
}, value))
|
|
13115
|
+
})]
|
|
13116
|
+
});
|
|
13117
|
+
}
|
|
13118
|
+
function RetryPolicyPreference({ preference, t }) {
|
|
13119
|
+
const snapshot = usePreferenceSnapshot(preference);
|
|
13120
|
+
const writable = snapshot.status === "ready" && snapshot.writable === true;
|
|
13121
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13122
|
+
className: "codexSubscriptionPreference",
|
|
13123
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13124
|
+
className: "codexSubscriptionPreferenceCopy",
|
|
13125
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13126
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
13127
|
+
children: t("retryPolicy")
|
|
13128
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13129
|
+
className: "codexSubscriptionPreferenceHint",
|
|
13130
|
+
children: t("retryPolicyHint")
|
|
13131
|
+
})]
|
|
13132
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13133
|
+
className: "codexSubscriptionQuotaModes",
|
|
13134
|
+
"data-saving": snapshot.saving || void 0,
|
|
13135
|
+
"aria-busy": snapshot.saving || void 0,
|
|
13136
|
+
role: "radiogroup",
|
|
13137
|
+
"aria-label": t("retryPolicy"),
|
|
13138
|
+
children: RETRY_POLICIES.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13139
|
+
className: "codexSubscriptionQuotaMode",
|
|
13140
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13141
|
+
type: "radio",
|
|
13142
|
+
name: "codex-retry-policy",
|
|
13143
|
+
checked: snapshot.retryPolicy === value,
|
|
13144
|
+
disabled: !writable,
|
|
13145
|
+
onChange: () => {
|
|
13146
|
+
preference.set({ [RETRY_POLICY_FIELD]: value });
|
|
13147
|
+
}
|
|
13148
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`retryPolicy_${value}`) })]
|
|
13149
|
+
}, value))
|
|
13150
|
+
})]
|
|
13151
|
+
});
|
|
13152
|
+
}
|
|
13153
|
+
function ConnectorsPreference({ preference, t }) {
|
|
13154
|
+
const snapshot = usePreferenceSnapshot(preference);
|
|
13155
|
+
const writable = snapshot.status === "ready" && snapshot.writable === true;
|
|
13156
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13157
|
+
className: "codexSubscriptionPreference",
|
|
13158
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13159
|
+
className: "codexSubscriptionPreferenceCopy",
|
|
13160
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13161
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
13162
|
+
children: [
|
|
13163
|
+
t("connectors"),
|
|
13164
|
+
" ",
|
|
13165
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13166
|
+
]
|
|
13167
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13168
|
+
className: "codexSubscriptionPreferenceHint",
|
|
13169
|
+
children: t("connectorsHint")
|
|
13170
|
+
})]
|
|
13171
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13172
|
+
className: "codexSubscriptionQuotaModes",
|
|
13173
|
+
"data-saving": snapshot.saving || void 0,
|
|
13174
|
+
"aria-busy": snapshot.saving || void 0,
|
|
13175
|
+
role: "radiogroup",
|
|
13176
|
+
"aria-label": t("connectors"),
|
|
13177
|
+
children: CONNECTOR_MODES.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13178
|
+
className: "codexSubscriptionQuotaMode",
|
|
13179
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13180
|
+
type: "radio",
|
|
13181
|
+
name: "codex-connectors",
|
|
13182
|
+
checked: snapshot.connectors === value,
|
|
13183
|
+
disabled: !writable,
|
|
13184
|
+
onChange: () => {
|
|
13185
|
+
preference.set({ [CONNECTORS_FIELD]: value });
|
|
13186
|
+
}
|
|
13187
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`connectors_${value}`) })]
|
|
13188
|
+
}, value))
|
|
13189
|
+
})]
|
|
13190
|
+
});
|
|
13191
|
+
}
|
|
12763
13192
|
function StreamIdleTimeoutPreference({ preference, t }) {
|
|
12764
13193
|
const snapshot = usePreferenceSnapshot(preference);
|
|
12765
13194
|
const writable = snapshot.status === "ready" && snapshot.writable === true;
|
|
@@ -13034,245 +13463,267 @@ window.__ModuleLoader__.load({
|
|
|
13034
13463
|
const snapshot = usePreferenceSnapshot(preference);
|
|
13035
13464
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13036
13465
|
className: section === "advanced" ? "codexSubscriptionAdvancedPreferences" : "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13037
|
-
children: [
|
|
13038
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
13039
|
-
className: "
|
|
13040
|
-
|
|
13041
|
-
children:
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13466
|
+
children: [
|
|
13467
|
+
snapshot.restartRequired ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
13468
|
+
className: "codexSubscriptionError",
|
|
13469
|
+
role: "status",
|
|
13470
|
+
children: t("settingsRestartRequired")
|
|
13471
|
+
}) : null,
|
|
13472
|
+
section === "advanced" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
13473
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
13474
|
+
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13475
|
+
"aria-label": t("modelsSectionTitle"),
|
|
13476
|
+
children: [
|
|
13477
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("modelsSectionTitle") }),
|
|
13478
|
+
defaultModel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultModelPreference, {
|
|
13479
|
+
preference,
|
|
13480
|
+
defaultModel,
|
|
13481
|
+
t
|
|
13482
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" })] }),
|
|
13483
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelCatalogStatus, {
|
|
13484
|
+
preference,
|
|
13485
|
+
t
|
|
13486
|
+
}),
|
|
13487
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13488
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PickerModelsPreference, {
|
|
13489
|
+
preference,
|
|
13490
|
+
t
|
|
13491
|
+
}),
|
|
13492
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13493
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextWindowPreference, {
|
|
13494
|
+
preference,
|
|
13495
|
+
t
|
|
13496
|
+
}),
|
|
13497
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13498
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InputImageDetailPreference, {
|
|
13499
|
+
preference,
|
|
13500
|
+
t
|
|
13501
|
+
}),
|
|
13502
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13503
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSummaryPreference, {
|
|
13504
|
+
preference,
|
|
13505
|
+
t
|
|
13506
|
+
}),
|
|
13507
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13508
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RetryPolicyPreference, {
|
|
13509
|
+
preference,
|
|
13510
|
+
t
|
|
13511
|
+
}),
|
|
13512
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorsPreference, {
|
|
13513
|
+
preference,
|
|
13514
|
+
t
|
|
13515
|
+
})
|
|
13516
|
+
]
|
|
13517
|
+
}),
|
|
13518
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
13519
|
+
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13520
|
+
"aria-label": t("searchSectionTitle"),
|
|
13521
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("searchSectionTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchProviderPreference, {
|
|
13064
13522
|
preference,
|
|
13065
13523
|
t
|
|
13524
|
+
})]
|
|
13525
|
+
}),
|
|
13526
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
13527
|
+
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13528
|
+
"aria-label": t("connectionTitle"),
|
|
13529
|
+
children: [
|
|
13530
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13531
|
+
className: "codexSubscriptionPreference",
|
|
13532
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13533
|
+
className: "codexSubscriptionPreferenceCopy",
|
|
13534
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13535
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
13536
|
+
children: [
|
|
13537
|
+
t("connectionTitle"),
|
|
13538
|
+
" ",
|
|
13539
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13540
|
+
]
|
|
13541
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13542
|
+
className: "codexSubscriptionPreferenceHint",
|
|
13543
|
+
children: t("connectionHint")
|
|
13544
|
+
})]
|
|
13545
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13546
|
+
className: "codexSubscriptionQuotaModes",
|
|
13547
|
+
role: "radiogroup",
|
|
13548
|
+
"aria-label": t("connectionTitle"),
|
|
13549
|
+
"aria-busy": snapshot.saving || void 0,
|
|
13550
|
+
children: ["sse", "websocket"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13551
|
+
className: "codexSubscriptionQuotaMode",
|
|
13552
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13553
|
+
type: "radio",
|
|
13554
|
+
name: "codex-connection-mode",
|
|
13555
|
+
checked: snapshot.connectionMode === value,
|
|
13556
|
+
disabled: !snapshot.writable,
|
|
13557
|
+
onChange: () => {
|
|
13558
|
+
preference.set({ connectionMode: value });
|
|
13559
|
+
}
|
|
13560
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: value === "sse" ? "SSE" : "WebSocket" })]
|
|
13561
|
+
}, value))
|
|
13562
|
+
})]
|
|
13563
|
+
}),
|
|
13564
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13565
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StreamIdleTimeoutPreference, {
|
|
13566
|
+
preference,
|
|
13567
|
+
t
|
|
13568
|
+
})
|
|
13569
|
+
]
|
|
13570
|
+
}),
|
|
13571
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
13572
|
+
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13573
|
+
"aria-label": t("reviewModelTitle"),
|
|
13574
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13575
|
+
className: "codexSubscriptionPreference",
|
|
13576
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13577
|
+
className: "codexSubscriptionPreferenceCopy",
|
|
13578
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13579
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
13580
|
+
children: [
|
|
13581
|
+
t("reviewModelTitle"),
|
|
13582
|
+
" ",
|
|
13583
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13584
|
+
]
|
|
13585
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13586
|
+
className: "codexSubscriptionPreferenceHint",
|
|
13587
|
+
children: t("reviewModelHint")
|
|
13588
|
+
})]
|
|
13589
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13590
|
+
className: "codexSubscriptionQuotaModes",
|
|
13591
|
+
role: "radiogroup",
|
|
13592
|
+
"aria-label": t("reviewModelTitle"),
|
|
13593
|
+
"aria-busy": snapshot.saving || void 0,
|
|
13594
|
+
children: ["session", "official"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13595
|
+
className: "codexSubscriptionQuotaMode",
|
|
13596
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13597
|
+
type: "radio",
|
|
13598
|
+
name: "codex-review-model",
|
|
13599
|
+
checked: snapshot.reviewModel === value,
|
|
13600
|
+
disabled: !snapshot.writable,
|
|
13601
|
+
onChange: () => {
|
|
13602
|
+
preference.set({ reviewModel: value });
|
|
13603
|
+
}
|
|
13604
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`reviewModel_${value}`) })]
|
|
13605
|
+
}, value))
|
|
13606
|
+
})]
|
|
13066
13607
|
})
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13071
|
-
"aria-label": t("searchSectionTitle"),
|
|
13072
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("searchSectionTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchProviderPreference, {
|
|
13608
|
+
}),
|
|
13609
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RemoteControlCard, {
|
|
13610
|
+
rpc,
|
|
13073
13611
|
preference,
|
|
13612
|
+
snapshot,
|
|
13074
13613
|
t
|
|
13075
|
-
})
|
|
13076
|
-
|
|
13077
|
-
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
children: [
|
|
13081
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13614
|
+
}),
|
|
13615
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
13616
|
+
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13617
|
+
"aria-label": t("compactionTitle"),
|
|
13618
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13082
13619
|
className: "codexSubscriptionPreference",
|
|
13083
13620
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13084
13621
|
className: "codexSubscriptionPreferenceCopy",
|
|
13085
13622
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13086
13623
|
className: "codexSubscriptionPreferenceLabel",
|
|
13087
13624
|
children: [
|
|
13088
|
-
t("
|
|
13625
|
+
t("compactionTitle"),
|
|
13089
13626
|
" ",
|
|
13090
13627
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13091
13628
|
]
|
|
13092
13629
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13093
13630
|
className: "codexSubscriptionPreferenceHint",
|
|
13094
|
-
children: t("
|
|
13631
|
+
children: t("compactionHint")
|
|
13095
13632
|
})]
|
|
13096
13633
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13097
13634
|
className: "codexSubscriptionQuotaModes",
|
|
13098
13635
|
role: "radiogroup",
|
|
13099
|
-
"aria-label": t("
|
|
13636
|
+
"aria-label": t("compactionTitle"),
|
|
13100
13637
|
"aria-busy": snapshot.saving || void 0,
|
|
13101
|
-
children: ["
|
|
13638
|
+
children: ["dsh", "cloud"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13102
13639
|
className: "codexSubscriptionQuotaMode",
|
|
13103
13640
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13104
13641
|
type: "radio",
|
|
13105
|
-
name: "codex-
|
|
13106
|
-
checked: snapshot.
|
|
13642
|
+
name: "codex-compaction-mode",
|
|
13643
|
+
checked: snapshot.compactionMode === value,
|
|
13107
13644
|
disabled: !snapshot.writable,
|
|
13108
13645
|
onChange: () => {
|
|
13109
|
-
preference.set({
|
|
13646
|
+
preference.set({ compactionMode: value });
|
|
13110
13647
|
}
|
|
13111
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: value
|
|
13648
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`compaction_${value}`) })]
|
|
13112
13649
|
}, value))
|
|
13113
13650
|
})]
|
|
13114
|
-
}),
|
|
13115
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13116
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StreamIdleTimeoutPreference, {
|
|
13117
|
-
preference,
|
|
13118
|
-
t
|
|
13119
13651
|
})
|
|
13120
|
-
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13124
|
-
"aria-label": t("reviewModelTitle"),
|
|
13125
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13126
|
-
className: "codexSubscriptionPreference",
|
|
13127
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13128
|
-
className: "codexSubscriptionPreferenceCopy",
|
|
13129
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13130
|
-
className: "codexSubscriptionPreferenceLabel",
|
|
13131
|
-
children: [
|
|
13132
|
-
t("reviewModelTitle"),
|
|
13133
|
-
" ",
|
|
13134
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13135
|
-
]
|
|
13136
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13137
|
-
className: "codexSubscriptionPreferenceHint",
|
|
13138
|
-
children: t("reviewModelHint")
|
|
13139
|
-
})]
|
|
13140
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13141
|
-
className: "codexSubscriptionQuotaModes",
|
|
13142
|
-
role: "radiogroup",
|
|
13143
|
-
"aria-label": t("reviewModelTitle"),
|
|
13144
|
-
"aria-busy": snapshot.saving || void 0,
|
|
13145
|
-
children: ["session", "official"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13146
|
-
className: "codexSubscriptionQuotaMode",
|
|
13147
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13148
|
-
type: "radio",
|
|
13149
|
-
name: "codex-review-model",
|
|
13150
|
-
checked: snapshot.reviewModel === value,
|
|
13151
|
-
disabled: !snapshot.writable,
|
|
13152
|
-
onChange: () => {
|
|
13153
|
-
preference.set({ reviewModel: value });
|
|
13154
|
-
}
|
|
13155
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`reviewModel_${value}`) })]
|
|
13156
|
-
}, value))
|
|
13157
|
-
})]
|
|
13158
|
-
})
|
|
13159
|
-
}),
|
|
13160
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RemoteControlCard, {
|
|
13161
|
-
rpc,
|
|
13162
|
-
preference,
|
|
13163
|
-
snapshot,
|
|
13164
|
-
t
|
|
13165
|
-
}),
|
|
13166
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
13167
|
-
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13168
|
-
"aria-label": t("compactionTitle"),
|
|
13169
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13170
|
-
className: "codexSubscriptionPreference",
|
|
13652
|
+
}),
|
|
13653
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
13654
|
+
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13655
|
+
"aria-label": t("subagentBackendTitle"),
|
|
13171
13656
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13172
|
-
className: "
|
|
13173
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
13174
|
-
className: "
|
|
13175
|
-
children: [
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13179
|
-
|
|
13180
|
-
|
|
13181
|
-
|
|
13182
|
-
|
|
13657
|
+
className: "codexSubscriptionPreference",
|
|
13658
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13659
|
+
className: "codexSubscriptionPreferenceCopy",
|
|
13660
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13661
|
+
className: "codexSubscriptionPreferenceLabel",
|
|
13662
|
+
children: [
|
|
13663
|
+
t("subagentBackendTitle"),
|
|
13664
|
+
" ",
|
|
13665
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13666
|
+
]
|
|
13667
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13668
|
+
className: "codexSubscriptionPreferenceHint",
|
|
13669
|
+
children: t(snapshot.subagentBackendAvailable ? "subagentBackendHint" : "subagentBackendUnavailable")
|
|
13670
|
+
})]
|
|
13671
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13672
|
+
className: "codexSubscriptionQuotaModes",
|
|
13673
|
+
role: "radiogroup",
|
|
13674
|
+
"aria-label": t("subagentBackendTitle"),
|
|
13675
|
+
"aria-busy": snapshot.saving || void 0,
|
|
13676
|
+
children: ["dsh", "codex"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13677
|
+
className: "codexSubscriptionQuotaMode",
|
|
13678
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13679
|
+
type: "radio",
|
|
13680
|
+
name: "codex-subagent-backend",
|
|
13681
|
+
checked: snapshot.subagentBackend === value,
|
|
13682
|
+
disabled: !snapshot.writable || !snapshot.subagentBackendAvailable || value === "codex" && !snapshot.subagentRuntimeInstalled,
|
|
13683
|
+
onChange: () => {
|
|
13684
|
+
preference.set({ subagentBackend: value });
|
|
13685
|
+
}
|
|
13686
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`subagentBackend_${value}`) })]
|
|
13687
|
+
}, value))
|
|
13183
13688
|
})]
|
|
13184
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
13185
|
-
|
|
13186
|
-
|
|
13187
|
-
|
|
13188
|
-
"aria-busy": snapshot.saving || void 0,
|
|
13189
|
-
children: ["dsh", "cloud"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13190
|
-
className: "codexSubscriptionQuotaMode",
|
|
13191
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13192
|
-
type: "radio",
|
|
13193
|
-
name: "codex-compaction-mode",
|
|
13194
|
-
checked: snapshot.compactionMode === value,
|
|
13195
|
-
disabled: !snapshot.writable,
|
|
13196
|
-
onChange: () => {
|
|
13197
|
-
preference.set({ compactionMode: value });
|
|
13198
|
-
}
|
|
13199
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`compaction_${value}`) })]
|
|
13200
|
-
}, value))
|
|
13689
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimeManagement, {
|
|
13690
|
+
rpc,
|
|
13691
|
+
preference,
|
|
13692
|
+
t
|
|
13201
13693
|
})]
|
|
13202
13694
|
})
|
|
13203
|
-
}),
|
|
13204
|
-
|
|
13205
|
-
className: "codexSubscriptionCard codexSubscriptionPreferencesCard",
|
|
13206
|
-
"aria-label": t("subagentBackendTitle"),
|
|
13207
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13208
|
-
className: "codexSubscriptionPreference",
|
|
13209
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13210
|
-
className: "codexSubscriptionPreferenceCopy",
|
|
13211
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
13212
|
-
className: "codexSubscriptionPreferenceLabel",
|
|
13213
|
-
children: [
|
|
13214
|
-
t("subagentBackendTitle"),
|
|
13215
|
-
" ",
|
|
13216
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "Beta" })
|
|
13217
|
-
]
|
|
13218
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13219
|
-
className: "codexSubscriptionPreferenceHint",
|
|
13220
|
-
children: t(snapshot.subagentBackendAvailable ? "subagentBackendHint" : "subagentBackendUnavailable")
|
|
13221
|
-
})]
|
|
13222
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13223
|
-
className: "codexSubscriptionQuotaModes",
|
|
13224
|
-
role: "radiogroup",
|
|
13225
|
-
"aria-label": t("subagentBackendTitle"),
|
|
13226
|
-
"aria-busy": snapshot.saving || void 0,
|
|
13227
|
-
children: ["dsh", "codex"].map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
13228
|
-
className: "codexSubscriptionQuotaMode",
|
|
13229
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
13230
|
-
type: "radio",
|
|
13231
|
-
name: "codex-subagent-backend",
|
|
13232
|
-
checked: snapshot.subagentBackend === value,
|
|
13233
|
-
disabled: !snapshot.writable || !snapshot.subagentBackendAvailable || value === "codex" && !snapshot.subagentRuntimeInstalled,
|
|
13234
|
-
onChange: () => {
|
|
13235
|
-
preference.set({ subagentBackend: value });
|
|
13236
|
-
}
|
|
13237
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`subagentBackend_${value}`) })]
|
|
13238
|
-
}, value))
|
|
13239
|
-
})]
|
|
13240
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimeManagement, {
|
|
13241
|
-
rpc,
|
|
13695
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
13696
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuickQuotaPreference, {
|
|
13242
13697
|
preference,
|
|
13243
13698
|
t
|
|
13699
|
+
}),
|
|
13700
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CapabilityPreferences, {
|
|
13701
|
+
preference,
|
|
13702
|
+
t,
|
|
13703
|
+
section: "quota"
|
|
13704
|
+
}),
|
|
13705
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13706
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoQuotaRetryPreference, {
|
|
13707
|
+
preference,
|
|
13708
|
+
t
|
|
13709
|
+
})
|
|
13710
|
+
] }),
|
|
13711
|
+
snapshot.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13712
|
+
className: "codexSubscriptionRecover",
|
|
13713
|
+
role: "alert",
|
|
13714
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
13715
|
+
className: "codexSubscriptionError",
|
|
13716
|
+
children: t("preferenceFailed")
|
|
13717
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
13718
|
+
type: "button",
|
|
13719
|
+
variant: "outline",
|
|
13720
|
+
onClick: () => {
|
|
13721
|
+
preference.retry();
|
|
13722
|
+
},
|
|
13723
|
+
children: t("preferenceRetry")
|
|
13244
13724
|
})]
|
|
13245
|
-
})
|
|
13246
|
-
]
|
|
13247
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuickQuotaPreference, {
|
|
13248
|
-
preference,
|
|
13249
|
-
t
|
|
13250
|
-
}),
|
|
13251
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CapabilityPreferences, {
|
|
13252
|
-
preference,
|
|
13253
|
-
t,
|
|
13254
|
-
section: "quota"
|
|
13255
|
-
}),
|
|
13256
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "codexSubscriptionDivider" }),
|
|
13257
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AutoQuotaRetryPreference, {
|
|
13258
|
-
preference,
|
|
13259
|
-
t
|
|
13260
|
-
})
|
|
13261
|
-
] }), snapshot.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13262
|
-
className: "codexSubscriptionRecover",
|
|
13263
|
-
role: "alert",
|
|
13264
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
13265
|
-
className: "codexSubscriptionError",
|
|
13266
|
-
children: t("preferenceFailed")
|
|
13267
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
13268
|
-
type: "button",
|
|
13269
|
-
variant: "outline",
|
|
13270
|
-
onClick: () => {
|
|
13271
|
-
preference.retry();
|
|
13272
|
-
},
|
|
13273
|
-
children: t("preferenceRetry")
|
|
13274
|
-
})]
|
|
13275
|
-
}) : null]
|
|
13725
|
+
}) : null
|
|
13726
|
+
]
|
|
13276
13727
|
});
|
|
13277
13728
|
}
|
|
13278
13729
|
//#endregion
|
|
@@ -13318,6 +13769,12 @@ window.__ModuleLoader__.load({
|
|
|
13318
13769
|
}
|
|
13319
13770
|
//#endregion
|
|
13320
13771
|
//#region src/client-account.jsx
|
|
13772
|
+
const LOGIN_FAILURES = [
|
|
13773
|
+
"account-claim",
|
|
13774
|
+
"network",
|
|
13775
|
+
"token-exchange",
|
|
13776
|
+
"callback"
|
|
13777
|
+
];
|
|
13321
13778
|
function AccountEmail({ candidate, fallback, t, emailVisible, onClick }) {
|
|
13322
13779
|
if (typeof candidate?.email !== "string" || candidate.email.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13323
13780
|
title: t("emailUnavailable"),
|
|
@@ -13677,7 +14134,7 @@ window.__ModuleLoader__.load({
|
|
|
13677
14134
|
flow?.phase === "failed" || error !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
13678
14135
|
className: "codexSubscriptionError",
|
|
13679
14136
|
role: "alert",
|
|
13680
|
-
children: error ?? t("failed")
|
|
14137
|
+
children: error ?? (LOGIN_FAILURES.includes(flow?.failure) ? t(`failed_${flow.failure.replace("-", "_")}`) : t("failed"))
|
|
13681
14138
|
}) : null
|
|
13682
14139
|
]
|
|
13683
14140
|
});
|
|
@@ -14130,6 +14587,276 @@ window.__ModuleLoader__.load({
|
|
|
14130
14587
|
};
|
|
14131
14588
|
}
|
|
14132
14589
|
//#endregion
|
|
14590
|
+
//#region src/client-usage-overview.jsx
|
|
14591
|
+
const uiLocale = () => typeof document === "undefined" ? void 0 : document.documentElement.lang || void 0;
|
|
14592
|
+
const WEEKS = 26;
|
|
14593
|
+
const compact = (value) => new Intl.NumberFormat(uiLocale(), {
|
|
14594
|
+
notation: "compact",
|
|
14595
|
+
maximumFractionDigits: 1
|
|
14596
|
+
}).format(value);
|
|
14597
|
+
const hours = (seconds) => seconds >= 3600 ? `${Math.round(seconds / 360) / 10} h` : `${Math.max(1, Math.round(seconds / 60))} min`;
|
|
14598
|
+
const key = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
14599
|
+
function UsageHeatmap({ days, t }) {
|
|
14600
|
+
const byDate = new Map(days.map((day) => [day.date, day.tokens]));
|
|
14601
|
+
const today = /* @__PURE__ */ new Date();
|
|
14602
|
+
today.setHours(0, 0, 0, 0);
|
|
14603
|
+
const start = new Date(today);
|
|
14604
|
+
start.setDate(start.getDate() - ((WEEKS - 1) * 7 + today.getDay()));
|
|
14605
|
+
const cells = [];
|
|
14606
|
+
for (let index = 0; index < WEEKS * 7; index += 1) {
|
|
14607
|
+
const date = new Date(start);
|
|
14608
|
+
date.setDate(start.getDate() + index);
|
|
14609
|
+
if (date > today) break;
|
|
14610
|
+
cells.push({
|
|
14611
|
+
date: key(date),
|
|
14612
|
+
tokens: byDate.get(key(date)) ?? 0,
|
|
14613
|
+
column: Math.floor(index / 7),
|
|
14614
|
+
row: index % 7
|
|
14615
|
+
});
|
|
14616
|
+
}
|
|
14617
|
+
const busy = cells.map((cell) => cell.tokens).filter((tokens) => tokens > 0).sort((a, b) => a - b);
|
|
14618
|
+
const level = (tokens) => tokens === 0 ? 0 : 1 + [
|
|
14619
|
+
.25,
|
|
14620
|
+
.5,
|
|
14621
|
+
.75
|
|
14622
|
+
].filter((point) => tokens > busy[Math.floor((busy.length - 1) * point)]).length;
|
|
14623
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
14624
|
+
className: "codexSubscriptionHeatmap",
|
|
14625
|
+
viewBox: `0 0 ${WEEKS * 14} 98`,
|
|
14626
|
+
role: "img",
|
|
14627
|
+
"aria-label": t("overviewHeatmap"),
|
|
14628
|
+
children: cells.map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
14629
|
+
x: cell.column * 14,
|
|
14630
|
+
y: cell.row * 14,
|
|
14631
|
+
width: "11",
|
|
14632
|
+
height: "11",
|
|
14633
|
+
rx: "2",
|
|
14634
|
+
"data-level": level(cell.tokens),
|
|
14635
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("title", { children: `${cell.date}: ${cell.tokens === 0 ? t("overviewNoUse") : fill(t("overviewTokens"), { value: compact(cell.tokens) })}` })
|
|
14636
|
+
}, cell.date))
|
|
14637
|
+
});
|
|
14638
|
+
}
|
|
14639
|
+
function UsageOverview({ rpc, t, signedIn, resetKey }) {
|
|
14640
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
14641
|
+
const [state, setState] = (0, react.useState)({ status: "idle" });
|
|
14642
|
+
const request = (0, react.useRef)(0);
|
|
14643
|
+
(0, react.useEffect)(() => {
|
|
14644
|
+
request.current += 1;
|
|
14645
|
+
setState({ status: "idle" });
|
|
14646
|
+
}, [signedIn, resetKey]);
|
|
14647
|
+
(0, react.useEffect)(() => {
|
|
14648
|
+
if (!open || !signedIn || state.status !== "idle") return;
|
|
14649
|
+
const id = ++request.current;
|
|
14650
|
+
setState({ status: "loading" });
|
|
14651
|
+
recoveryCall(rpc, "usage/profile", {}).then((value) => {
|
|
14652
|
+
if (request.current === id) setState({
|
|
14653
|
+
status: "ready",
|
|
14654
|
+
value
|
|
14655
|
+
});
|
|
14656
|
+
}).catch((error) => {
|
|
14657
|
+
if (request.current === id) setState({
|
|
14658
|
+
status: "error",
|
|
14659
|
+
message: error.message
|
|
14660
|
+
});
|
|
14661
|
+
});
|
|
14662
|
+
}, [
|
|
14663
|
+
open,
|
|
14664
|
+
signedIn,
|
|
14665
|
+
state.status,
|
|
14666
|
+
rpc
|
|
14667
|
+
]);
|
|
14668
|
+
if (!signedIn) return null;
|
|
14669
|
+
const value = state.value;
|
|
14670
|
+
const stats = value === void 0 || value.available === false ? [] : [
|
|
14671
|
+
[t("overviewLifetime"), value.lifetimeTokens === void 0 ? void 0 : compact(value.lifetimeTokens)],
|
|
14672
|
+
[t("overviewPeak"), value.peakDailyTokens === void 0 ? void 0 : compact(value.peakDailyTokens)],
|
|
14673
|
+
[t("overviewStreak"), value.currentStreakDays === void 0 ? void 0 : fill(t("overviewDays"), { value: value.currentStreakDays })],
|
|
14674
|
+
[t("overviewLongestStreak"), value.longestStreakDays === void 0 ? void 0 : fill(t("overviewDays"), { value: value.longestStreakDays })],
|
|
14675
|
+
[t("overviewThreads"), value.totalThreads === void 0 ? void 0 : value.totalThreads.toLocaleString(uiLocale())],
|
|
14676
|
+
[t("overviewEffort"), value.mostUsedReasoningEffort === void 0 ? void 0 : `${value.mostUsedReasoningEffort}${value.mostUsedReasoningEffortPercent === void 0 ? "" : ` · ${value.mostUsedReasoningEffortPercent}%`}`],
|
|
14677
|
+
[t("overviewFast"), value.fastModePercent === void 0 ? void 0 : `${value.fastModePercent}%`],
|
|
14678
|
+
[t("overviewLongestTurn"), value.longestRunningTurnSeconds === void 0 ? void 0 : hours(value.longestRunningTurnSeconds)]
|
|
14679
|
+
].filter(([, text]) => text !== void 0);
|
|
14680
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
14681
|
+
className: "codexSubscriptionHistory",
|
|
14682
|
+
onToggle: (event) => setOpen(event.currentTarget.open),
|
|
14683
|
+
children: [
|
|
14684
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("overviewTitle") }),
|
|
14685
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
14686
|
+
"aria-live": "polite",
|
|
14687
|
+
children: [
|
|
14688
|
+
state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14689
|
+
className: "codexSubscriptionEmpty",
|
|
14690
|
+
role: "status",
|
|
14691
|
+
children: t("overviewLoading")
|
|
14692
|
+
}) : null,
|
|
14693
|
+
state.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14694
|
+
className: "codexSubscriptionError",
|
|
14695
|
+
role: "alert",
|
|
14696
|
+
children: state.message
|
|
14697
|
+
}) : null,
|
|
14698
|
+
state.status === "ready" && stats.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14699
|
+
className: "codexSubscriptionEmpty",
|
|
14700
|
+
role: "status",
|
|
14701
|
+
children: t("overviewUnavailable")
|
|
14702
|
+
}) : null
|
|
14703
|
+
]
|
|
14704
|
+
}),
|
|
14705
|
+
stats.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
|
|
14706
|
+
className: "codexSubscriptionOverviewStats",
|
|
14707
|
+
children: stats.map(([label, text]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: text })] }, label))
|
|
14708
|
+
}), value.days.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageHeatmap, {
|
|
14709
|
+
days: value.days,
|
|
14710
|
+
t
|
|
14711
|
+
})] })
|
|
14712
|
+
]
|
|
14713
|
+
});
|
|
14714
|
+
}
|
|
14715
|
+
//#endregion
|
|
14716
|
+
//#region src/client-usage-history.jsx
|
|
14717
|
+
const DIMENSIONS = [
|
|
14718
|
+
"model",
|
|
14719
|
+
"surface",
|
|
14720
|
+
"thread_source",
|
|
14721
|
+
"turn_trigger"
|
|
14722
|
+
];
|
|
14723
|
+
const LABELS = /* @__PURE__ */ new Map([
|
|
14724
|
+
["desktop_app", "historyDesktopApp"],
|
|
14725
|
+
["cli", "historyCli"],
|
|
14726
|
+
["ide_extension", "historyIde"],
|
|
14727
|
+
["web", "historyWeb"],
|
|
14728
|
+
["mobile", "historyMobile"],
|
|
14729
|
+
["user", "historyUser"],
|
|
14730
|
+
["subagent", "historySubagent"],
|
|
14731
|
+
["memory_consolidation", "historyMemory"],
|
|
14732
|
+
["review", "historyReview"],
|
|
14733
|
+
["composer", "historyComposer"],
|
|
14734
|
+
["automation", "historyAutomation"]
|
|
14735
|
+
]);
|
|
14736
|
+
const day = (value) => new Date(value).toLocaleDateString(uiLocale(), {
|
|
14737
|
+
month: "numeric",
|
|
14738
|
+
day: "numeric"
|
|
14739
|
+
});
|
|
14740
|
+
const amount = (value) => value > 0 && value < .1 ? "<0.1" : (value >= 10 ? Math.round(value) : Math.round(value * 10) / 10).toLocaleString(uiLocale());
|
|
14741
|
+
const labelOf = (dimension, key, t) => dimension === "model" ? key : LABELS.has(key) ? t(LABELS.get(key)) : key.replaceAll("_", " ");
|
|
14742
|
+
function Rows({ dimension, rows, total, t }) {
|
|
14743
|
+
const top = Math.max(total, ...rows.map((row) => row.percent));
|
|
14744
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
14745
|
+
className: "codexSubscriptionHistoryGroup",
|
|
14746
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", { children: t(`historyBy_${dimension}`) }), rows.toSorted((a, b) => b.percent - a.percent).map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
14747
|
+
className: "codexSubscriptionHistoryRow",
|
|
14748
|
+
children: [
|
|
14749
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
14750
|
+
className: "codexSubscriptionHistoryKey",
|
|
14751
|
+
children: labelOf(dimension, row.key, t)
|
|
14752
|
+
}),
|
|
14753
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("progress", {
|
|
14754
|
+
max: top,
|
|
14755
|
+
value: row.percent,
|
|
14756
|
+
"aria-label": `${labelOf(dimension, row.key, t)} ${amount(row.percent)}%`
|
|
14757
|
+
}),
|
|
14758
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("strong", { children: [amount(row.percent), "%"] })
|
|
14759
|
+
]
|
|
14760
|
+
}, row.key))]
|
|
14761
|
+
});
|
|
14762
|
+
}
|
|
14763
|
+
function UsageHistory({ rpc, t, signedIn, resetKey }) {
|
|
14764
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
14765
|
+
const [state, setState] = (0, react.useState)({ status: "idle" });
|
|
14766
|
+
const [selected, setSelected] = (0, react.useState)(0);
|
|
14767
|
+
const request = (0, react.useRef)(0);
|
|
14768
|
+
(0, react.useEffect)(() => {
|
|
14769
|
+
request.current += 1;
|
|
14770
|
+
setState({ status: "idle" });
|
|
14771
|
+
setSelected(0);
|
|
14772
|
+
}, [signedIn, resetKey]);
|
|
14773
|
+
(0, react.useEffect)(() => {
|
|
14774
|
+
if (!open || !signedIn || state.status !== "idle") return;
|
|
14775
|
+
const id = ++request.current;
|
|
14776
|
+
setState({ status: "loading" });
|
|
14777
|
+
recoveryCall(rpc, "usage/history", {}).then((value) => {
|
|
14778
|
+
if (request.current === id) setState({
|
|
14779
|
+
status: "ready",
|
|
14780
|
+
value
|
|
14781
|
+
});
|
|
14782
|
+
}).catch((error) => {
|
|
14783
|
+
if (request.current === id) setState({
|
|
14784
|
+
status: "error",
|
|
14785
|
+
message: error.message
|
|
14786
|
+
});
|
|
14787
|
+
});
|
|
14788
|
+
}, [
|
|
14789
|
+
open,
|
|
14790
|
+
signedIn,
|
|
14791
|
+
state.status,
|
|
14792
|
+
rpc
|
|
14793
|
+
]);
|
|
14794
|
+
if (!signedIn) return null;
|
|
14795
|
+
const value = state.value;
|
|
14796
|
+
const periods = (value?.periods ?? []).filter((period) => period.usedPercent !== void 0);
|
|
14797
|
+
const period = periods[Math.min(selected, Math.max(0, periods.length - 1))];
|
|
14798
|
+
const present = DIMENSIONS.filter((dimension) => period?.breakdowns?.[dimension]?.length > 0);
|
|
14799
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
14800
|
+
className: "codexSubscriptionHistory",
|
|
14801
|
+
onToggle: (event) => setOpen(event.currentTarget.open),
|
|
14802
|
+
children: [
|
|
14803
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t("historyTitle") }),
|
|
14804
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
14805
|
+
"aria-live": "polite",
|
|
14806
|
+
children: [
|
|
14807
|
+
state.status === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14808
|
+
className: "codexSubscriptionEmpty",
|
|
14809
|
+
role: "status",
|
|
14810
|
+
children: t("historyLoading")
|
|
14811
|
+
}) : null,
|
|
14812
|
+
state.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14813
|
+
className: "codexSubscriptionError",
|
|
14814
|
+
role: "alert",
|
|
14815
|
+
children: state.message
|
|
14816
|
+
}) : null,
|
|
14817
|
+
state.status === "ready" && value.available === false ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14818
|
+
className: "codexSubscriptionEmpty",
|
|
14819
|
+
role: "status",
|
|
14820
|
+
children: t("historyUnavailable")
|
|
14821
|
+
}) : null,
|
|
14822
|
+
state.status === "ready" && value.available !== false && period === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14823
|
+
className: "codexSubscriptionEmpty",
|
|
14824
|
+
role: "status",
|
|
14825
|
+
children: t("historyEmpty")
|
|
14826
|
+
}) : null
|
|
14827
|
+
]
|
|
14828
|
+
}),
|
|
14829
|
+
period === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
14830
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
14831
|
+
className: "codexSubscriptionHistoryPeriods",
|
|
14832
|
+
role: "group",
|
|
14833
|
+
"aria-label": t("historyPeriods"),
|
|
14834
|
+
children: periods.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
14835
|
+
type: "button",
|
|
14836
|
+
"aria-pressed": item === period,
|
|
14837
|
+
onClick: () => setSelected(index),
|
|
14838
|
+
children: `${day(item.startsAt)}–${day(item.endsAt)}`
|
|
14839
|
+
}, item.startsAt))
|
|
14840
|
+
}),
|
|
14841
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
14842
|
+
className: "codexSubscriptionHistorySummary",
|
|
14843
|
+
children: [fill(t("historyUsed"), { value: amount(period.usedPercent) }), period.complete ? "" : ` ${t("historyPartial")}`]
|
|
14844
|
+
}),
|
|
14845
|
+
present.map((dimension) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Rows, {
|
|
14846
|
+
dimension,
|
|
14847
|
+
rows: period.breakdowns[dimension],
|
|
14848
|
+
total: period.usedPercent,
|
|
14849
|
+
t
|
|
14850
|
+
}, dimension)),
|
|
14851
|
+
value.approximate ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
14852
|
+
className: "codexSubscriptionCreditNote",
|
|
14853
|
+
children: t("historyApproximate")
|
|
14854
|
+
}) : null
|
|
14855
|
+
] })
|
|
14856
|
+
]
|
|
14857
|
+
});
|
|
14858
|
+
}
|
|
14859
|
+
//#endregion
|
|
14133
14860
|
//#region src/client-usage.jsx
|
|
14134
14861
|
const count = (value) => Number(value).toLocaleString();
|
|
14135
14862
|
const creditAmount = (value) => Number.isFinite(Number(value)) && String(value).trim() !== "" ? Number(value).toLocaleString(void 0, { maximumFractionDigits: 2 }) : value;
|
|
@@ -14495,6 +15222,18 @@ window.__ModuleLoader__.load({
|
|
|
14495
15222
|
]
|
|
14496
15223
|
}, `${limit.id}-${window.windowSeconds}-${index}`)))
|
|
14497
15224
|
}),
|
|
15225
|
+
limits.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageOverview, {
|
|
15226
|
+
rpc,
|
|
15227
|
+
t,
|
|
15228
|
+
signedIn,
|
|
15229
|
+
resetKey
|
|
15230
|
+
}),
|
|
15231
|
+
limits.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageHistory, {
|
|
15232
|
+
rpc,
|
|
15233
|
+
t,
|
|
15234
|
+
signedIn,
|
|
15235
|
+
resetKey
|
|
15236
|
+
}),
|
|
14498
15237
|
visibleUsage?.chatPass === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
14499
15238
|
className: "codexSubscriptionLimits",
|
|
14500
15239
|
children: visibleUsage.chatPass.windows.map((window, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|