@bitkyc08/opencodex 2.75.0 → 2.76.0
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.md +6 -1
- package/bin/ocx.mjs +12 -1
- package/gui/dist/assets/App-CddorHdA.js +51 -0
- package/gui/dist/assets/App-DMudtISW.css +1 -0
- package/gui/dist/assets/{Tray-CGAD2AGk.js → Tray-DjNwwrWS.js} +1 -1
- package/gui/dist/assets/index-Btze1I3T.css +1 -0
- package/gui/dist/assets/index-CvnY7E6i.js +86 -0
- package/gui/dist/assets/quota-summary-B_AWpHfP.js +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/opengateway.svg +12 -0
- package/package.json +1 -1
- package/src/adapters/anthropic/account-metadata.ts +17 -0
- package/src/adapters/anthropic/client-identity.ts +69 -0
- package/src/adapters/anthropic/passthrough.ts +23 -4
- package/src/adapters/anthropic.ts +18 -1
- package/src/adapters/command-code-project-context.ts +7 -11
- package/src/adapters/devin/cloud-direct/tool-schema.ts +12 -48
- package/src/adapters/kiro-retry.ts +23 -8
- package/src/adapters/openai-chat/messages.ts +1 -1
- package/src/adapters/registry.ts +8 -1
- package/src/adapters/zed.ts +377 -0
- package/src/bridge/sse.ts +4 -2
- package/src/chatgpt/app-server-shim/app-server-rewrite.ts +45 -0
- package/src/chatgpt/app-server-shim/bundle-trust.ts +77 -0
- package/src/chatgpt/app-server-shim/filter.ts +157 -0
- package/src/chatgpt/app-server-shim/gate-rewrite.ts +99 -0
- package/src/chatgpt/app-server-shim/launcher.ts +91 -0
- package/src/claude/desktop-3p-startup.ts +62 -0
- package/src/claude/desktop-3p.ts +5 -0
- package/src/claude/first-party-settings.ts +14 -0
- package/src/claude/intercept/cli-catalog.ts +150 -0
- package/src/claude/intercept/cli-picker.ts +82 -0
- package/src/claude/intercept/listener.ts +21 -6
- package/src/claude/intercept/picker-bootstrap.ts +23 -5
- package/src/claude/intercept/picker-models.ts +57 -13
- package/src/claude/intercept/runtime.ts +30 -2
- package/src/claude/intercept/settings.ts +3 -0
- package/src/cli/agent.ts +172 -0
- package/src/cli/alias.ts +2 -1
- package/src/cli/capabilities-command.ts +3 -2
- package/src/cli/capabilities.ts +87 -0
- package/src/cli/chatgpt-command.ts +140 -0
- package/src/cli/combo.ts +144 -19
- package/src/cli/config-command.ts +3 -1
- package/src/cli/dispatch.ts +10 -1
- package/src/cli/help.ts +1 -0
- package/src/cli/index.ts +5 -24
- package/src/cli/init.ts +16 -2
- package/src/cli/integrations.ts +13 -0
- package/src/cli/internal-command.ts +12 -5
- package/src/cli/observe.ts +6 -1
- package/src/cli/registry.ts +6 -0
- package/src/cli/route-policy.ts +3 -1
- package/src/cli/runtime-api.ts +5 -2
- package/src/cli/status-oauth.ts +5 -0
- package/src/cli/status.ts +8 -1
- package/src/cli/stop-approval.ts +55 -16
- package/src/cli/stop-report.ts +5 -0
- package/src/clients/lazycodex.ts +48 -0
- package/src/clients/omo-role-models.ts +111 -0
- package/src/codex/account-credit-use.ts +99 -0
- package/src/codex/account-lifecycle.ts +2 -0
- package/src/codex/agent-role-models.ts +171 -0
- package/src/codex/auth-api/account-list.ts +10 -3
- package/src/codex/auth-api/routes.ts +34 -0
- package/src/codex/auth-context.ts +52 -11
- package/src/codex/catalog/discovered-natives.ts +11 -1
- package/src/codex/catalog/gather-capture.ts +6 -1
- package/src/codex/catalog/model-hints.ts +9 -1
- package/src/codex/catalog/provider-models.ts +60 -0
- package/src/codex/catalog/routed-gather.ts +30 -5
- package/src/codex/convergence-types.ts +2 -1
- package/src/codex/main-account-external-usage.ts +62 -0
- package/src/codex/main-account-hard-lock.ts +24 -13
- package/src/codex/native-profile-processes.ts +53 -16
- package/src/codex/prompt-layers/toml-edit.ts +1 -1
- package/src/codex/quota-types.ts +3 -7
- package/src/codex/quota.ts +19 -4
- package/src/codex/role-auto-assign.ts +159 -0
- package/src/codex/role-sizing-limits.ts +2 -0
- package/src/codex/role-sizing.ts +216 -0
- package/src/codex/routing/selection.ts +36 -0
- package/src/codex/routing/thread-affinity.ts +2 -0
- package/src/codex/routing.ts +4 -4
- package/src/codex/subagent-model-fallback.ts +82 -26
- package/src/codex/subagent-selectable-models.ts +32 -0
- package/src/combos/index.ts +18 -0
- package/src/combos/jev-decision-contract.ts +20 -0
- package/src/combos/jev-dispatch.ts +18 -0
- package/src/combos/jev-model-backend.ts +127 -0
- package/src/combos/jev.ts +249 -33
- package/src/combos/types.ts +125 -2
- package/src/config/diagnostics.ts +18 -0
- package/src/config/macos-system-proxy.ts +72 -15
- package/src/config/owner-registry.ts +13 -4
- package/src/config/process-state.ts +17 -8
- package/src/config/proxy-env.ts +35 -5
- package/src/config/schema/config-schema.ts +30 -1
- package/src/config/schema/leaf-validators.ts +4 -0
- package/src/config/serving-runtimes.ts +95 -1
- package/src/generated/compatibility-version.json +336 -156
- package/src/lib/errors.ts +7 -7
- package/src/lib/jsonc.ts +13 -0
- package/src/lib/local-chat-completion.ts +144 -0
- package/src/lib/provider-outbound.ts +87 -1
- package/src/lib/provider-runtime-fetch.ts +23 -0
- package/src/lib/provider-tls-profile.ts +221 -0
- package/src/lib/request-execution-budget.ts +16 -6
- package/src/lib/spend-reservation-ledger.ts +54 -20
- package/src/lib/sse-decoder.ts +20 -17
- package/src/lib/synced-state-location.ts +96 -0
- package/src/lib/winsw.ts +14 -5
- package/src/oauth/anthropic-account-refusal.ts +53 -4
- package/src/oauth/anthropic-model-quota.ts +83 -0
- package/src/oauth/anthropic-rate-limit-policy.ts +37 -0
- package/src/oauth/anthropic-routing.ts +112 -58
- package/src/oauth/health.ts +39 -3
- package/src/oauth/index.ts +14 -0
- package/src/oauth/kiro-account-load.ts +10 -0
- package/src/oauth/zed.ts +134 -0
- package/src/providers/model-discovery.ts +19 -8
- package/src/providers/model-rename-fields.ts +1 -0
- package/src/providers/provider-id-rewrite.ts +9 -2
- package/src/providers/quota/account-cache.ts +29 -7
- package/src/providers/quota/anthropic-cooldown-recovery.ts +18 -0
- package/src/providers/quota/anthropic-family-headers.ts +25 -0
- package/src/providers/quota/vendor-probes-oauth.ts +5 -1
- package/src/providers/quota-types.ts +4 -0
- package/src/providers/registry/entries-core.ts +18 -0
- package/src/providers/registry/entries-extended.ts +55 -0
- package/src/providers/registry/types.ts +3 -0
- package/src/providers/xai-fast-model.ts +12 -4
- package/src/providers/zed.ts +598 -0
- package/src/responses/state/snapshot-select.ts +22 -9
- package/src/responses/state.ts +2 -3
- package/src/router.ts +9 -0
- package/src/server/anthropic-rate-limit-headers.ts +7 -0
- package/src/server/auth-cors.ts +7 -0
- package/src/server/chat-completions.ts +9 -4
- package/src/server/claude-messages.ts +59 -21
- package/src/server/index/claude-intercept-lifecycle.ts +71 -25
- package/src/server/index/optional-listeners.ts +4 -0
- package/src/server/index/spend-ledger-lifecycle.ts +4 -0
- package/src/server/management/agent-settings-routes.ts +74 -37
- package/src/server/management/claude-desktop-picker-routes.ts +7 -0
- package/src/server/management/claude-intercept-routes.ts +35 -0
- package/src/server/management/codex-agent-role-routes.ts +122 -0
- package/src/server/management/codex-role-auto-assign.ts +208 -0
- package/src/server/management/combo-routes.ts +62 -5
- package/src/server/management/config-routes.ts +35 -3
- package/src/server/management/context.ts +4 -1
- package/src/server/management/decision-discovery.ts +74 -0
- package/src/server/management/decision-model-validation.ts +80 -0
- package/src/server/management/decision-routes.ts +160 -0
- package/src/server/management/native-integration-routes.ts +16 -0
- package/src/server/management/provider-routes.ts +30 -34
- package/src/server/management/route-registry.ts +12 -0
- package/src/server/management/sibling-guard.ts +1 -0
- package/src/server/management/zed-provider-probe.ts +38 -0
- package/src/server/management-api.ts +12 -1
- package/src/server/messages-native-oauth.ts +7 -2
- package/src/server/messages-native.ts +7 -3
- package/src/server/relay.ts +3 -1
- package/src/server/request-log.ts +2 -0
- package/src/server/responses/adapter-continuation.ts +3 -3
- package/src/server/responses/adapter-dispatch.ts +18 -3
- package/src/server/responses/compact.ts +14 -1
- package/src/server/responses/core-auth.ts +2 -0
- package/src/server/responses/core-combo.ts +67 -11
- package/src/server/responses/core-normalize.ts +21 -1
- package/src/server/responses/core-options.ts +11 -1
- package/src/server/responses/core.ts +5 -3
- package/src/server/responses/fetch-helpers.ts +6 -3
- package/src/server/responses/jev-model-invoke.ts +190 -0
- package/src/server/responses/passthrough-delivery.ts +16 -0
- package/src/server/responses/policy-fallback.ts +55 -3
- package/src/server/responses/policy-request-scope.ts +80 -0
- package/src/server/responses/request-prepare.ts +70 -18
- package/src/server/responses/request-transport.ts +54 -23
- package/src/server/responses/run-turn-execution.ts +1 -0
- package/src/server/responses/sidecar-execution.ts +9 -3
- package/src/server/responses-hosted-image-display.ts +225 -0
- package/src/service/managing-cli.ts +34 -4
- package/src/service/systemd-env.ts +75 -0
- package/src/service/windows-guarded-manager.ts +60 -19
- package/src/service/windows-scheduler.ts +22 -3
- package/src/service/windows-taskxml.ts +32 -10
- package/src/service-manager-probe.ts +72 -19
- package/src/types/config.ts +31 -1
- package/src/types/provider.ts +2 -0
- package/src/types/request.ts +2 -0
- package/src/update/index.ts +39 -6
- package/src/update/job.ts +63 -63
- package/src/update/npm-cache-preflight.d.mts +33 -1
- package/src/update/npm-cache-preflight.mjs +131 -18
- package/src/update/ownership-transaction.ts +19 -1
- package/src/update/restart-ownership.ts +80 -6
- package/src/update/transactional-install.d.mts +2 -0
- package/src/update/transactional-install.mjs +6 -1
- package/src/usage/jev-stats.ts +28 -1
- package/src/usage/log.ts +1 -1
- package/src/vision/anthropic-describe.ts +5 -3
- package/src/vision/index.ts +1 -0
- package/src/vision/plan.ts +2 -1
- package/src/vision/routed-describe.ts +29 -121
- package/src/web-search/alpha-search.ts +3 -3
- package/src/web-search/anthropic-executor.ts +6 -4
- package/src/web-search/index.ts +1 -1
- package/src/web-search/loop.ts +3 -3
- package/src/web-search/passthrough-bridge.ts +2 -1
- package/src/web-search/run-turn-loop.ts +1 -1
- package/src/web-search/sidecar-providers.ts +2 -1
- package/gui/dist/assets/App-ia4U0ufY.css +0 -1
- package/gui/dist/assets/App-xm0zGNOe.js +0 -51
- package/gui/dist/assets/index-DBT3Q31Y.css +0 -1
- package/gui/dist/assets/index-D_RGAT6Q.js +0 -86
- package/gui/dist/assets/quota-summary-CUFq48t-.js +0 -1
|
@@ -19,18 +19,13 @@
|
|
|
19
19
|
* admission secret in a forwardable header is a forwarding hazard). Loopback
|
|
20
20
|
* binds require no token at all (resolveApiAuth admits loopback).
|
|
21
21
|
*
|
|
22
|
-
* Destination (#4236)
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* loopback") is closed by resolving through `localInferenceDestination`
|
|
26
|
-
* rather than composing 127.0.0.1 by hand.
|
|
22
|
+
* Destination (#4236) and transport: postLocalChatCompletion in
|
|
23
|
+
* src/lib/local-chat-completion.ts, which resolves the unauthenticated
|
|
24
|
+
* loopback listener when one is enabled and otherwise the BIND address.
|
|
27
25
|
*/
|
|
28
26
|
import type { OcxConfig } from "../types";
|
|
29
|
-
import { localAdmissionToken
|
|
30
|
-
import {
|
|
31
|
-
import { redactSecretString } from "../lib/redact";
|
|
32
|
-
import { sidecarEnter } from "../lib/sidecar-tracker";
|
|
33
|
-
import { configuredPort } from "../server/auth-cors";
|
|
27
|
+
import { localAdmissionToken } from "../lib/local-destinations";
|
|
28
|
+
import { localChatCompletionBaseUrl, postLocalChatCompletion } from "../lib/local-chat-completion";
|
|
34
29
|
import type { DescribeOutcome, VisionSettings } from "./describe";
|
|
35
30
|
|
|
36
31
|
export const VISION_DESCRIBE_TERMINAL_HEADER = "x-opencodex-vision-describe";
|
|
@@ -77,28 +72,7 @@ export function routedDescribeAdmissionToken(config: Pick<OcxConfig, "apiKeys">)
|
|
|
77
72
|
export function routedDescribeBaseUrl(
|
|
78
73
|
config: Pick<OcxConfig, "port" | "hostname" | "unauthenticatedLoopbackListener">,
|
|
79
74
|
): string {
|
|
80
|
-
return
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* The local destination this self-fetch dials, and whether it needs a credential.
|
|
85
|
-
*
|
|
86
|
-
* This is a local client like any other: the unauthenticated loopback listener when one is
|
|
87
|
-
* enabled, otherwise the bind address — on a tailnet-bound hub there is no loopback socket at
|
|
88
|
-
* all (#4236). The helper sends the OpenAI chat wire, which that listener now admits.
|
|
89
|
-
*/
|
|
90
|
-
function routedDescribeDestination(
|
|
91
|
-
config: Pick<OcxConfig, "port" | "hostname" | "unauthenticatedLoopbackListener">,
|
|
92
|
-
) {
|
|
93
|
-
// config.port can be 0 (ephemeral bind, tests) or stale after a live port override; the
|
|
94
|
-
// server records its ACTUAL bound port via setCorsOrigin at startup, so prefer that when
|
|
95
|
-
// config carries no positive port. `configuredPort()` is itself `0` when `_corsOrigin` has no
|
|
96
|
-
// explicit port (a default-port origin), so the literal default has to backstop it or the
|
|
97
|
-
// composed URL names port 0 and the self-fetch cannot connect.
|
|
98
|
-
const port = config.port && config.port > 0
|
|
99
|
-
? config.port
|
|
100
|
-
: Number(configuredPort()) || 10_100;
|
|
101
|
-
return localInferenceDestination(config, port);
|
|
75
|
+
return localChatCompletionBaseUrl(config);
|
|
102
76
|
}
|
|
103
77
|
|
|
104
78
|
export async function describeImageRouted(
|
|
@@ -114,93 +88,27 @@ export async function describeImageRouted(
|
|
|
114
88
|
const invalid = validateImageUrl(imageUrl);
|
|
115
89
|
if (invalid) return { text: "", error: invalid };
|
|
116
90
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
content: [
|
|
141
|
-
...(contextText ? [{ type: "text", text: `User's request context: ${contextText}` }] : []),
|
|
142
|
-
{ type: "image_url", image_url: { url: imageUrl } },
|
|
143
|
-
],
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const linkedSignal = signalWithTimeout(settings.timeoutMs, abortSignal);
|
|
149
|
-
const sidecarExit = sidecarEnter("vision");
|
|
150
|
-
const t0 = Date.now();
|
|
151
|
-
try {
|
|
152
|
-
const res = await fetch(`${baseUrlOverride ?? routedDescribeBaseUrl(config)}/v1/chat/completions`, {
|
|
153
|
-
method: "POST",
|
|
154
|
-
headers,
|
|
155
|
-
body: JSON.stringify(requestBody),
|
|
156
|
-
signal: linkedSignal.signal,
|
|
157
|
-
redirect: "manual",
|
|
158
|
-
});
|
|
159
|
-
const detachBodyGuard = cancelBodyOnAbort(res.body, linkedSignal.signal);
|
|
160
|
-
try {
|
|
161
|
-
const raw = await res.text();
|
|
162
|
-
if (raw.length > MAX_ROUTED_RESPONSE_BYTES) {
|
|
163
|
-
return { text: "", error: "routed describe response exceeded byte bound" };
|
|
164
|
-
}
|
|
165
|
-
if (!res.ok) {
|
|
166
|
-
return { text: "", error: `routed describe HTTP ${res.status}: ${redactSecretString(raw.slice(0, 200))}` };
|
|
167
|
-
}
|
|
168
|
-
let payload: unknown;
|
|
169
|
-
try { payload = JSON.parse(raw); } catch {
|
|
170
|
-
return { text: "", error: "routed describe returned non-JSON" };
|
|
171
|
-
}
|
|
172
|
-
const content = extractChatContent(payload);
|
|
173
|
-
if (!content) return { text: "", error: "routed describe returned no text" };
|
|
174
|
-
return { text: content };
|
|
175
|
-
} finally {
|
|
176
|
-
detachBodyGuard();
|
|
177
|
-
}
|
|
178
|
-
} catch (e) {
|
|
179
|
-
const kind = e instanceof Error && e.name === "TimeoutError" ? "timeout" : "connect_error";
|
|
180
|
-
console.warn(`[vision] routed describe ${kind} (${Date.now() - t0}ms)`);
|
|
181
|
-
return { text: "", error: redactSecretString(e instanceof Error ? e.message : String(e)) };
|
|
182
|
-
} finally {
|
|
183
|
-
sidecarExit();
|
|
184
|
-
linkedSignal.cleanup();
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function extractChatContent(payload: unknown): string | undefined {
|
|
189
|
-
if (!payload || typeof payload !== "object") return undefined;
|
|
190
|
-
const choices = (payload as { choices?: unknown }).choices;
|
|
191
|
-
if (!Array.isArray(choices) || choices.length === 0) return undefined;
|
|
192
|
-
const message = (choices[0] as { message?: unknown })?.message;
|
|
193
|
-
if (!message || typeof message !== "object") return undefined;
|
|
194
|
-
const content = (message as { content?: unknown }).content;
|
|
195
|
-
if (typeof content === "string" && content.trim().length > 0) return content;
|
|
196
|
-
// Some adapters emit content parts; join text parts.
|
|
197
|
-
if (Array.isArray(content)) {
|
|
198
|
-
const joined = content
|
|
199
|
-
.map(part => (part && typeof part === "object" && typeof (part as { text?: unknown }).text === "string"
|
|
200
|
-
? (part as { text: string }).text
|
|
201
|
-
: ""))
|
|
202
|
-
.join("");
|
|
203
|
-
if (joined.trim().length > 0) return joined;
|
|
204
|
-
}
|
|
205
|
-
return undefined;
|
|
91
|
+
return postLocalChatCompletion({
|
|
92
|
+
config,
|
|
93
|
+
label: "routed describe",
|
|
94
|
+
logTag: "vision",
|
|
95
|
+
timeoutMs: settings.timeoutMs,
|
|
96
|
+
maxResponseBytes: MAX_ROUTED_RESPONSE_BYTES,
|
|
97
|
+
headers: { [VISION_DESCRIBE_TERMINAL_HEADER]: "1" },
|
|
98
|
+
abortSignal,
|
|
99
|
+
baseUrlOverride,
|
|
100
|
+
body: {
|
|
101
|
+
model: routedModel,
|
|
102
|
+
messages: [
|
|
103
|
+
{ role: "system", content: DESCRIBE_INSTRUCTION },
|
|
104
|
+
{
|
|
105
|
+
role: "user",
|
|
106
|
+
content: [
|
|
107
|
+
...(contextText ? [{ type: "text", text: `User's request context: ${contextText}` }] : []),
|
|
108
|
+
{ type: "image_url", image_url: { url: imageUrl } },
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
});
|
|
206
114
|
}
|
|
@@ -62,7 +62,7 @@ const DEFAULT_BACKEND_MODELS = {
|
|
|
62
62
|
export type AlphaSearchSidecarBackend = keyof typeof DEFAULT_BACKEND_MODELS;
|
|
63
63
|
|
|
64
64
|
type ResolvedAlphaSearchSidecar =
|
|
65
|
-
| { backend: "anthropic"; providerName: string; provider: OcxProviderConfig }
|
|
65
|
+
| { backend: "anthropic"; providerName: string; provider: OcxProviderConfig; config: OcxConfig }
|
|
66
66
|
| { backend: "xai"; providerName: string; provider: OcxProviderConfig }
|
|
67
67
|
| { backend: "gemini"; providerName: string; provider: OcxProviderConfig }
|
|
68
68
|
| { backend: "exa"; apiKey: string };
|
|
@@ -103,7 +103,7 @@ export function resolveAlphaSearchSidecar(config: OcxConfig): AlphaSearchSidecar
|
|
|
103
103
|
case "anthropic": {
|
|
104
104
|
const found = findAnthropicSidecarProvider(config);
|
|
105
105
|
return found
|
|
106
|
-
? { status: "ready", sidecar: { backend, providerName: found.providerName, provider: found.provider } }
|
|
106
|
+
? { status: "ready", sidecar: { backend, providerName: found.providerName, provider: found.provider, config } }
|
|
107
107
|
: { status: "missing-credential", backend };
|
|
108
108
|
}
|
|
109
109
|
case "xai": {
|
|
@@ -188,7 +188,7 @@ async function runAlphaSearchQuery(
|
|
|
188
188
|
): Promise<SidecarOutcome> {
|
|
189
189
|
switch (resolved.backend) {
|
|
190
190
|
case "anthropic":
|
|
191
|
-
return runAnthropicWebSearch(query, resolved.providerName, resolved.provider, settings, signal);
|
|
191
|
+
return runAnthropicWebSearch(query, resolved.providerName, resolved.provider, settings, signal, config);
|
|
192
192
|
case "xai":
|
|
193
193
|
return runXaiWebSearch(
|
|
194
194
|
query,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { OcxProviderConfig } from "../types";
|
|
2
|
-
import {
|
|
1
|
+
import type { OcxConfig, OcxProviderConfig } from "../types";
|
|
2
|
+
import { publicOAuthAuthenticationErrorMessage } from "../oauth";
|
|
3
|
+
import { getAnthropicSidecarAccessToken } from "../oauth/anthropic-routing";
|
|
3
4
|
import { ANTHROPIC_OAUTH_BETA, CLAUDE_CODE_SYSTEM_INSTRUCTION } from "../oauth/anthropic";
|
|
4
5
|
import { sidecarThinkingOff } from "../adapters/anthropic-model-contract";
|
|
5
6
|
import { CLAUDE_CODE_HEADERS, claudeCodeSessionId } from "../adapters/client-fingerprint";
|
|
@@ -153,7 +154,7 @@ export async function parseAnthropicSidecarSSE(res: Response): Promise<SidecarOu
|
|
|
153
154
|
|
|
154
155
|
/**
|
|
155
156
|
* Execute ONE web search via a Claude sidecar through the STORED anthropic OAuth credential — the
|
|
156
|
-
* Anthropic-backed analog of runWebSearch.
|
|
157
|
+
* Anthropic-backed analog of runWebSearch. Resolves the helper model's permitted account (refresh handled)
|
|
157
158
|
* and reproduces the Claude Code OAuth fingerprint (identity system block first, oauth beta, client
|
|
158
159
|
* headers, stable session id) so the request is first-party-shaped. Never throws — returns `{error}`
|
|
159
160
|
* so the caller injects a graceful tool result.
|
|
@@ -164,12 +165,13 @@ export async function runAnthropicWebSearch(
|
|
|
164
165
|
provider: OcxProviderConfig,
|
|
165
166
|
settings: SidecarSettings,
|
|
166
167
|
abortSignal?: AbortSignal,
|
|
168
|
+
config?: OcxConfig,
|
|
167
169
|
): Promise<SidecarOutcome> {
|
|
168
170
|
const base = provider.baseUrl.replace(/\/v1\/?$/, "");
|
|
169
171
|
const url = `${base}/v1/messages`;
|
|
170
172
|
let token: string;
|
|
171
173
|
try {
|
|
172
|
-
token = await
|
|
174
|
+
token = await getAnthropicSidecarAccessToken(providerName, settings.model, config);
|
|
173
175
|
} catch (e) {
|
|
174
176
|
return { text: "", sources: [], error: `anthropic sidecar auth failed: ${publicOAuthAuthenticationErrorMessage(e)}` };
|
|
175
177
|
}
|
package/src/web-search/index.ts
CHANGED
|
@@ -170,7 +170,7 @@ export function planWebSearch(
|
|
|
170
170
|
// resolveSidecarBackend's explicit-or-openai contract.
|
|
171
171
|
const auth = resolveSidecarAuth(config);
|
|
172
172
|
const anthropicSidecar = auth.isAnthropicAuth && auth.anthropicProviderName && auth.anthropicProvider
|
|
173
|
-
? { providerName: auth.anthropicProviderName, provider: auth.anthropicProvider }
|
|
173
|
+
? { providerName: auth.anthropicProviderName, provider: auth.anthropicProvider, config }
|
|
174
174
|
: undefined;
|
|
175
175
|
const backend = resolveSidecarBackend(cfg.backend);
|
|
176
176
|
const maxSearches = cfg.maxSearchesPerTurn ?? DEFAULT_MAX_SEARCHES;
|
package/src/web-search/loop.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AdapterRequest, IncomingMeta, ProviderAdapter } from "../adapters/base";
|
|
2
|
-
import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderConfig, OcxProviderOpaqueToolCallMetadata, OcxThinkingContent, OcxUsage, RateLimitRetryPolicy } from "../types";
|
|
2
|
+
import type { AdapterEvent, OcxConfig, OcxMessage, OcxParsedRequest, OcxProviderConfig, OcxProviderOpaqueToolCallMetadata, OcxThinkingContent, OcxUsage, RateLimitRetryPolicy } from "../types";
|
|
3
3
|
import { namespacedToolName, toolChoiceToolPredicate } from "../types";
|
|
4
4
|
import { cloneProviderOpaqueToolCallMetadata } from "../responses/provider-opaque-metadata";
|
|
5
5
|
import type { AttemptRecoveryKind } from "../usage/log";
|
|
@@ -282,7 +282,7 @@ export interface WebSearchLoopDeps {
|
|
|
282
282
|
/** Required for the openai backend; unused (and typically undefined) for the anthropic backend. */
|
|
283
283
|
forwardProvider?: OcxProviderConfig;
|
|
284
284
|
/** Required for the anthropic backend: the stored-OAuth provider that runs web_search_20250305. */
|
|
285
|
-
anthropicSidecar?: { providerName: string; provider: OcxProviderConfig };
|
|
285
|
+
anthropicSidecar?: { providerName: string; provider: OcxProviderConfig; config: OcxConfig };
|
|
286
286
|
/** Required for the xai backend: the stored Grok OAuth provider (L7). */
|
|
287
287
|
xaiSidecar?: { providerName: string; provider: OcxProviderConfig };
|
|
288
288
|
/** Required for the gemini backend: the stored Antigravity CCA provider (L8). */
|
|
@@ -743,7 +743,7 @@ export async function runWithWebSearch(deps: WebSearchLoopDeps): Promise<Respons
|
|
|
743
743
|
// signal would otherwise look like an ordinary degradable failure).
|
|
744
744
|
try {
|
|
745
745
|
if (backend === "anthropic" && anthropicSidecar) {
|
|
746
|
-
outcome = await runAnthropicWebSearch(query, anthropicSidecar.providerName, anthropicSidecar.provider, settings, signal);
|
|
746
|
+
outcome = await runAnthropicWebSearch(query, anthropicSidecar.providerName, anthropicSidecar.provider, settings, signal, anthropicSidecar.config);
|
|
747
747
|
} else if (backend === "xai") {
|
|
748
748
|
// L7: stored Grok OAuth to the pinned api.x.ai Responses endpoint; same
|
|
749
749
|
// never-throws contract and no Codex/OpenAI pool outcome recording (F5 parity).
|
|
@@ -232,7 +232,7 @@ export function resolveOllamaWebSearchEndpoint(
|
|
|
232
232
|
/** Credentials that may run a non-Ollama passthrough-bridge search. The key never rides the plan. */
|
|
233
233
|
export interface PassthroughWebSearchBridgeAuth {
|
|
234
234
|
openAiSidecar?: ResolvedOpenAiForwardSidecar;
|
|
235
|
-
anthropic?: { providerName: string; provider: OcxProviderConfig };
|
|
235
|
+
anthropic?: { providerName: string; provider: OcxProviderConfig; config: OcxConfig };
|
|
236
236
|
xai?: { providerName: string; provider: OcxProviderConfig };
|
|
237
237
|
gemini?: { providerName: string; provider: OcxProviderConfig };
|
|
238
238
|
exaApiKey?: string;
|
|
@@ -967,6 +967,7 @@ export function createPassthroughWebSearchBridgeExecutor(
|
|
|
967
967
|
anthropic.provider,
|
|
968
968
|
settings,
|
|
969
969
|
querySignal,
|
|
970
|
+
anthropic.config,
|
|
970
971
|
);
|
|
971
972
|
}
|
|
972
973
|
case "xai": {
|
|
@@ -262,7 +262,7 @@ export async function* runTurnWebSearchLoop(
|
|
|
262
262
|
switch (plan.backend) {
|
|
263
263
|
case "anthropic":
|
|
264
264
|
return plan.anthropicSidecar
|
|
265
|
-
? await runAnthropicWebSearch(query, plan.anthropicSidecar.providerName, plan.anthropicSidecar.provider, plan.settings, signal)
|
|
265
|
+
? await runAnthropicWebSearch(query, plan.anthropicSidecar.providerName, plan.anthropicSidecar.provider, plan.settings, signal, plan.anthropicSidecar.config)
|
|
266
266
|
: { text: "", sources: [], error: "anthropic backend selected without a resolved sidecar provider" };
|
|
267
267
|
case "xai":
|
|
268
268
|
return plan.xaiSidecar
|
|
@@ -35,6 +35,7 @@ export function resolveSidecarBackend(
|
|
|
35
35
|
export interface AnthropicSidecarProvider {
|
|
36
36
|
providerName: string;
|
|
37
37
|
provider: OcxProviderConfig;
|
|
38
|
+
config: OcxConfig;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
/**
|
|
@@ -48,7 +49,7 @@ export interface AnthropicSidecarProvider {
|
|
|
48
49
|
export function findAnthropicSidecarProvider(config: OcxConfig): AnthropicSidecarProvider | undefined {
|
|
49
50
|
const auth = resolveSidecarAuth(config);
|
|
50
51
|
if (!auth.isAnthropicAuth || !auth.anthropicProviderName || !auth.anthropicProvider) return undefined;
|
|
51
|
-
return { providerName: auth.anthropicProviderName, provider: auth.anthropicProvider };
|
|
52
|
+
return { providerName: auth.anthropicProviderName, provider: auth.anthropicProvider, config };
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
/**
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.codex-account-controls{flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:12px;min-width:0;display:flex}.codex-account-auto-switch{flex:none;align-items:center;gap:7px;min-width:0;display:flex}.codex-account-auto-switch-label{font-size:var(--text-label);color:var(--muted);font-weight:var(--weight-medium);white-space:nowrap}.codex-account-auto-switch-input-wrap{align-items:stretch;display:inline-flex;position:relative}.codex-account-auto-switch-input{width:76px;height:30px;font-size:var(--text-label);text-align:right;padding:4px 38px 4px 8px}.codex-account-auto-switch-unit{color:var(--muted);font-size:var(--text-label);pointer-events:none;position:absolute;top:50%;right:25px;transform:translateY(-50%)}.codex-account-auto-switch-input-wrap .ocx-stepper{width:22px}.codex-account-auto-switch-toggle{transform-origin:50%;margin-inline:-3px;transform:scale(.8)}.quota-row--codex-credits .quota-val{white-space:nowrap}.quota-compact:has(>.quota-row--codex-credits){grid-template-columns:minmax(34px,max-content) max-content minmax(34px,max-content) minmax(38px,max-content) minmax(58px,1fr) minmax(30px,max-content);column-gap:8px}.quota-compact:has(>.quota-row--codex-credits)>*{grid-column:1/-1}.quota-compact:has(>.quota-row--codex-credits)>.quota-row:not(.quota-row--credits){grid-template-columns:subgrid}.codex-auth-credits-toggle{align-items:center;gap:var(--space-2);white-space:nowrap;display:inline-flex}.codex-auth-credits-toggle__label{font-size:var(--text-label);color:var(--muted)}.kiro-device-dialog{max-width:var(--prose-measure);border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--surface);width:100%;color:var(--text);padding:var(--space-6)}.kiro-device-dialog::backdrop{background:var(--glass-rail)}.kiro-login-choices{gap:var(--space-2);margin-block:var(--space-4);display:grid}.kiro-login-choices .btn{min-height:var(--control-touch);justify-content:flex-start}.kiro-device-code{align-items:center;gap:var(--space-3);margin-block:var(--space-4);flex-wrap:wrap;display:flex}.kiro-device-code-value{font-family:var(--font-code);font-size:var(--text-title);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-wide)}.kiro-device-destination{overflow-wrap:anywhere;-webkit-user-select:all;user-select:all}.kiro-device-actions{justify-content:flex-end;gap:var(--space-2);margin-top:var(--space-4);display:flex}.remote-link-page{gap:var(--space-4);display:grid}.remote-link-page .page-head{align-items:flex-start}.remote-link-page .page-sub{max-width:var(--prose-measure);margin:0}.remote-link-panel{gap:var(--space-4);display:grid}.remote-link-off-preview{min-height:260px;position:relative;overflow:hidden}.remote-link-off-preview:after{content:"";pointer-events:none;-webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);background:color-mix(in srgb, var(--bg) 24%, transparent);position:absolute;inset:0}.remote-link-preview-content{gap:var(--space-3);filter:grayscale();opacity:.64;-webkit-user-select:none;user-select:none;display:grid}.remote-link-preview-row{justify-content:space-between;align-items:center;gap:var(--space-3);padding:var(--space-3);border:1px solid var(--border-soft);border-radius:var(--radius-sm);background:var(--raised);display:flex}.remote-link-preview-lines{gap:var(--space-2);width:min(55%,300px);display:grid}.remote-link-preview-lines span{border-radius:var(--radius-pill);background:var(--border);height:8px;display:block}.remote-link-switch-row{z-index:1;justify-content:space-between;align-items:center;gap:var(--space-4);display:flex;position:relative}.remote-link-switch{width:var(--control-touch);height:var(--control-md);border:1px solid var(--border);border-radius:var(--radius-pill);background:var(--toggle-off-bg);cursor:pointer;padding:3px}.remote-link-switch:after{content:"";background:var(--toggle-dot-color);width:24px;height:24px;transition:transform var(--motion-fast) ease;border-radius:50%;display:block}.remote-link-switch[aria-checked=true]{background:var(--toggle-on-bg)}.remote-link-switch[aria-checked=true]:after{transform:translate(16px)}.remote-link-switch:focus-visible,.remote-link-role-card:focus-visible,.remote-link-sheet button:focus-visible,.remote-link-row button:focus-visible{outline:2px solid var(--accent-ring);outline-offset:2px}.remote-link-role-grid{gap:var(--space-3);grid-template-columns:repeat(2,minmax(0,1fr));display:grid}.remote-link-role-card{min-height:132px;padding:var(--space-4);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--raised);color:var(--text);text-align:left;cursor:pointer}.remote-link-role-card:hover{background:var(--raised-hover)}.remote-link-role-card[aria-disabled=true]{color:var(--muted);cursor:not-allowed;opacity:.72}.remote-link-role-card[aria-disabled=true]:hover{background:var(--raised)}.remote-link-role-card[aria-checked=true]{border-color:var(--text);box-shadow:0 0 0 1px var(--text)}.remote-link-role-card strong,.remote-link-role-card span{display:block}.remote-link-role-card span{margin-top:var(--space-2);color:var(--muted);font-size:var(--text-label)}.remote-link-toolbar{justify-content:space-between;align-items:center;gap:var(--space-3);display:flex}.remote-link-status{align-items:center;gap:var(--space-2);color:var(--muted);font-size:var(--text-label);display:inline-flex}.remote-link-status:before{content:"";background:var(--faint);border-radius:50%;flex:none;width:8px;height:8px}.remote-link-status[data-state=connected]:before{background:var(--green)}.remote-link-status[data-state=reconnecting]:before{background:var(--amber)}.remote-link-status[data-state=failed]:before{background:var(--red)}.remote-link-status[data-state=connecting]:before{background:var(--amber)}.remote-link-children{gap:var(--space-2);display:grid}.remote-link-row{gap:var(--space-3);padding:var(--space-3);border:1px solid var(--border-soft);border-radius:var(--radius-sm);background:var(--raised);grid-template-columns:minmax(0,1fr) auto;align-items:center;display:grid}.remote-link-row-main{gap:var(--space-2);min-width:0;display:grid}.remote-link-row-meta{gap:var(--space-3);color:var(--muted);font-size:var(--text-caption);flex-wrap:wrap;display:flex}.remote-link-row .btn{min-height:var(--control-touch)}.remote-link-error{color:var(--red)}.remote-link-hint{margin-top:var(--space-1);color:var(--muted);font-size:var(--text-label);overflow-wrap:anywhere;display:block}.remote-link-info{color:var(--muted);font-size:var(--text-label)}.remote-link-restart{gap:var(--space-2);padding:var(--space-4);border:1px solid var(--border-soft);border-radius:var(--radius-sm);background:var(--raised);display:grid}.remote-link-restart p{color:var(--muted);margin:0}.remote-link-fingerprint{padding:var(--space-3);overflow-wrap:anywhere;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--raised);font-family:var(--font-code);font-size:var(--text-label);margin:0}.remote-link-workspace-card{justify-content:space-between;align-items:center;gap:var(--space-4);display:flex}.remote-link-workspace-card p{margin:var(--space-1) 0 0;color:var(--muted);font-size:var(--text-label)}.remote-link-sheet{width:min(620px, calc(100vw - var(--space-4)));max-height:min(760px, calc(100dvh - var(--space-4)));padding:var(--space-6);border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg);color:var(--text);box-shadow:var(--shadow);margin:auto;overflow:auto}.remote-link-sheet::backdrop{background:color-mix(in srgb, var(--text) 24%, transparent)}.remote-link-sheet-head{justify-content:space-between;align-items:flex-start;gap:var(--space-3);display:flex}.remote-link-sheet-head h3{font-size:var(--text-title);margin:0}.remote-link-sheet-body{gap:var(--space-4);margin-top:var(--space-5);display:grid}.remote-link-candidates{gap:var(--space-2);display:grid}.remote-link-candidate{justify-content:space-between;align-items:center;gap:var(--space-3);min-height:var(--control-touch);padding:var(--space-2) var(--space-3);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--raised);color:var(--text);cursor:pointer;text-align:left;display:flex}.remote-link-candidate:hover{background:var(--raised-hover)}.remote-link-form{gap:var(--space-2);display:grid}.remote-link-form .field-label{margin-bottom:0}.remote-link-sheet-actions{justify-content:flex-end;gap:var(--space-2);flex-wrap:wrap;display:flex}.remote-link-confirm-dialog{width:min(460px, calc(100vw - var(--space-4)));padding:var(--space-5);border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);color:var(--text);box-shadow:var(--shadow);margin:auto}.remote-link-confirm-dialog::backdrop{background:color-mix(in srgb, var(--text) 24%, transparent)}.remote-link-confirm-dialog h3{font-size:var(--text-subtitle);margin:0}.remote-link-confirm-dialog p{color:var(--muted)}@media (width<=620px){.remote-link-role-grid{grid-template-columns:1fr}.remote-link-workspace-card,.remote-link-switch-row{flex-direction:column;align-items:stretch}.remote-link-switch{align-self:flex-start}.remote-link-sheet{width:calc(100vw - var(--space-2));border-radius:var(--radius-lg) var(--radius-lg) 0 0;max-height:88dvh;margin:auto auto 0}}@media (prefers-reduced-motion:reduce){.remote-link-page *,.remote-link-page :before,.remote-link-page :after{scroll-behavior:auto!important;transition:none!important;animation:none!important}}.quota-summary-bar{z-index:var(--z-sticky);border-bottom:1px solid var(--border);background:var(--bg);min-height:34px;font-size:var(--text-label);align-items:center;gap:12px;padding:4px 16px;display:flex;position:sticky;top:0}.quota-summary-scroller{flex:1;align-items:center;gap:2px;min-width:0;display:flex}.quota-summary-list{overscroll-behavior-x:contain;scrollbar-width:none;flex-wrap:nowrap;flex:auto;align-items:center;gap:4px;min-width:0;margin:0;padding:3px;list-style:none;display:flex;overflow:auto hidden}.quota-summary-list::-webkit-scrollbar{display:none}.quota-summary-item{flex:none}.quota-summary-scroll{border:1px solid var(--border);background:var(--surface);width:22px;height:22px;color:var(--text);font:inherit;cursor:pointer;border-radius:999px;flex:none;place-items:center;padding:0;font-weight:600;line-height:1;display:inline-grid}.quota-summary-scroll:hover:not([aria-disabled=true]){background:var(--bg)}.quota-summary-scroll[aria-disabled=true]{color:var(--muted);opacity:.45;cursor:default}.quota-summary-scroll:focus-visible{outline:2px solid var(--text);outline-offset:1px}.quota-summary-chip{color:var(--text);font:inherit;white-space:nowrap;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:999px;align-items:center;gap:6px;padding:3px 8px;text-decoration:none;display:inline-flex}.quota-summary-chip:hover,.quota-summary-chip--open{border-color:var(--border)}.quota-summary-chip:focus-visible{outline:2px solid var(--text);outline-offset:1px}.quota-summary-name{color:var(--muted)}.quota-summary-pct{font-variant-numeric:tabular-nums;font-weight:600}.quota-summary-flag{width:14px;height:14px;color:var(--bg);font-size:var(--text-micro);border-radius:50%;place-items:center;font-weight:700;display:inline-grid}.quota-summary-item--warn .quota-summary-chip{background:var(--amber-soft)}.quota-summary-item--warn .quota-summary-pct{color:var(--amber)}.quota-summary-item--warn .quota-summary-flag{background:var(--amber)}.quota-summary-item--critical .quota-summary-chip{border-color:var(--red);background:var(--red-soft)}.quota-summary-item--critical .quota-summary-pct{color:var(--red)}.quota-summary-item--critical .quota-summary-flag{background:var(--red)}.quota-summary-popover{top:calc(var(--qs-pop-top,0) * 1px);left:calc(var(--qs-pop-left,0) * 1px);z-index:var(--z-popover);border:1px solid var(--border);background:var(--surface);border-radius:8px;min-width:260px;max-width:calc(100% - 16px);padding:10px 12px;position:fixed;box-shadow:0 8px 24px #00000024}.quota-summary-popover:before{content:"";left:calc(var(--qs-bridge-left,0) * 1px - 1px);right:calc(var(--qs-bridge-right,0) * 1px - 1px);height:calc((var(--qs-pop-gap,4) + 1) * 1px);position:absolute;bottom:100%}.quota-summary-popover-head{justify-content:space-between;align-items:center;gap:12px;margin-bottom:6px;display:flex}.quota-summary-badge{font-size:var(--text-caption);border-radius:999px;padding:1px 6px}.quota-summary-badge--warn{color:var(--amber);background:var(--amber-soft)}.quota-summary-badge--critical{color:var(--red);background:var(--red-soft)}.quota-summary-table{border-collapse:collapse;width:100%}.quota-summary-table th,.quota-summary-table td{text-align:left;white-space:nowrap;padding:3px 0;font-weight:400}.quota-summary-table td.quota-summary-row-pct{font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;padding:3px 12px;font-weight:600}.quota-summary-row-reset{color:var(--muted);white-space:nowrap}.quota-summary-table th[scope=row]{white-space:normal;overflow-wrap:anywhere}.quota-summary-row--warn .quota-summary-row-pct{color:var(--amber)}.quota-summary-row--critical .quota-summary-row-pct{color:var(--red)}.quota-summary-popover-foot{color:var(--muted);font-size:var(--text-caption);flex-wrap:wrap;justify-content:space-between;gap:4px 12px;margin-top:6px;display:flex}.quota-summary-updated{color:var(--muted);font-size:var(--text-caption);white-space:nowrap;flex-shrink:0}.quota-summary-popover-link{color:var(--text);text-underline-offset:2px;text-decoration:underline}.quota-summary-popover-link:focus-visible{outline:2px solid var(--text);outline-offset:1px}.quota-summary-updated--stale{color:var(--amber)}.main:has(>.quota-summary-bar):has(>.main-inner--combos .combos-workspace-shell){flex-direction:column;height:100dvh;display:flex}.main:has(>.quota-summary-bar)>.main-inner.main-inner--combos:has(.combos-workspace-shell){flex:auto;height:auto;min-height:0}@media (width<=760px){.quota-summary-bar{padding:4px 10px;position:static}.quota-summary-popover{top:calc(var(--qs-pop-top,0) * 1px);min-width:0;left:8px;right:8px}.main:has(>.quota-summary-bar):has(>.main-inner--combos .combos-workspace-shell){height:100%;min-height:0}}.app{--titlebar-h:40px;--tl-inset:80px;--chrome-clear:52px}.app--macos{--chrome-clear:124px;--sidebar-column:max(232px, calc(var(--tl-inset) + 52px))}.sidebar-top{z-index:calc(var(--z-overlay,30) + 1);width:232px;height:var(--titlebar-h,40px);border-bottom:1px solid var(--border);background:var(--glass-rail);-webkit-backdrop-filter:var(--glass-blur);-webkit-user-select:none;user-select:none;align-items:center;padding:0 10px 0 14px;display:flex;position:fixed;top:0;left:0}.app--macos .sidebar-top{width:var(--sidebar-column);padding-left:var(--tl-inset,80px)}.sidebar{padding-top:calc(var(--titlebar-h,40px) + 18px)}.sidebar-collapse{border-radius:var(--radius-sm);width:28px;height:28px;color:var(--muted);cursor:pointer;transition:background var(--motion-fast), color var(--motion-fast);background:0 0;border:none;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.sidebar-collapse:hover{background:var(--accent-soft);color:var(--text)}.sidebar-collapse:focus-visible{outline:2px solid var(--accent-ring);outline-offset:2px}.sidebar-collapse svg{width:18px;height:18px}.main-top{z-index:var(--z-sticky);height:var(--titlebar-h,40px);background:var(--bg);border-bottom:1px solid var(--border);-webkit-user-select:none;user-select:none;align-items:stretch;display:flex;position:sticky;top:0}.main-top>.quota-summary-bar{border-bottom:none;flex:auto;min-width:0;min-height:0;padding:0 16px;position:static}.main:has(>.main-top):has(>.main-inner--combos .combos-workspace-shell){flex-direction:column;height:100dvh;display:flex}.main:has(>.main-top)>.main-inner.main-inner--combos:has(.combos-workspace-shell){flex:auto;height:auto;min-height:0}@media (width>=761px){.app{transition:grid-template-columns .16s}.app--macos.app--reduced-zoom{transition:none}.app--macos:not(.app--nav-collapsed){grid-template-columns:var(--sidebar-column) minmax(0, 1fr)}.app.app--nav-collapsed{grid-template-columns:0 1fr}.app--nav-collapsed .sidebar{display:none}.app--nav-collapsed .main{grid-column:2}.app--nav-collapsed .sidebar-top{-webkit-backdrop-filter:none;background:0 0;border-bottom:none;width:auto;margin:0;padding:0 12px}.app--macos.app--nav-collapsed .sidebar-top{padding-left:var(--tl-inset,80px)}.app--nav-collapsed .main-top,.app--nav-collapsed .main>.quota-summary-bar{padding-left:var(--chrome-clear,52px)}}@media (width<=760px){.sidebar-top{display:none}.main-top{z-index:auto;position:static}.main:has(>.main-top):has(>.main-inner--combos .combos-workspace-shell){height:100%;min-height:0}.app--macos .mobile-topbar{padding-left:var(--tl-inset,80px)}.app--macos .sidebar.open{padding-top:calc(var(--titlebar-h,40px) + 18px)}}@media (width<=320px){.app--macos .mobile-topbar{flex-wrap:wrap}.app--macos .mobile-topbar-actions{width:calc(100% + var(--tl-inset,80px));margin-left:calc(-1 * var(--tl-inset,80px));justify-content:flex-end}}
|