@eddyskywalker/dsh-chatgpt-subscription 0.11.7 → 0.12.1
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/CHANGELOG.md +11 -0
- package/README.md +34 -2
- package/lib/client.js +125 -4
- package/lib/client.js.map +1 -1
- package/lib/index.js +349 -19
- package/lib/types/client/CodexSubscriptionSection.d.ts +18 -0
- package/lib/types/client/CodexSubscriptionSection.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +45 -5
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/host/antigravity/mapper.d.ts +3 -2
- package/lib/types/host/antigravity/mapper.d.ts.map +1 -1
- package/lib/types/host/antigravity/tool-schema.d.ts +13 -1
- package/lib/types/host/antigravity/tool-schema.d.ts.map +1 -1
- package/lib/types/host/claude/mapper.d.ts +57 -3
- package/lib/types/host/claude/mapper.d.ts.map +1 -1
- package/lib/types/host/codex-fetch.d.ts.map +1 -1
- package/lib/types/host/fetch-address-policy.d.ts +2 -1
- package/lib/types/host/fetch-address-policy.d.ts.map +1 -1
- package/lib/types/host/fetch-configuration.d.ts +6 -0
- package/lib/types/host/fetch-configuration.d.ts.map +1 -0
- package/lib/types/host/routes.d.ts +2 -2
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/host/search-provider-switcher.d.ts +2 -0
- package/lib/types/host/search-provider-switcher.d.ts.map +1 -1
- package/lib/types/index.d.ts +7 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/contracts.d.ts +11 -0
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -2984,6 +2984,24 @@ var CodexAccountPool = class extends AccountPoolCore {
|
|
|
2984
2984
|
}
|
|
2985
2985
|
};
|
|
2986
2986
|
//#endregion
|
|
2987
|
+
//#region src/host/fetch-configuration.ts
|
|
2988
|
+
const DEFAULT_FETCH_MAX_BODY_CHARS = 1e5;
|
|
2989
|
+
const DEFAULT_FETCH_MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
2990
|
+
function positiveFetchLimit(value, fallback, name) {
|
|
2991
|
+
const resolved = value === void 0 ? fallback : value;
|
|
2992
|
+
if (!Number.isSafeInteger(resolved) || resolved < 1) throw new Error(`${name} must be a positive safe integer.`);
|
|
2993
|
+
return resolved;
|
|
2994
|
+
}
|
|
2995
|
+
function resolveFetchConfiguration(config) {
|
|
2996
|
+
const fetchProvider = config.fetchProvider ?? "auto";
|
|
2997
|
+
if (fetchProvider !== "auto" && fetchProvider !== "plugin" && fetchProvider !== "dsh") throw new Error("fetchProvider must be auto, plugin, or dsh.");
|
|
2998
|
+
return {
|
|
2999
|
+
fetchProvider,
|
|
3000
|
+
fetchMaxBodyChars: positiveFetchLimit(config.fetchMaxBodyChars, DEFAULT_FETCH_MAX_BODY_CHARS, "fetchMaxBodyChars"),
|
|
3001
|
+
fetchMaxResponseBytes: positiveFetchLimit(config.fetchMaxResponseBytes, DEFAULT_FETCH_MAX_RESPONSE_BYTES, "fetchMaxResponseBytes")
|
|
3002
|
+
};
|
|
3003
|
+
}
|
|
3004
|
+
//#endregion
|
|
2987
3005
|
//#region src/host/fetch-address-policy.ts
|
|
2988
3006
|
/**
|
|
2989
3007
|
* Destination policy for this plugin's fetch provider.
|
|
@@ -3001,7 +3019,8 @@ var CodexAccountPool = class extends AccountPoolCore {
|
|
|
3001
3019
|
* proxy on this machine must not become a path into loopback or a LAN — and it
|
|
3002
3020
|
* also refuses a name this machine resolves into private space. Only the proxy's
|
|
3003
3021
|
* own fake-ip answers are accepted, since that is what the proxy's name
|
|
3004
|
-
* resolution looks like from here
|
|
3022
|
+
* resolution looks like from here: the IPv4 one, and the IPv6 one only beside it
|
|
3023
|
+
* (see assertPublicFetchTarget). The URL hostname still reaches the proxy
|
|
3005
3024
|
* intact, so the proxy decides where the name really goes.
|
|
3006
3025
|
*
|
|
3007
3026
|
* @module dsh-chatgpt-subscription/fetch-address-policy
|
|
@@ -3114,11 +3133,22 @@ function isNonPublicIpLiteral(hostname) {
|
|
|
3114
3133
|
*/
|
|
3115
3134
|
function assertPublicFetchTarget(hostname, addresses) {
|
|
3116
3135
|
if (isNonPublicIpLiteral(hostname)) throw new WebError(`URL hostname "${hostname}" is not a public IP address`, "WEB_BLOCKED_URL");
|
|
3136
|
+
const claimedByProxy = addresses.some(isProxyFakeIpAddress);
|
|
3117
3137
|
for (const address of addresses) {
|
|
3118
3138
|
if (isPublicIpAddress(address) || isProxyFakeIpAddress(address)) continue;
|
|
3139
|
+
if (claimedByProxy && isUnassignedUniqueLocal(address)) continue;
|
|
3119
3140
|
throw new WebError(`URL hostname "${hostname}" resolves to a non-public IP address`, "WEB_BLOCKED_URL");
|
|
3120
3141
|
}
|
|
3121
3142
|
}
|
|
3143
|
+
/**
|
|
3144
|
+
* Whether an IPv6 address is inside fc00::/8: the unique-local half RFC 4193
|
|
3145
|
+
* leaves unassigned (real unique-local networks are numbered from fd00::/8), and
|
|
3146
|
+
* where proxies place their IPv6 fake-ip range.
|
|
3147
|
+
*/
|
|
3148
|
+
function isUnassignedUniqueLocal(address) {
|
|
3149
|
+
const words = ipv6Words(unbracket(address));
|
|
3150
|
+
return words !== void 0 && (words[0] ?? 0) >> 8 === 252;
|
|
3151
|
+
}
|
|
3122
3152
|
/** Whether a dotted quad is public, using {@link NON_PUBLIC_IPV4}. */
|
|
3123
3153
|
function isPublicIpv4(address) {
|
|
3124
3154
|
const value = ipv4Value(address);
|
|
@@ -3204,12 +3234,10 @@ function unbracket(hostname) {
|
|
|
3204
3234
|
}
|
|
3205
3235
|
//#endregion
|
|
3206
3236
|
//#region src/host/codex-fetch.ts
|
|
3207
|
-
const DEFAULT_MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
3208
|
-
const DEFAULT_MAX_BODY_CHARS = 1e5;
|
|
3209
3237
|
function createCodexFetchProvider(options = {}) {
|
|
3210
3238
|
const fetchFn = options.fetchFn ?? fetch;
|
|
3211
|
-
const maxResponseBytes = options.maxResponseBytes
|
|
3212
|
-
const maxBodyChars = options.maxBodyChars
|
|
3239
|
+
const maxResponseBytes = positiveFetchLimit(options.maxResponseBytes, DEFAULT_FETCH_MAX_RESPONSE_BYTES, "maxResponseBytes");
|
|
3240
|
+
const maxBodyChars = positiveFetchLimit(options.maxBodyChars, DEFAULT_FETCH_MAX_BODY_CHARS, "maxBodyChars");
|
|
3213
3241
|
const resolveHostAddresses = options.resolveHostAddresses ?? lookupHostAddresses;
|
|
3214
3242
|
return {
|
|
3215
3243
|
id: CODEX_FETCH_PROVIDER_ID,
|
|
@@ -7363,7 +7391,7 @@ function identityKey(credentials) {
|
|
|
7363
7391
|
//#endregion
|
|
7364
7392
|
//#region src/host/routes.ts
|
|
7365
7393
|
const MAX_BODY_BYTES$6 = 64 * 1024;
|
|
7366
|
-
function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher, routeAudit, accountPool) {
|
|
7394
|
+
function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher, routeAudit, accountPool, fetchConfiguration) {
|
|
7367
7395
|
const handler = async (request, response) => {
|
|
7368
7396
|
const url = new URL(request.url ?? "/", "http://dsh.local");
|
|
7369
7397
|
if (request.method === "GET" && url.pathname === `/api/dsh-chatgpt-subscription/status`) {
|
|
@@ -7378,7 +7406,8 @@ function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwit
|
|
|
7378
7406
|
preferences: preferences.status(),
|
|
7379
7407
|
detectedProxy: proxyManager?.getSystemProxy() ?? null,
|
|
7380
7408
|
activeProxy: proxyManager?.resolveActiveProxyUrl() ?? null,
|
|
7381
|
-
switcher: searchSwitcher?.status() ?? null
|
|
7409
|
+
switcher: searchSwitcher?.status() ?? null,
|
|
7410
|
+
fetchConfiguration
|
|
7382
7411
|
}
|
|
7383
7412
|
});
|
|
7384
7413
|
return;
|
|
@@ -7790,10 +7819,13 @@ var SearchProviderSwitcher = class {
|
|
|
7790
7819
|
}
|
|
7791
7820
|
const codexSelected = preference === SEARCH_PROVIDER_CODEX;
|
|
7792
7821
|
const nextSearch = codexSelected ? CODEX_SEARCH_PROVIDER_ID : this.originalSearchProvider;
|
|
7793
|
-
const nextFetch = codexSelected || options.pluginFetch === true ? CODEX_FETCH_PROVIDER_ID : this.originalFetchProvider;
|
|
7822
|
+
const nextFetch = options.fetchProvider === "plugin" || options.fetchProvider !== "dsh" && (codexSelected || options.pluginFetch === true) ? CODEX_FETCH_PROVIDER_ID : this.originalFetchProvider;
|
|
7794
7823
|
const configured = config.searchProvider === nextSearch && config.fetchProvider === nextFetch;
|
|
7795
7824
|
const applied = running === void 0 || running.searchProvider === nextSearch && running.fetchProvider === nextFetch;
|
|
7796
|
-
if (configured && applied)
|
|
7825
|
+
if (configured && applied) {
|
|
7826
|
+
this.state = "applied";
|
|
7827
|
+
return;
|
|
7828
|
+
}
|
|
7797
7829
|
const nextConfig = { ...config };
|
|
7798
7830
|
if (nextSearch === void 0) delete nextConfig.searchProvider;
|
|
7799
7831
|
else nextConfig.searchProvider = nextSearch;
|
|
@@ -8562,7 +8594,170 @@ function mergeSchemas(left, right) {
|
|
|
8562
8594
|
if (Array.isArray(left.required) && Array.isArray(right.required)) merged.required = [.../* @__PURE__ */ new Set([...left.required, ...right.required])];
|
|
8563
8595
|
return merged;
|
|
8564
8596
|
}
|
|
8565
|
-
|
|
8597
|
+
/** Value constraints a branch summary reports, in a stable order. */
|
|
8598
|
+
const constraintFields = [
|
|
8599
|
+
"format",
|
|
8600
|
+
"pattern",
|
|
8601
|
+
"minimum",
|
|
8602
|
+
"maximum",
|
|
8603
|
+
"minLength",
|
|
8604
|
+
"maxLength",
|
|
8605
|
+
"minItems",
|
|
8606
|
+
"maxItems",
|
|
8607
|
+
"minProperties",
|
|
8608
|
+
"maxProperties"
|
|
8609
|
+
];
|
|
8610
|
+
/** Keys the same-type union merge below represents rather than drops. */
|
|
8611
|
+
const mergedTypeKeys = /* @__PURE__ */ new Set([
|
|
8612
|
+
"type",
|
|
8613
|
+
"enum",
|
|
8614
|
+
"nullable",
|
|
8615
|
+
"description",
|
|
8616
|
+
...constraintFields
|
|
8617
|
+
]);
|
|
8618
|
+
/**
|
|
8619
|
+
* One alternative in the words a model can act on.
|
|
8620
|
+
*
|
|
8621
|
+
* Folding removes the branch from the schema itself, so this text carries the
|
|
8622
|
+
* branch description and its constraints too: the type alone would leave the
|
|
8623
|
+
* model with strictly less than the schema it started from.
|
|
8624
|
+
*/
|
|
8625
|
+
function describeBranch(branch) {
|
|
8626
|
+
const type = typeof branch.type === "string" ? branch.type : isRecord$22(branch.properties) ? "object" : isRecord$22(branch.items) ? "array" : "value";
|
|
8627
|
+
const details = [];
|
|
8628
|
+
if (isRecord$22(branch.properties)) {
|
|
8629
|
+
const names = Object.keys(branch.properties);
|
|
8630
|
+
if (names.length > 0) details.push(`{${names.join(",")}}`);
|
|
8631
|
+
}
|
|
8632
|
+
if (Array.isArray(branch.required) && branch.required.length > 0) details.push(`requires ${branch.required.map(String).join(",")}`);
|
|
8633
|
+
if (Array.isArray(branch.enum)) details.push(`enum[${branch.enum.map((value) => JSON.stringify(value)).join(",")}]`);
|
|
8634
|
+
for (const field of constraintFields) if (branch[field] !== void 0) details.push(`${field}=${JSON.stringify(branch[field])}`);
|
|
8635
|
+
if (branch.nullable === true) details.push("or null");
|
|
8636
|
+
const summary = details.length > 0 ? `${type} ${details.join(" ")}` : type;
|
|
8637
|
+
const description = typeof branch.description === "string" ? branch.description.trim() : "";
|
|
8638
|
+
return description === "" ? summary : `${summary} — "${description}"`;
|
|
8639
|
+
}
|
|
8640
|
+
/** How well one branch can stand in for a whole union; a named object shape wins. */
|
|
8641
|
+
function branchRank(branch) {
|
|
8642
|
+
if (isRecord$22(branch.properties)) return 3;
|
|
8643
|
+
if (branch.type === "object") return 2;
|
|
8644
|
+
if (branch.type === "array") return 1;
|
|
8645
|
+
return 0;
|
|
8646
|
+
}
|
|
8647
|
+
/**
|
|
8648
|
+
* The one JSON Schema type a literal set declares, when it declares exactly one.
|
|
8649
|
+
*
|
|
8650
|
+
* Read from the caller's literals, never from the wire's stringified `enum`: a
|
|
8651
|
+
* `{ const: 5 }` branch is a number, and `String(5)` alone cannot say so.
|
|
8652
|
+
*/
|
|
8653
|
+
function literalType(values) {
|
|
8654
|
+
const kinds = new Set(values.map((value) => typeof value));
|
|
8655
|
+
if (kinds.size !== 1) return void 0;
|
|
8656
|
+
const [kind] = kinds;
|
|
8657
|
+
return kind === "string" || kind === "number" || kind === "boolean" ? kind : void 0;
|
|
8658
|
+
}
|
|
8659
|
+
/**
|
|
8660
|
+
* The single form the wire can declare for a set of union branches.
|
|
8661
|
+
*
|
|
8662
|
+
* `folded` is false only when the declared form carries every constraint the
|
|
8663
|
+
* branches between them declared; once a constraint is only in the description,
|
|
8664
|
+
* the fold says so instead of passing a partial restatement off as the union.
|
|
8665
|
+
*/
|
|
8666
|
+
function unionShape(branches) {
|
|
8667
|
+
if (branches.length === 1) return {
|
|
8668
|
+
shape: branches[0],
|
|
8669
|
+
folded: false
|
|
8670
|
+
};
|
|
8671
|
+
if (new Set(branches.map((branch) => branch.type)).size === 1 && branches.every((branch) => !isRecord$22(branch.properties) && !isRecord$22(branch.items))) {
|
|
8672
|
+
const shape = { type: branches[0].type };
|
|
8673
|
+
if (branches.every((branch) => Array.isArray(branch.enum))) {
|
|
8674
|
+
const values = [...new Set(branches.flatMap((branch) => branch.enum))];
|
|
8675
|
+
if (values.length > 0) shape.enum = values;
|
|
8676
|
+
}
|
|
8677
|
+
if (branches.some((branch) => branch.nullable === true)) shape.nullable = true;
|
|
8678
|
+
return {
|
|
8679
|
+
shape,
|
|
8680
|
+
folded: branches.some((branch) => Object.entries(branch).some(([key, value]) => !mergedTypeKeys.has(key) && !Object.is(shape[key], value)))
|
|
8681
|
+
};
|
|
8682
|
+
}
|
|
8683
|
+
return {
|
|
8684
|
+
shape: branches.reduce((best, branch) => branchRank(branch) > branchRank(best) ? branch : best),
|
|
8685
|
+
folded: true
|
|
8686
|
+
};
|
|
8687
|
+
}
|
|
8688
|
+
/** Append the folded union to whatever description the node already carried. */
|
|
8689
|
+
function withUnionHint(description, hint) {
|
|
8690
|
+
const base = typeof description === "string" ? description.trim() : "";
|
|
8691
|
+
return base === "" ? hint : `${base}\n\n${hint}`;
|
|
8692
|
+
}
|
|
8693
|
+
function unionHint(alternatives, declared) {
|
|
8694
|
+
const text = `Union of accepted forms: ${alternatives.map(describeBranch).join(" | ")}.`;
|
|
8695
|
+
return declared === void 0 ? text : `${text} Send "${describeBranch(declared)}": this gateway validates the declared form only, and the alternatives describe the original tool contract.`;
|
|
8696
|
+
}
|
|
8697
|
+
/**
|
|
8698
|
+
* One node's own fields, children folded, composition keys set aside.
|
|
8699
|
+
*
|
|
8700
|
+
* `anyOf`, `oneOf` and `allOf` are keywords only in these positions: a parameter
|
|
8701
|
+
* NAMED `anyOf` is data, so recursion goes through `properties` by name and never
|
|
8702
|
+
* reads a property key as a keyword.
|
|
8703
|
+
*/
|
|
8704
|
+
function foldOwnFields(node) {
|
|
8705
|
+
const out = {};
|
|
8706
|
+
for (const [key, value] of Object.entries(node)) {
|
|
8707
|
+
if (key === "anyOf" || key === "oneOf" || key === "allOf") continue;
|
|
8708
|
+
if (key === "properties" && isRecord$22(value)) {
|
|
8709
|
+
out.properties = Object.fromEntries(Object.entries(value).map(([name, child]) => [name, foldSchemaUnions(child)]));
|
|
8710
|
+
continue;
|
|
8711
|
+
}
|
|
8712
|
+
if (key === "items") {
|
|
8713
|
+
out.items = foldSchemaUnions(value);
|
|
8714
|
+
continue;
|
|
8715
|
+
}
|
|
8716
|
+
out[key] = value;
|
|
8717
|
+
}
|
|
8718
|
+
return out;
|
|
8719
|
+
}
|
|
8720
|
+
/**
|
|
8721
|
+
* Replace every composition keyword in one already-converted schema with a
|
|
8722
|
+
* single declared form, moving what folding drops into `description`.
|
|
8723
|
+
*
|
|
8724
|
+
* This runs after {@link toAntigravityToolSchema} resolved references and merged
|
|
8725
|
+
* `allOf`, so it is one pass over the wire shape and no second sanitizer can
|
|
8726
|
+
* strip the hint it just wrote.
|
|
8727
|
+
*
|
|
8728
|
+
* Folding NARROWS the wire contract: preferring the object branch leaves the
|
|
8729
|
+
* schema declaring an object, so a caller that would have sent the string form
|
|
8730
|
+
* now sends against a schema that does not mention it. That is the only way
|
|
8731
|
+
* past a gateway that refuses a composed schema outright, and the description
|
|
8732
|
+
* keeps the dropped forms visible as the original tool contract rather than
|
|
8733
|
+
* silently erasing them. DSH's own tool validator is the real gate: an
|
|
8734
|
+
* argument the model sends anyway fails there, naming the actual problem.
|
|
8735
|
+
*/
|
|
8736
|
+
function foldSchemaUnions(node) {
|
|
8737
|
+
if (!isRecord$22(node)) return node;
|
|
8738
|
+
let own = foldOwnFields(node);
|
|
8739
|
+
if (Array.isArray(node.allOf)) for (const branch of node.allOf) {
|
|
8740
|
+
const folded = foldSchemaUnions(branch);
|
|
8741
|
+
if (isRecord$22(folded)) own = mergeSchemas(own, folded);
|
|
8742
|
+
}
|
|
8743
|
+
const alternatives = Array.isArray(node.anyOf) ? node.anyOf : Array.isArray(node.oneOf) ? node.oneOf : [];
|
|
8744
|
+
if (alternatives.length === 0) return own;
|
|
8745
|
+
const branches = alternatives.map((branch) => foldSchemaUnions(branch)).filter(isRecord$22);
|
|
8746
|
+
if (branches.length === 0) return own;
|
|
8747
|
+
const shapes = branches.filter((branch) => branch.type !== "null");
|
|
8748
|
+
const acceptsNull = branches.some((branch) => branch.type === "null");
|
|
8749
|
+
if (shapes.length === 0) {
|
|
8750
|
+
const onlyNull = mergeSchemas({ nullable: true }, own);
|
|
8751
|
+
onlyNull.description = withUnionHint(own.description, unionHint(branches, { nullable: true }));
|
|
8752
|
+
return onlyNull;
|
|
8753
|
+
}
|
|
8754
|
+
const { shape, folded } = unionShape(shapes);
|
|
8755
|
+
const merged = mergeSchemas(shape, own);
|
|
8756
|
+
if (acceptsNull) merged.nullable = true;
|
|
8757
|
+
if (branches.length > 1) merged.description = withUnionHint(merged.description, unionHint(branches, folded ? shape : void 0));
|
|
8758
|
+
return merged;
|
|
8759
|
+
}
|
|
8760
|
+
function toAntigravityToolSchema(schema, options = {}) {
|
|
8566
8761
|
if (!isRecord$22(schema)) return schema;
|
|
8567
8762
|
const root = schema;
|
|
8568
8763
|
function resolveReference(reference) {
|
|
@@ -8605,9 +8800,17 @@ function toAntigravityToolSchema(schema) {
|
|
|
8605
8800
|
"boolean"
|
|
8606
8801
|
].includes(typeof node.const)) out.enum = [String(node.const)];
|
|
8607
8802
|
} else if (Array.isArray(node.enum)) out.enum = node.enum.map((value) => String(value));
|
|
8803
|
+
if (options.foldUnions && node.type === void 0 && !Array.isArray(node.type)) {
|
|
8804
|
+
const values = Object.hasOwn(node, "const") ? [node.const] : node.enum;
|
|
8805
|
+
if (Array.isArray(values) && values.length > 0) {
|
|
8806
|
+
const literal = literalType(values);
|
|
8807
|
+
if (literal !== void 0) out.type = literal;
|
|
8808
|
+
}
|
|
8809
|
+
}
|
|
8608
8810
|
return mergeSchemas(inherited, out);
|
|
8609
8811
|
}
|
|
8610
|
-
|
|
8812
|
+
const converted = convert(root, /* @__PURE__ */ new Set());
|
|
8813
|
+
return options.foldUnions === true ? foldSchemaUnions(converted) : converted;
|
|
8611
8814
|
}
|
|
8612
8815
|
//#endregion
|
|
8613
8816
|
//#region src/host/antigravity/mapper.ts
|
|
@@ -9018,15 +9221,27 @@ function convertMessages(options, model, runtimeModel, images = NO_RESOLVED_IMAG
|
|
|
9018
9221
|
}
|
|
9019
9222
|
return contents;
|
|
9020
9223
|
}
|
|
9021
|
-
function stripMetaSchema$3(schema) {
|
|
9022
|
-
return toAntigravityToolSchema(schema);
|
|
9224
|
+
function stripMetaSchema$3(schema, options) {
|
|
9225
|
+
return toAntigravityToolSchema(schema, options);
|
|
9023
9226
|
}
|
|
9024
|
-
|
|
9227
|
+
/**
|
|
9228
|
+
* Whether this request's tool declarations must declare one form per parameter.
|
|
9229
|
+
*
|
|
9230
|
+
* Antigravity routes a Claude-family runtime model to Vertex Anthropic, whose
|
|
9231
|
+
* `input_schema` validation rejects a request whose tool schema still composes
|
|
9232
|
+
* itself with `anyOf`/`oneOf`/`allOf` (#39). Gemini ignores `anyOf`, so its
|
|
9233
|
+
* declarations keep the composed form they always sent.
|
|
9234
|
+
*/
|
|
9235
|
+
function foldsToolSchemaUnions(modelId, runtimeModel) {
|
|
9236
|
+
return modelId.startsWith("claude-") || runtimeModel.startsWith("claude-");
|
|
9237
|
+
}
|
|
9238
|
+
function convertTools(tools, modelId = "", runtimeModel = "") {
|
|
9025
9239
|
if (!tools || tools.length === 0) return void 0;
|
|
9240
|
+
const foldUnions = foldsToolSchemaUnions(modelId, runtimeModel);
|
|
9026
9241
|
return [{ functionDeclarations: tools.map((tool) => ({
|
|
9027
9242
|
name: tool.name,
|
|
9028
9243
|
description: tool.description || "",
|
|
9029
|
-
parameters: stripMetaSchema$3(tool.parameters) || {
|
|
9244
|
+
parameters: stripMetaSchema$3(tool.parameters, { foldUnions }) || {
|
|
9030
9245
|
type: "object",
|
|
9031
9246
|
properties: {}
|
|
9032
9247
|
}
|
|
@@ -9087,7 +9302,7 @@ function buildRequest$2(options, model, projectId, runtimeModel, effort, images
|
|
|
9087
9302
|
generationConfig.maxOutputTokens = options.maxTokens !== void 0 ? Math.min(options.maxTokens, maxAllowed) : maxAllowed;
|
|
9088
9303
|
request.generationConfig = generationConfig;
|
|
9089
9304
|
const toolChoice = options.toolChoice;
|
|
9090
|
-
const tools = convertTools(options.tools);
|
|
9305
|
+
const tools = convertTools(options.tools, model.id, runtimeModel);
|
|
9091
9306
|
if (tools) {
|
|
9092
9307
|
request.tools = tools;
|
|
9093
9308
|
if (toolChoice) request.toolConfig = { functionCallingConfig: { mode: mapToolChoiceMode(toolChoice) } };
|
|
@@ -34312,14 +34527,94 @@ function offloadOldestRequestImages(options) {
|
|
|
34312
34527
|
};
|
|
34313
34528
|
}
|
|
34314
34529
|
/**
|
|
34530
|
+
* Longest side, in pixels, the wire accepts for one image in any request.
|
|
34531
|
+
* TRANSCRIBED from the API's vision limits. The harness normalizes stored
|
|
34532
|
+
* images to an 8192 px long edge, so a stored image can still exceed this.
|
|
34533
|
+
*/
|
|
34534
|
+
const MAX_IMAGE_EDGE = 8e3;
|
|
34535
|
+
/**
|
|
34536
|
+
* Longest side, in pixels, the wire accepts for every image once one request
|
|
34537
|
+
* carries more than {@link MANY_IMAGE_THRESHOLD} images. TRANSCRIBED: past that
|
|
34538
|
+
* count the request is rejected with "At least one of the image dimensions
|
|
34539
|
+
* exceed max allowed size for many-image requests: 2000 pixels".
|
|
34540
|
+
*
|
|
34541
|
+
* Rejection is a 400 for the whole request. History keeps every image, so a
|
|
34542
|
+
* long session can only add images. Once it holds more than twenty and one is
|
|
34543
|
+
* wider than 2000 px, which is common for side-by-side screenshots, every later
|
|
34544
|
+
* turn fails. The session cannot recover by itself.
|
|
34545
|
+
*/
|
|
34546
|
+
const MANY_IMAGE_EDGE = 2e3;
|
|
34547
|
+
/**
|
|
34548
|
+
* Encoded-byte target for one downscaled request version.
|
|
34549
|
+
*
|
|
34550
|
+
* CHOICE: 3.5 MiB of raw bytes is about 4.9 MB of base64. That stays under the
|
|
34551
|
+
* 5 MB per-image ceiling whichever form the server measures. When no quality
|
|
34552
|
+
* level meets the target, the harness keeps its smallest output.
|
|
34553
|
+
*/
|
|
34554
|
+
const REQUEST_IMAGE_VERSION_MAX_BYTES = 3.5 * 1024 * 1024;
|
|
34555
|
+
function countRequestImages(content) {
|
|
34556
|
+
if (!Array.isArray(content)) return 0;
|
|
34557
|
+
let count = 0;
|
|
34558
|
+
for (const block of content) {
|
|
34559
|
+
if (!isRecord$5(block)) continue;
|
|
34560
|
+
if (block.type === "image") count += 1;
|
|
34561
|
+
else if (block.type === "tool-result") count += countRequestImages(block.content);
|
|
34562
|
+
}
|
|
34563
|
+
return count;
|
|
34564
|
+
}
|
|
34565
|
+
/**
|
|
34566
|
+
* Long-edge ceiling every image of this request must meet.
|
|
34567
|
+
*
|
|
34568
|
+
* The API counts image blocks, so a repeated attachment counts every time it
|
|
34569
|
+
* appears. The count is taken before images are resolved: a block that later
|
|
34570
|
+
* degrades to placeholder text still counts. Overcounting can only lower the
|
|
34571
|
+
* ceiling, and a lower ceiling never causes a rejection.
|
|
34572
|
+
*/
|
|
34573
|
+
function requestImageEdgeLimit(options) {
|
|
34574
|
+
let count = 0;
|
|
34575
|
+
for (const message of options.messages) count += countRequestImages(message.content);
|
|
34576
|
+
return count > 20 ? MANY_IMAGE_EDGE : MAX_IMAGE_EDGE;
|
|
34577
|
+
}
|
|
34578
|
+
/**
|
|
34579
|
+
* Request-version target for one stored image whose long edge is over the
|
|
34580
|
+
* ceiling, or undefined when it fits. The short edge rounds to the nearest
|
|
34581
|
+
* pixel, matching the harness's long-edge resize. A reference without usable
|
|
34582
|
+
* dimensions is sent as stored.
|
|
34583
|
+
*/
|
|
34584
|
+
function requestImageEdgeTarget(ref, edge) {
|
|
34585
|
+
const { width, height } = ref;
|
|
34586
|
+
if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width <= 0 || height <= 0) return void 0;
|
|
34587
|
+
if (Math.max(width, height) <= edge) return void 0;
|
|
34588
|
+
const maxPixels = Math.max(1, Math.floor(edge * edge * (Math.min(width, height) / Math.max(width, height))));
|
|
34589
|
+
return width >= height ? {
|
|
34590
|
+
width: edge,
|
|
34591
|
+
height: Math.max(1, Math.round(edge * height / width)),
|
|
34592
|
+
maxPixels,
|
|
34593
|
+
maxBytes: REQUEST_IMAGE_VERSION_MAX_BYTES
|
|
34594
|
+
} : {
|
|
34595
|
+
width: Math.max(1, Math.round(edge * width / height)),
|
|
34596
|
+
height: edge,
|
|
34597
|
+
maxPixels,
|
|
34598
|
+
maxBytes: REQUEST_IMAGE_VERSION_MAX_BYTES
|
|
34599
|
+
};
|
|
34600
|
+
}
|
|
34601
|
+
/**
|
|
34315
34602
|
* Read every durable { type: 'image', attachment } block one request carries.
|
|
34316
34603
|
* An unreadable image resolves to 'unavailable' rather than disappearing, so
|
|
34317
34604
|
* the model is told the picture is missing instead of answering about a blank.
|
|
34605
|
+
*
|
|
34606
|
+
* An image whose long edge is over this request's ceiling is sent as the
|
|
34607
|
+
* harness's downscaled request version (see {@link requestImageEdgeLimit}). The
|
|
34608
|
+
* stored image and durable history do not change, and an image that already
|
|
34609
|
+
* fits is sent byte-for-byte as stored. If a downscaled version cannot be
|
|
34610
|
+
* produced, the image resolves to 'unavailable'. A visible placeholder is better
|
|
34611
|
+
* than sending the original, which would make the whole request fail.
|
|
34318
34612
|
*/
|
|
34319
34613
|
async function resolveRequestImages(options, attachments, signal) {
|
|
34320
34614
|
const refs = /* @__PURE__ */ new Map();
|
|
34321
34615
|
for (const message of options.messages) collectImageRefs(message.content, refs);
|
|
34322
34616
|
if (refs.size === 0) return NO_RESOLVED_IMAGES;
|
|
34617
|
+
const edge = requestImageEdgeLimit(options);
|
|
34323
34618
|
const resolved = /* @__PURE__ */ new Map();
|
|
34324
34619
|
await Promise.all([...refs].map(async ([attachmentId, ref]) => {
|
|
34325
34620
|
if (!attachments) {
|
|
@@ -34327,6 +34622,16 @@ async function resolveRequestImages(options, attachments, signal) {
|
|
|
34327
34622
|
return;
|
|
34328
34623
|
}
|
|
34329
34624
|
try {
|
|
34625
|
+
const target = requestImageEdgeTarget(ref, edge);
|
|
34626
|
+
if (target !== void 0) {
|
|
34627
|
+
const version = await attachments.readImageRequest(ref, target, signal);
|
|
34628
|
+
resolved.set(attachmentId, Math.max(version.width, version.height) > edge ? { kind: "unavailable" } : {
|
|
34629
|
+
kind: "inline",
|
|
34630
|
+
mediaType: version.mediaType,
|
|
34631
|
+
data: Buffer.from(version.data).toString("base64")
|
|
34632
|
+
});
|
|
34633
|
+
return;
|
|
34634
|
+
}
|
|
34330
34635
|
const stored = await attachments.readImage(ref, signal);
|
|
34331
34636
|
resolved.set(attachmentId, {
|
|
34332
34637
|
kind: "inline",
|
|
@@ -42165,6 +42470,13 @@ function releaseListener(handle) {
|
|
|
42165
42470
|
//#endregion
|
|
42166
42471
|
//#region src/index.ts
|
|
42167
42472
|
const Config = z.object({
|
|
42473
|
+
fetchProvider: z.union([
|
|
42474
|
+
z.const("auto"),
|
|
42475
|
+
z.const("plugin"),
|
|
42476
|
+
z.const("dsh")
|
|
42477
|
+
]).default("auto"),
|
|
42478
|
+
fetchMaxBodyChars: z.number().min(1).max(Number.MAX_SAFE_INTEGER).step(1).default(DEFAULT_FETCH_MAX_BODY_CHARS),
|
|
42479
|
+
fetchMaxResponseBytes: z.number().min(1).max(Number.MAX_SAFE_INTEGER).step(1).default(DEFAULT_FETCH_MAX_RESPONSE_BYTES),
|
|
42168
42480
|
syncAgentPresets: z.boolean().default(true),
|
|
42169
42481
|
subagentModelAuthorization: z.boolean().default(true),
|
|
42170
42482
|
subagentModelTools: z.array(z.string()).default([]),
|
|
@@ -42181,6 +42493,7 @@ const inject = [
|
|
|
42181
42493
|
"loader"
|
|
42182
42494
|
];
|
|
42183
42495
|
function apply(ctx, pluginConfig = {}) {
|
|
42496
|
+
const fetchConfiguration = resolveFetchConfiguration(pluginConfig);
|
|
42184
42497
|
if (pluginConfig.syncAgentPresets !== false) ctx.effect(() => installBundledPresets(ctx, installDispatchPreset(ctx)), "dsh-chatgpt-subscription: agent preset sync");
|
|
42185
42498
|
const store = createPlatformTokenStore();
|
|
42186
42499
|
const preferences = registerPreferenceStore(ctx.settings);
|
|
@@ -42517,9 +42830,22 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
42517
42830
|
signal: options?.signal
|
|
42518
42831
|
})).catch(() => []));
|
|
42519
42832
|
const searchSwitcher = new SearchProviderSwitcher(ctx.loader);
|
|
42833
|
+
let lastFetchDiagnostic;
|
|
42520
42834
|
const applyWebProviders = (current = preferences.status()) => {
|
|
42521
42835
|
const pluginFetch = proxyManager.resolveActiveProxyUrl() !== null;
|
|
42522
|
-
searchSwitcher.select(current.searchProvider, {
|
|
42836
|
+
searchSwitcher.select(current.searchProvider, {
|
|
42837
|
+
pluginFetch,
|
|
42838
|
+
fetchProvider: fetchConfiguration.fetchProvider
|
|
42839
|
+
}).then(() => {
|
|
42840
|
+
const status = searchSwitcher.status();
|
|
42841
|
+
if (status.state === "missing" || status.state === "failed") return;
|
|
42842
|
+
const reason = fetchConfiguration.fetchProvider !== "auto" ? "explicit configuration" : current.searchProvider === "codex" ? "Codex search selected" : pluginFetch ? "active proxy detected" : "no proxy or Codex search";
|
|
42843
|
+
const diagnostic = `${status.configuredFetchProvider ?? "DSH default"} (mode=${fetchConfiguration.fetchProvider}; ${reason}; plugin limits=${fetchConfiguration.fetchMaxBodyChars} chars/${fetchConfiguration.fetchMaxResponseBytes} bytes)`;
|
|
42844
|
+
if (diagnostic !== lastFetchDiagnostic) {
|
|
42845
|
+
lastFetchDiagnostic = diagnostic;
|
|
42846
|
+
ctx.logger.info(`[dsh-chatgpt-subscription] Web fetch provider configured: ${diagnostic}`);
|
|
42847
|
+
}
|
|
42848
|
+
}).catch((error) => {
|
|
42523
42849
|
ctx.logger.warn(`[dsh-chatgpt-subscription] Web provider selection could not be applied: ${error instanceof Error ? error.message : String(error)}`);
|
|
42524
42850
|
});
|
|
42525
42851
|
};
|
|
@@ -42545,13 +42871,17 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
42545
42871
|
}))
|
|
42546
42872
|
});
|
|
42547
42873
|
};
|
|
42548
|
-
const disposeRoutes = registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher, readRouteAudit, codexAccountPool);
|
|
42874
|
+
const disposeRoutes = registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher, readRouteAudit, codexAccountPool, fetchConfiguration);
|
|
42549
42875
|
const disposeAdapter = ctx.llm.registerAdapter([PROVIDER_ID$7], adapter);
|
|
42550
42876
|
const disposeImageTool = ctx.tools.register(createCodexImageTool(oauth, ctx.attachments, { fetchFn: proxyFetch }));
|
|
42551
42877
|
const disposeVideoTool = ctx.tools.register(createKimiVideoTool(ctx, { fetchFn: proxyFetch }));
|
|
42552
42878
|
ctx.inject(["web"], (ctx) => {
|
|
42553
42879
|
ctx.web.registerSearchProvider(createCodexSearchProvider(oauth, { fetchFn: proxyFetch }));
|
|
42554
|
-
ctx.web.registerFetchProvider(createCodexFetchProvider({
|
|
42880
|
+
ctx.web.registerFetchProvider(createCodexFetchProvider({
|
|
42881
|
+
fetchFn: proxyFetch,
|
|
42882
|
+
maxBodyChars: fetchConfiguration.fetchMaxBodyChars,
|
|
42883
|
+
maxResponseBytes: fetchConfiguration.fetchMaxResponseBytes
|
|
42884
|
+
}));
|
|
42555
42885
|
setTimeout(applyWebProviders, 0);
|
|
42556
42886
|
});
|
|
42557
42887
|
const disposePreferenceWatch = preferences.watch((next) => applyWebProviders(next));
|
|
@@ -5,6 +5,24 @@ type Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>;
|
|
|
5
5
|
type BusyAction = 'login' | 'token' | 'quota' | 'reset-credit' | 'test' | 'logout' | 'preferences' | 'set-primary' | 'delete' | 'clear-cooldown' | 'strategy' | null;
|
|
6
6
|
type Translate = Props['t'];
|
|
7
7
|
export declare function CodexSubscriptionSection({ t }: Props): React.JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Read-only view of the fetch selection, shown under the search source.
|
|
10
|
+
*
|
|
11
|
+
* Both blocks are optional on the status DTO, so every row is rendered only from
|
|
12
|
+
* a value the host actually reported. That distinction is load-bearing: a
|
|
13
|
+
* missing `switcher` means the host tells us nothing and the row stays hidden,
|
|
14
|
+
* while a reported `configuredFetchProvider: null` is a real answer — the host
|
|
15
|
+
* pinned no provider, which is the DSH default. Guessing an id there would claim
|
|
16
|
+
* a provider the settings page never observed.
|
|
17
|
+
*
|
|
18
|
+
* Nothing here is editable: the mode and the limits live in the plugin Config,
|
|
19
|
+
* not in the preferences this card sits in, so the numbers cannot be mistaken for
|
|
20
|
+
* a setting that this page can change.
|
|
21
|
+
*/
|
|
22
|
+
export declare function FetchProviderStatusCard({ status, t }: {
|
|
23
|
+
status: PluginStatusDto | null | undefined;
|
|
24
|
+
t: Translate;
|
|
25
|
+
}): React.JSX.Element | null;
|
|
8
26
|
export declare function storageLabel(storage: CredentialStorageDto | undefined, t: Translate): string;
|
|
9
27
|
export declare function storageNotice(storage: CredentialStorageDto | undefined, t: Translate): string;
|
|
10
28
|
export declare function ResetCreditsFact({ resetCredits, busy, onUse, t }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodexSubscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/CodexSubscriptionSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAyB,oBAAoB,EAAE,eAAe,EAAkB,cAAc,EAA8D,MAAM,wBAAwB,CAAA;AAOtM,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,KAAK,KAAK,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AACtE,KAAK,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,aAAa,GAC9F,aAAa,GAAG,QAAQ,GAAG,gBAAgB,GAAG,UAAU,GAAG,IAAI,CAAA;AACnE,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAE3B,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"CodexSubscriptionSection.d.ts","sourceRoot":"","sources":["../../../src/client/CodexSubscriptionSection.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AACjF,OAAO,KAAK,EAAyB,oBAAoB,EAAE,eAAe,EAAkB,cAAc,EAA8D,MAAM,wBAAwB,CAAA;AAOtM,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAGjC,KAAK,KAAK,GAAG,YAAY,CAAC,kBAAkB,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAA;AACtE,KAAK,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,aAAa,GAC9F,aAAa,GAAG,QAAQ,GAAG,gBAAgB,GAAG,UAAU,GAAG,IAAI,CAAA;AACnE,KAAK,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;AAE3B,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsiBxE;AA+BD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAAE,MAAM,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAAC,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CA4B7I;AAOD,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO5F;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAO7F;AAcD,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAAE,YAAY,EAAE,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAUzN;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAczH;AAMD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CAYpF;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,SAA4B,GAAG,MAAM,GAAG,IAAI,CAGxG;AAoCD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAgBtE"}
|
|
@@ -70,10 +70,30 @@ export declare const zh: {
|
|
|
70
70
|
readonly summaryConcise: "简洁(显示简要推理摘要)";
|
|
71
71
|
readonly summaryDetailed: "详细(显示更详细的推理摘要)";
|
|
72
72
|
readonly summaryNone: "无(不显示推理摘要)";
|
|
73
|
-
readonly searchProvider: "
|
|
74
|
-
readonly searchProviderHint: "选择 DSH
|
|
73
|
+
readonly searchProvider: "搜索来源";
|
|
74
|
+
readonly searchProviderHint: "选择 DSH 联网搜索使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。抓取模式为 auto 时,抓取来源跟随此选择。";
|
|
75
75
|
readonly searchProviderDsh: "DSH 默认";
|
|
76
76
|
readonly searchProviderCodex: "ChatGPT(代理隧道)";
|
|
77
|
+
readonly fetchStatus: "抓取来源(只读)";
|
|
78
|
+
readonly fetchStatusHint: "以下内容由 Host 上报,只读展示。";
|
|
79
|
+
readonly fetchConfiguredProvider: "配置的抓取 Provider";
|
|
80
|
+
readonly fetchProviderDshDefault: "DSH 默认(Host 未固定抓取 provider)";
|
|
81
|
+
readonly switcherState: "抓取选择器状态";
|
|
82
|
+
readonly switcherStateIdle: "空闲(尚未应用选择)";
|
|
83
|
+
readonly switcherStateApplying: "应用中(正在切换 Host 的 web provider)";
|
|
84
|
+
readonly switcherStateApplied: "已应用";
|
|
85
|
+
readonly switcherStateMissing: "未找到可切换的 web 服务";
|
|
86
|
+
readonly switcherStateFailed: "切换失败,请检查 Host 日志";
|
|
87
|
+
readonly fetchMode: "抓取模式";
|
|
88
|
+
readonly fetchModeAuto: "auto(有可用代理或选了 ChatGPT 搜索时用插件抓取)";
|
|
89
|
+
readonly fetchModePlugin: "plugin(始终用本插件抓取)";
|
|
90
|
+
readonly fetchModeDsh: "dsh(保留 DSH 原有抓取来源)";
|
|
91
|
+
readonly fetchMaxBodyChars: "插件正文上限";
|
|
92
|
+
readonly fetchMaxResponseBytes: "插件响应体上限";
|
|
93
|
+
readonly characters: "字符";
|
|
94
|
+
readonly bytes: "字节";
|
|
95
|
+
readonly fetchLimitsInactive: "仅在实际使用插件抓取时生效;走 DSH 原有抓取来源时不适用这两个上限。";
|
|
96
|
+
readonly fetchConfigSource: "模式与上限在插件 Config 中修改(不是本页面偏好),修改后重载插件或重启 DSH 生效。";
|
|
77
97
|
readonly providerDefault: "使用 Provider 默认值";
|
|
78
98
|
readonly contextWindows: "模型上下文窗口";
|
|
79
99
|
readonly contextWindowsHint: "只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。";
|
|
@@ -225,10 +245,30 @@ export declare const dictionaries: {
|
|
|
225
245
|
readonly summaryConcise: "简洁(显示简要推理摘要)";
|
|
226
246
|
readonly summaryDetailed: "详细(显示更详细的推理摘要)";
|
|
227
247
|
readonly summaryNone: "无(不显示推理摘要)";
|
|
228
|
-
readonly searchProvider: "
|
|
229
|
-
readonly searchProviderHint: "选择 DSH
|
|
248
|
+
readonly searchProvider: "搜索来源";
|
|
249
|
+
readonly searchProviderHint: "选择 DSH 联网搜索使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。抓取模式为 auto 时,抓取来源跟随此选择。";
|
|
230
250
|
readonly searchProviderDsh: "DSH 默认";
|
|
231
251
|
readonly searchProviderCodex: "ChatGPT(代理隧道)";
|
|
252
|
+
readonly fetchStatus: "抓取来源(只读)";
|
|
253
|
+
readonly fetchStatusHint: "以下内容由 Host 上报,只读展示。";
|
|
254
|
+
readonly fetchConfiguredProvider: "配置的抓取 Provider";
|
|
255
|
+
readonly fetchProviderDshDefault: "DSH 默认(Host 未固定抓取 provider)";
|
|
256
|
+
readonly switcherState: "抓取选择器状态";
|
|
257
|
+
readonly switcherStateIdle: "空闲(尚未应用选择)";
|
|
258
|
+
readonly switcherStateApplying: "应用中(正在切换 Host 的 web provider)";
|
|
259
|
+
readonly switcherStateApplied: "已应用";
|
|
260
|
+
readonly switcherStateMissing: "未找到可切换的 web 服务";
|
|
261
|
+
readonly switcherStateFailed: "切换失败,请检查 Host 日志";
|
|
262
|
+
readonly fetchMode: "抓取模式";
|
|
263
|
+
readonly fetchModeAuto: "auto(有可用代理或选了 ChatGPT 搜索时用插件抓取)";
|
|
264
|
+
readonly fetchModePlugin: "plugin(始终用本插件抓取)";
|
|
265
|
+
readonly fetchModeDsh: "dsh(保留 DSH 原有抓取来源)";
|
|
266
|
+
readonly fetchMaxBodyChars: "插件正文上限";
|
|
267
|
+
readonly fetchMaxResponseBytes: "插件响应体上限";
|
|
268
|
+
readonly characters: "字符";
|
|
269
|
+
readonly bytes: "字节";
|
|
270
|
+
readonly fetchLimitsInactive: "仅在实际使用插件抓取时生效;走 DSH 原有抓取来源时不适用这两个上限。";
|
|
271
|
+
readonly fetchConfigSource: "模式与上限在插件 Config 中修改(不是本页面偏好),修改后重载插件或重启 DSH 生效。";
|
|
232
272
|
readonly providerDefault: "使用 Provider 默认值";
|
|
233
273
|
readonly contextWindows: "模型上下文窗口";
|
|
234
274
|
readonly contextWindowsHint: "只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。";
|
|
@@ -306,6 +346,6 @@ export declare const dictionaries: {
|
|
|
306
346
|
readonly email: string;
|
|
307
347
|
readonly lastUsed: string;
|
|
308
348
|
};
|
|
309
|
-
en: Record<"stale" | "quota" | "account" | "storage" | "rotationStrategy" | "pending" | "accountId" | "relogin" | "tokens" | "title" | "hubTitle" | "intro" | "signedOut" | "signedIn" | "plan" | "expires" | "storageWindows" | "storageMacKeychain" | "storageLinuxFile" | "storageMemory" | "storageUnavailable" | "securityWindows" | "securityMacKeychain" | "securityLinuxFile" | "securityMemory" | "securityUnavailable" | "signIn" | "signInAgain" | "cancel" | "signOut" | "refreshToken" | "popupBlocked" | "continueLogin" | "loading" | "connection" | "provider" | "connectionState" | "connected" | "untested" | "testConnection" | "testing" | "latency" | "enableProvider" | "selectAll" | "unselectAll" | "models" | "modelsHint" | "proxySettings" | "proxyMode" | "proxyModeHint" | "proxyModeAuto" | "proxyModeCustom" | "proxyModeDirect" | "customProxyUrl" | "customProxyUrlHint" | "customProxyUrlPlaceholder" | "saveProxyUrl" | "proxyDetected" | "proxyDetectedEffective" | "proxyNoneDetected" | "proxyDirectHint" | "enhancements" | "fastMode" | "fastModeHint" | "outputVerbosity" | "outputVerbosityHint" | "verbosityLow" | "verbosityMedium" | "verbosityHigh" | "reasoningSummary" | "reasoningSummaryHint" | "summaryAuto" | "summaryConcise" | "summaryDetailed" | "summaryNone" | "searchProvider" | "searchProviderHint" | "searchProviderDsh" | "searchProviderCodex" | "providerDefault" | "contextWindows" | "contextWindowsHint" | "contextWindow" | "contextWindowInvalid" | "contextWindowReset" | "contextWindowResetAll" | "contextWindowResetAllConfirm" | "contextWindowsNoneEnabled" | "saveContextWindow" | "save" | "quickQuota" | "quickQuotaHint" | "quotaIntro" | "refreshQuota" | "refreshing" | "noQuota" | "quotaSignedOut" | "updated" | "primary" | "secondary" | "limitWindow" | "used" | "remaining" | "available" | "unavailable" | "unlimited" | "credits" | "monthlySpend" | "resetCredits" | "resetCreditExpires" | "useResetCredit" | "usingResetCredit" | "useResetCreditConfirm" | "resetCreditUsed" | "spendControlReached" | "limit" | "exhausted" | "resets" | "quickQuotaLabel" | "quickQuotaLoading" | "imageToolRunning" | "imageToolDone" | "imageToolFailed" | "image" | "openImage" | "openNamedImage" | "imageLoading" | "imageLoadFailed" | "imagePreviewClose" | "imagePreviewOpenOriginal" | "retry" | "unknown" | "accountPool" | "addAccount" | "accountCount" | "primaryAccount" | "activeAccount" | "setPrimary" | "deleteAccount" | "cooling" | "cooldownLeft" | "clearCooldown" | "needsRelogin" | "strategySequential" | "strategyRoundRobin" | "strategySticky" | "noAccounts" | "storageNotice" | "email" | "lastUsed", string>;
|
|
349
|
+
en: Record<"stale" | "quota" | "account" | "storage" | "rotationStrategy" | "pending" | "accountId" | "relogin" | "tokens" | "title" | "hubTitle" | "intro" | "signedOut" | "signedIn" | "plan" | "expires" | "storageWindows" | "storageMacKeychain" | "storageLinuxFile" | "storageMemory" | "storageUnavailable" | "securityWindows" | "securityMacKeychain" | "securityLinuxFile" | "securityMemory" | "securityUnavailable" | "signIn" | "signInAgain" | "cancel" | "signOut" | "refreshToken" | "popupBlocked" | "continueLogin" | "loading" | "connection" | "provider" | "connectionState" | "connected" | "untested" | "testConnection" | "testing" | "latency" | "enableProvider" | "selectAll" | "unselectAll" | "models" | "modelsHint" | "proxySettings" | "proxyMode" | "proxyModeHint" | "proxyModeAuto" | "proxyModeCustom" | "proxyModeDirect" | "customProxyUrl" | "customProxyUrlHint" | "customProxyUrlPlaceholder" | "saveProxyUrl" | "proxyDetected" | "proxyDetectedEffective" | "proxyNoneDetected" | "proxyDirectHint" | "enhancements" | "fastMode" | "fastModeHint" | "outputVerbosity" | "outputVerbosityHint" | "verbosityLow" | "verbosityMedium" | "verbosityHigh" | "reasoningSummary" | "reasoningSummaryHint" | "summaryAuto" | "summaryConcise" | "summaryDetailed" | "summaryNone" | "searchProvider" | "searchProviderHint" | "searchProviderDsh" | "searchProviderCodex" | "fetchStatus" | "fetchStatusHint" | "fetchConfiguredProvider" | "fetchProviderDshDefault" | "switcherState" | "switcherStateIdle" | "switcherStateApplying" | "switcherStateApplied" | "switcherStateMissing" | "switcherStateFailed" | "fetchMode" | "fetchModeAuto" | "fetchModePlugin" | "fetchModeDsh" | "fetchMaxBodyChars" | "fetchMaxResponseBytes" | "characters" | "bytes" | "fetchLimitsInactive" | "fetchConfigSource" | "providerDefault" | "contextWindows" | "contextWindowsHint" | "contextWindow" | "contextWindowInvalid" | "contextWindowReset" | "contextWindowResetAll" | "contextWindowResetAllConfirm" | "contextWindowsNoneEnabled" | "saveContextWindow" | "save" | "quickQuota" | "quickQuotaHint" | "quotaIntro" | "refreshQuota" | "refreshing" | "noQuota" | "quotaSignedOut" | "updated" | "primary" | "secondary" | "limitWindow" | "used" | "remaining" | "available" | "unavailable" | "unlimited" | "credits" | "monthlySpend" | "resetCredits" | "resetCreditExpires" | "useResetCredit" | "usingResetCredit" | "useResetCreditConfirm" | "resetCreditUsed" | "spendControlReached" | "limit" | "exhausted" | "resets" | "quickQuotaLabel" | "quickQuotaLoading" | "imageToolRunning" | "imageToolDone" | "imageToolFailed" | "image" | "openImage" | "openNamedImage" | "imageLoading" | "imageLoadFailed" | "imagePreviewClose" | "imagePreviewOpenOriginal" | "retry" | "unknown" | "accountPool" | "addAccount" | "accountCount" | "primaryAccount" | "activeAccount" | "setPrimary" | "deleteAccount" | "cooling" | "cooldownLeft" | "clearCooldown" | "needsRelogin" | "strategySequential" | "strategyRoundRobin" | "strategySticky" | "noAccounts" | "storageNotice" | "email" | "lastUsed", string>;
|
|
310
350
|
};
|
|
311
351
|
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAG,0BAAmC,CAAA;AAIrD,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAG,0BAAmC,CAAA;AAIrD,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0JL,CAAA;AAEV,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,CAwJ9C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AACvC,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAa,CAAA"}
|