@eddyskywalker/dsh-chatgpt-subscription 0.39.2 → 0.40.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 +35 -0
- package/README.md +34 -2
- package/lib/client.js +301 -0
- package/lib/client.js.map +1 -1
- package/lib/index.js +355 -10
- package/lib/types/client/CompactionRouteBundleConfig.d.ts +19 -0
- package/lib/types/client/CompactionRouteBundleConfig.d.ts.map +1 -0
- package/lib/types/client/CompactionRouteCard.d.ts +43 -0
- package/lib/types/client/CompactionRouteCard.d.ts.map +1 -0
- package/lib/types/client/api.d.ts +3 -1
- package/lib/types/client/api.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/locales-ru/hub.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +27 -1
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/compat.d.ts +9 -1
- package/lib/types/compat.d.ts.map +1 -1
- package/lib/types/host/agent-preset.d.ts.map +1 -1
- package/lib/types/host/compaction-route/index.d.ts +132 -0
- package/lib/types/host/compaction-route/index.d.ts.map +1 -0
- package/lib/types/host/preferences.d.ts.map +1 -1
- package/lib/types/host/routes.d.ts.map +1 -1
- package/lib/types/host/subagent-model-authorization.d.ts +53 -1
- package/lib/types/host/subagent-model-authorization.d.ts.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/shared/compaction-route.d.ts +63 -0
- package/lib/types/shared/compaction-route.d.ts.map +1 -0
- package/lib/types/shared/contracts.d.ts +26 -0
- package/lib/types/shared/contracts.d.ts.map +1 -1
- package/lib/types/shared/preferences.d.ts +2 -0
- package/lib/types/shared/preferences.d.ts.map +1 -1
- package/package.json +1 -1
- package/presets/dispatch/README.md +8 -2
- package/presets/dispatch/agent.cordis.yml +11 -4
package/lib/index.js
CHANGED
|
@@ -133,7 +133,15 @@ const OAUTH_DEVICE_GRANT_LIFETIME_MS = 15 * 6e4;
|
|
|
133
133
|
const OAUTH_DEVICE_MIN_POLL_INTERVAL_MS = 1e3;
|
|
134
134
|
const TOKEN_REFRESH_MARGIN_MS = 6e4;
|
|
135
135
|
const ROUTE_PREFIX$4 = "/api/dsh-chatgpt-subscription";
|
|
136
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Version this line presents to the Codex backend in its `user-agent`.
|
|
138
|
+
*
|
|
139
|
+
* It must equal `package.json`'s version: a stale value here reports a plugin
|
|
140
|
+
* version that no release ever shipped, and nothing else in the build notices.
|
|
141
|
+
* `test/responses-client.test.ts` asserts the two agree, so a release that
|
|
142
|
+
* forgets this constant fails the suite instead of shipping quietly.
|
|
143
|
+
*/
|
|
144
|
+
const PLUGIN_VERSION = "0.40.1";
|
|
137
145
|
const CODEX_CHATGPT_PROVIDER_ID = "codex-chatgpt";
|
|
138
146
|
const CODEX_API_BASE = "https://chatgpt.com/backend-api/codex";
|
|
139
147
|
const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses`;
|
|
@@ -10630,6 +10638,50 @@ var FilePreferencesStore = class {
|
|
|
10630
10638
|
}
|
|
10631
10639
|
};
|
|
10632
10640
|
//#endregion
|
|
10641
|
+
//#region src/shared/compaction-route.ts
|
|
10642
|
+
/** Runtime membership test for one stored target. */
|
|
10643
|
+
function isCompactionRouteTarget(value) {
|
|
10644
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
10645
|
+
const record = value;
|
|
10646
|
+
return isNonEmptyString(record.provider) && isNonEmptyString(record.model);
|
|
10647
|
+
}
|
|
10648
|
+
function isNonEmptyString(value) {
|
|
10649
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
10650
|
+
}
|
|
10651
|
+
/**
|
|
10652
|
+
* Decide whether the payload is admissible on the target.
|
|
10653
|
+
*
|
|
10654
|
+
* An undisclosed modality list is unknown, not negative: the harness documents
|
|
10655
|
+
* absence as "not disclosed", so refusing on it would disable the feature on
|
|
10656
|
+
* every route that simply does not advertise. The request still runs, and a
|
|
10657
|
+
* real rejection falls back the same way an error does.
|
|
10658
|
+
*
|
|
10659
|
+
* @param facts - what the directory says about the target.
|
|
10660
|
+
* @param needs - what the payload contains.
|
|
10661
|
+
* @returns the refusal reason, or `undefined` when the target may take it.
|
|
10662
|
+
*/
|
|
10663
|
+
function compactionSkipReason(facts, needs) {
|
|
10664
|
+
const modalities = facts.modalities;
|
|
10665
|
+
if (modalities === void 0) return void 0;
|
|
10666
|
+
const accepts = new Set(modalities);
|
|
10667
|
+
if (needs.video && !accepts.has("video")) return "target-accepts-no-video";
|
|
10668
|
+
}
|
|
10669
|
+
/**
|
|
10670
|
+
* Whether the target can carry images inline.
|
|
10671
|
+
*
|
|
10672
|
+
* Used for the recorded outcome only: an image the target cannot take is
|
|
10673
|
+
* replaced by a placeholder during projection, so the summary is still produced
|
|
10674
|
+
* but may describe a screenshot it never saw.
|
|
10675
|
+
*
|
|
10676
|
+
* @param facts - what the directory says about the target.
|
|
10677
|
+
* @returns false only when the target discloses image support and omits it.
|
|
10678
|
+
*/
|
|
10679
|
+
function compactionRoutesImages(facts) {
|
|
10680
|
+
const modalities = facts.modalities;
|
|
10681
|
+
if (modalities === void 0) return true;
|
|
10682
|
+
return modalities.includes("image");
|
|
10683
|
+
}
|
|
10684
|
+
//#endregion
|
|
10633
10685
|
//#region src/shared/preferences.ts
|
|
10634
10686
|
const PREFERENCES_NAMESPACE = "dsh-chatgpt-subscription";
|
|
10635
10687
|
const DEFAULT_PREFERENCES = {
|
|
@@ -10642,7 +10694,8 @@ const DEFAULT_PREFERENCES = {
|
|
|
10642
10694
|
searchProvider: "dsh",
|
|
10643
10695
|
contextWindowOverrides: {},
|
|
10644
10696
|
proxyMode: "auto",
|
|
10645
|
-
customProxyUrl: null
|
|
10697
|
+
customProxyUrl: null,
|
|
10698
|
+
compactionRoute: null
|
|
10646
10699
|
};
|
|
10647
10700
|
const SEARCH_PROVIDER_CODEX = "codex";
|
|
10648
10701
|
function isSearchProviderPreference(value) {
|
|
@@ -10848,7 +10901,11 @@ function registerPreferenceStore(settings) {
|
|
|
10848
10901
|
z.const("custom"),
|
|
10849
10902
|
z.const("direct")
|
|
10850
10903
|
]).default(DEFAULT_PREFERENCES.proxyMode),
|
|
10851
|
-
customProxyUrl: z.union([z.string(), z.const(null)]).default(DEFAULT_PREFERENCES.customProxyUrl)
|
|
10904
|
+
customProxyUrl: z.union([z.string(), z.const(null)]).default(DEFAULT_PREFERENCES.customProxyUrl),
|
|
10905
|
+
compactionRoute: z.union([z.object({
|
|
10906
|
+
provider: z.string(),
|
|
10907
|
+
model: z.string()
|
|
10908
|
+
}), z.const(null)]).default(DEFAULT_PREFERENCES.compactionRoute ?? null)
|
|
10852
10909
|
});
|
|
10853
10910
|
if (!hasRegister(settings)) {
|
|
10854
10911
|
const fileStore = new FilePreferencesStore(schema, preferencesPath(), readLegacyPreferences);
|
|
@@ -10899,6 +10956,13 @@ var SettingsPreferenceStore = class {
|
|
|
10899
10956
|
if (!isProxyMode(patch.proxyMode)) throw new PreferenceError("Unsupported proxy mode preference.");
|
|
10900
10957
|
normalized.proxyMode = patch.proxyMode;
|
|
10901
10958
|
}
|
|
10959
|
+
if (patch.compactionRoute !== void 0) {
|
|
10960
|
+
if (patch.compactionRoute !== null && !isCompactionRouteTarget(patch.compactionRoute)) throw new PreferenceError("Unsupported compaction route.");
|
|
10961
|
+
normalized.compactionRoute = patch.compactionRoute === null ? null : {
|
|
10962
|
+
provider: patch.compactionRoute.provider.trim(),
|
|
10963
|
+
model: patch.compactionRoute.model.trim()
|
|
10964
|
+
};
|
|
10965
|
+
}
|
|
10902
10966
|
if (patch.customProxyUrl !== void 0) if (patch.customProxyUrl !== null) {
|
|
10903
10967
|
const trimmed = patch.customProxyUrl.trim();
|
|
10904
10968
|
if (trimmed.length > 0 && !/^https?:\/\//i.test(trimmed) && !/^socks5?:\/\//i.test(trimmed)) normalized.customProxyUrl = `http://${trimmed}`;
|
|
@@ -13629,6 +13693,12 @@ function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwit
|
|
|
13629
13693
|
value: await usage.testConnection()
|
|
13630
13694
|
});
|
|
13631
13695
|
return;
|
|
13696
|
+
case `${ROUTE_PREFIX$4}/compaction/candidates`:
|
|
13697
|
+
json(response, {
|
|
13698
|
+
ok: true,
|
|
13699
|
+
value: await compactionCandidates(ctx)
|
|
13700
|
+
});
|
|
13701
|
+
return;
|
|
13632
13702
|
case `${ROUTE_PREFIX$4}/preferences/update`: {
|
|
13633
13703
|
const patch = readPreferencesUpdate(body, preferences.status());
|
|
13634
13704
|
const value = await preferences.update(patch);
|
|
@@ -13737,6 +13807,23 @@ function field(value, name) {
|
|
|
13737
13807
|
const candidate = value[name];
|
|
13738
13808
|
return typeof candidate === "string" && candidate !== "" ? candidate : null;
|
|
13739
13809
|
}
|
|
13810
|
+
/** The provider and model directory a compaction target is chosen from. */
|
|
13811
|
+
async function compactionCandidates(ctx) {
|
|
13812
|
+
const llm = ctx.llm;
|
|
13813
|
+
if (llm === void 0 || typeof llm.listProviders !== "function") return { providers: [] };
|
|
13814
|
+
return { providers: (await Promise.all(llm.listProviders().map(async (provider) => {
|
|
13815
|
+
const models = await llm.listModels(provider.id).catch(() => []);
|
|
13816
|
+
return {
|
|
13817
|
+
id: provider.id,
|
|
13818
|
+
name: provider.name,
|
|
13819
|
+
models: models.map((model) => ({
|
|
13820
|
+
id: model.id,
|
|
13821
|
+
name: model.name,
|
|
13822
|
+
modalities: [...model.inputModalities ?? []]
|
|
13823
|
+
}))
|
|
13824
|
+
};
|
|
13825
|
+
}))).filter((provider) => provider.models.length > 0) };
|
|
13826
|
+
}
|
|
13740
13827
|
function isRecord$44(value) {
|
|
13741
13828
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13742
13829
|
}
|
|
@@ -13770,6 +13857,13 @@ function readPreferencesUpdate(value, current) {
|
|
|
13770
13857
|
if (value.searchProvider !== "dsh" && value.searchProvider !== "codex") throw new PreferenceError("searchProvider must be dsh or codex.");
|
|
13771
13858
|
patch.searchProvider = value.searchProvider;
|
|
13772
13859
|
}
|
|
13860
|
+
if ("compactionRoute" in value) {
|
|
13861
|
+
if (value.compactionRoute !== null && !isCompactionRouteTarget(value.compactionRoute)) throw new PreferenceError("compactionRoute must be null or an object with provider and model.");
|
|
13862
|
+
patch.compactionRoute = value.compactionRoute === null ? null : {
|
|
13863
|
+
provider: value.compactionRoute.provider.trim(),
|
|
13864
|
+
model: value.compactionRoute.model.trim()
|
|
13865
|
+
};
|
|
13866
|
+
}
|
|
13773
13867
|
if ("contextWindowOverrides" in value) {
|
|
13774
13868
|
if (!isRecord$44(value.contextWindowOverrides)) throw new PreferenceError("contextWindowOverrides must be an object.");
|
|
13775
13869
|
const overrides = {};
|
|
@@ -75608,6 +75702,34 @@ function inheritRouteDenialReason(toolName, provider, model, allowed, reasoningE
|
|
|
75608
75702
|
return `subagent model selection: "${toolName}" keeps its child on ${provider === void 0 || model === void 0 ? "the calling agent's route" : `"${provider}/${model}"${reasoningEffort === void 0 ? "" : ` (${reasoningEffort})`}`}, which this Session's allowlist does not authorize, so it is unavailable for now. Its child cannot be re-routed, so either delegate through a tool that exposes provider and model — passing one of ${authorizedRoutesText(allowed)} — or continue on an authorized model for this session, after which ${toolName} works again.`;
|
|
75609
75703
|
}
|
|
75610
75704
|
/**
|
|
75705
|
+
* Enforce the allowlist against the route an inherit-mode child would run on.
|
|
75706
|
+
* @param agent - Calling agent whose route the child inherits.
|
|
75707
|
+
* @param toolName - the tool the model called.
|
|
75708
|
+
* @param allowed - Routes the calling Session authorizes.
|
|
75709
|
+
* @returns a denial reason when the inherited route is unauthorized.
|
|
75710
|
+
*/
|
|
75711
|
+
function inheritedRouteDenial(agent, toolName, allowed) {
|
|
75712
|
+
const inherited = inheritedRouteOf(agent);
|
|
75713
|
+
if (inherited.provider !== void 0 && inherited.model !== void 0 && routesInclude(allowed, inherited.provider, inherited.model)) return void 0;
|
|
75714
|
+
return inheritRouteDenialReason(toolName, inherited.provider, inherited.model, allowed, inherited.reasoningEffort);
|
|
75715
|
+
}
|
|
75716
|
+
/**
|
|
75717
|
+
* Build the denial reason for a half-specified route aimed at a tool that
|
|
75718
|
+
* exposes no route field at all.
|
|
75719
|
+
*
|
|
75720
|
+
* This is the one denial whose cause is not the call: the delegation tool was
|
|
75721
|
+
* mounted without model selection, so no argument can name a child route. The
|
|
75722
|
+
* reason states the configuration defect and the route the child would inherit,
|
|
75723
|
+
* because "call list_subagent_models and pass a route" would be unactionable.
|
|
75724
|
+
* @param toolName - the tool the model called.
|
|
75725
|
+
* @param inherited - the route the child would inherit from the caller.
|
|
75726
|
+
* @param allowed - Routes the calling Session authorizes.
|
|
75727
|
+
* @returns the corrective reason handed back to the model.
|
|
75728
|
+
*/
|
|
75729
|
+
function routeFieldsUnavailableReason(toolName, inherited, allowed) {
|
|
75730
|
+
return `subagent model selection: "${toolName}" exposes no provider/model parameter in this deployment, so no call can name a child route — the delegation tool is mounted without model selection enabled. The child would run on ${inherited.provider === void 0 || inherited.model === void 0 ? "the calling agent's own route" : `"${inherited.provider}/${inherited.model}"`}; authorized routes are ${authorizedRoutesText(allowed)}.`;
|
|
75731
|
+
}
|
|
75732
|
+
/**
|
|
75611
75733
|
* Resolve one tool's enforcement mode from the configured policies. An
|
|
75612
75734
|
* unconfigured name is `undefined`: the guard does not police it, which is how
|
|
75613
75735
|
* the plain-name configuration keeps its existing meaning.
|
|
@@ -75773,7 +75895,7 @@ function rewriteAuthorizedPromptAssembly(assembly, allowed, toolNames = DEFAULT_
|
|
|
75773
75895
|
* @param inheritToolNames - Delegation tools that start a child on the caller's own route.
|
|
75774
75896
|
* @returns a denial reason, or undefined to leave the call untouched.
|
|
75775
75897
|
*/
|
|
75776
|
-
function delegationDenialReason(agent, toolName, args, preference, sessions, toolNames = DEFAULT_DELEGATION_TOOLS, scope = "session", inheritToolNames = []) {
|
|
75898
|
+
function delegationDenialReason(agent, toolName, args, preference, sessions, toolNames = DEFAULT_DELEGATION_TOOLS, scope = "session", inheritToolNames = [], declaresRouteParameters) {
|
|
75777
75899
|
const mode = delegationModeOf([...toolNames.map((name) => ({
|
|
75778
75900
|
name,
|
|
75779
75901
|
mode: "explicit"
|
|
@@ -75789,9 +75911,11 @@ function delegationDenialReason(agent, toolName, args, preference, sessions, too
|
|
|
75789
75911
|
const requestedModel = asString$1(request["model"]);
|
|
75790
75912
|
if (mode === "inherit") {
|
|
75791
75913
|
if (requestedProvider !== void 0 && requestedModel !== void 0) return inheritOverrideReason(toolName, requestedProvider, requestedModel);
|
|
75792
|
-
|
|
75793
|
-
|
|
75794
|
-
|
|
75914
|
+
return inheritedRouteDenial(agent, toolName, allowed);
|
|
75915
|
+
}
|
|
75916
|
+
if (declaresRouteParameters?.(agent, toolName) === false) {
|
|
75917
|
+
if (requestedProvider === void 0 && requestedModel === void 0) return inheritedRouteDenial(agent, toolName, allowed);
|
|
75918
|
+
if (requestedProvider === void 0 || requestedModel === void 0) return routeFieldsUnavailableReason(toolName, inheritedRouteOf(agent), allowed);
|
|
75795
75919
|
}
|
|
75796
75920
|
if (requestedProvider === void 0) return requestedModel === void 0 ? missingRouteReason(allowed) : partialRouteReason("provider", requestedModel, allowed);
|
|
75797
75921
|
if (requestedModel === void 0) return partialRouteReason("model", requestedProvider, allowed);
|
|
@@ -75808,7 +75932,7 @@ function delegationDenialReason(agent, toolName, args, preference, sessions, too
|
|
|
75808
75932
|
* @returns a guard that denies delegations outside the Session allowlist.
|
|
75809
75933
|
*/
|
|
75810
75934
|
function createSubagentAuthorization(options) {
|
|
75811
|
-
return (agent, toolName, args) => delegationDenialReason(agent, toolName, args, subagentModelSelectionPreference(options.settings), options.sessions, options.toolNames, options.scope ?? "session", options.inheritToolNames ?? []);
|
|
75935
|
+
return (agent, toolName, args) => delegationDenialReason(agent, toolName, args, subagentModelSelectionPreference(options.settings), options.sessions, options.toolNames, options.scope ?? "session", options.inheritToolNames ?? [], options.declaresRouteParameters);
|
|
75812
75936
|
}
|
|
75813
75937
|
/** Delegation names this guard recognizes when configuration omits them. */
|
|
75814
75938
|
function normalizeDelegationToolNames(value) {
|
|
@@ -75849,6 +75973,36 @@ function validateDelegationToolNames(toolNames) {
|
|
|
75849
75973
|
return [...toolNames];
|
|
75850
75974
|
}
|
|
75851
75975
|
/**
|
|
75976
|
+
* Build the live route-parameter probe from the Host tool registry.
|
|
75977
|
+
*
|
|
75978
|
+
* The registry is read per call rather than snapshotted: an HMR replacement or a
|
|
75979
|
+
* preset change can remount the delegation tool, and a stale answer would put
|
|
75980
|
+
* the guard back on the impossible branch.
|
|
75981
|
+
* @param ctx - Host context carrying the `tools` registry.
|
|
75982
|
+
* @returns a probe over the registry, or undefined when it exposes no readable
|
|
75983
|
+
* definitions (older harness generations), which keeps the configured mode.
|
|
75984
|
+
*/
|
|
75985
|
+
function routeParameterProbe(ctx) {
|
|
75986
|
+
const registry = ctx.tools;
|
|
75987
|
+
if (typeof registry?.definitions !== "function") return void 0;
|
|
75988
|
+
const definitions = registry.definitions.bind(registry);
|
|
75989
|
+
return (agent, toolName) => {
|
|
75990
|
+
let visible;
|
|
75991
|
+
try {
|
|
75992
|
+
visible = definitions(agent);
|
|
75993
|
+
} catch {
|
|
75994
|
+
return;
|
|
75995
|
+
}
|
|
75996
|
+
const definition = visible.find((entry) => entry?.name === toolName);
|
|
75997
|
+
if (definition === void 0) return void 0;
|
|
75998
|
+
const parameters = asRecord$1(definition.parameters);
|
|
75999
|
+
if (parameters === void 0) return void 0;
|
|
76000
|
+
const properties = asRecord$1(parameters["properties"]);
|
|
76001
|
+
if (properties !== void 0) return "provider" in properties || "model" in properties;
|
|
76002
|
+
return "provider" in parameters || "model" in parameters;
|
|
76003
|
+
};
|
|
76004
|
+
}
|
|
76005
|
+
/**
|
|
75852
76006
|
* Register the monotonic guard on the Host tool registry, and — when the Host
|
|
75853
76007
|
* context exposes Cordis events — enrich `list_subagent_models` output with the
|
|
75854
76008
|
* Session's split `{ provider, model }` routes and rewrite the misleading
|
|
@@ -75869,7 +76023,8 @@ function installSubagentModelAuthorization(ctx, sessions, config = {}) {
|
|
|
75869
76023
|
sessions,
|
|
75870
76024
|
toolNames,
|
|
75871
76025
|
inheritToolNames,
|
|
75872
|
-
scope
|
|
76026
|
+
scope,
|
|
76027
|
+
declaresRouteParameters: routeParameterProbe(ctx)
|
|
75873
76028
|
});
|
|
75874
76029
|
const disposeGuard = ctx.tools.guard((exec) => authorize(exec.agent, exec.name, exec.arguments));
|
|
75875
76030
|
const eventHost = ctx;
|
|
@@ -76511,6 +76666,7 @@ Before dispatching, check whether subagent model selection is enabled in this se
|
|
|
76511
76666
|
|
|
76512
76667
|
subagent_fork deliberately shares the parent agent's route (reusing conversation history and KV cache); use it only for reviews that require the coordinator's context, never as a shortcut around explicit routing.
|
|
76513
76668
|
It has no provider/model parameters, so the explicit-route rule under [State: Listed] does not apply to it; however, the guard still validates the route it inherits: if your current model is not in the allowlist, subagent_fork will be hard-rejected—switch to subagent with an explicit allowed route, or switch this session to an allowed model so subagent_fork becomes available again.
|
|
76669
|
+
When the parent route is itself one of the authorized routes, subagent_fork needs no route argument and no discovery tool: its admission is decided by the route the calling session is actually running, so it still works when list_subagent_models is absent or when a delegation tool exposes no route field. Prefer it exactly then—parent route authorized and the subtask needs this conversation's context—and prefer subagent when the subtask needs another model or a clean context. Never conclude that delegation is impossible from a broken explicit-route path alone: try subagent_fork once and read the denial, which names the parent route and the authorized routes.
|
|
76514
76670
|
Choose models based on task nature and model capability; keep model selection consistent across tasks of the same kind within a batch.
|
|
76515
76671
|
|
|
76516
76672
|
## R3 · Subagent Autonomy
|
|
@@ -76698,7 +76854,8 @@ Reset: fallback applies only to the current task. When the next task begins, alw
|
|
|
76698
76854
|
config: {
|
|
76699
76855
|
provider: "spawn",
|
|
76700
76856
|
toolName: "subagent",
|
|
76701
|
-
|
|
76857
|
+
modelSelection: true,
|
|
76858
|
+
modelDiscovery: true,
|
|
76702
76859
|
backgroundMode: "continuable"
|
|
76703
76860
|
}
|
|
76704
76861
|
},
|
|
@@ -78004,6 +78161,178 @@ function releaseListener$1(handle) {
|
|
|
78004
78161
|
}
|
|
78005
78162
|
handle?.dispose?.();
|
|
78006
78163
|
}
|
|
78164
|
+
//#endregion
|
|
78165
|
+
//#region src/host/compaction-route/index.ts
|
|
78166
|
+
/**
|
|
78167
|
+
* Route an automatic compaction summary to a model other than the one that
|
|
78168
|
+
* built the conversation.
|
|
78169
|
+
*
|
|
78170
|
+
* A host computes the summary on the conversation's own model unless its
|
|
78171
|
+
* compaction config names another route. That config is preset-owned, so this
|
|
78172
|
+
* plugin cannot offer it as a setting; it re-routes the call one layer down,
|
|
78173
|
+
* at the `llm/stream` waterfall, where a compaction request is identifiable by
|
|
78174
|
+
* its `purpose` and every preset passes through.
|
|
78175
|
+
*
|
|
78176
|
+
* Three rules shape the listener:
|
|
78177
|
+
*
|
|
78178
|
+
* - **Refuse before sending what cannot work.** A video block has no wire
|
|
78179
|
+
* fallback on a target that does not take video, so the request would fail
|
|
78180
|
+
* after paying for it. The payload is inspected first and the conversation
|
|
78181
|
+
* model keeps the call instead.
|
|
78182
|
+
* - **Buffer, then fall back.** A host turns an adapter throw into a terminal
|
|
78183
|
+
* `finish` chunk instead of an exception, and a half-written summary is
|
|
78184
|
+
* worthless, so the alternate attempt is collected first. Only a complete one
|
|
78185
|
+
* is released downstream; anything else falls back to the conversation model
|
|
78186
|
+
* and is recorded, because a fallback the operator cannot see is a cost they
|
|
78187
|
+
* did not agree to.
|
|
78188
|
+
* - **Do not impose an output cap.** The host asks for 65 536 tokens of summary
|
|
78189
|
+
* by default; the official client sends no cap at all and lets the route
|
|
78190
|
+
* decide, so the cap is dropped for the re-routed call.
|
|
78191
|
+
*
|
|
78192
|
+
* @module dsh-chatgpt-subscription/compaction-route
|
|
78193
|
+
*/
|
|
78194
|
+
/** How long one provider's model directory is reused. */
|
|
78195
|
+
const MODEL_CACHE_MS = 6e4;
|
|
78196
|
+
/**
|
|
78197
|
+
* Install the `llm/stream` listener.
|
|
78198
|
+
*
|
|
78199
|
+
* Returns `undefined` when the host exposes no event bus, so a caller can skip
|
|
78200
|
+
* installation instead of failing the plugin's load.
|
|
78201
|
+
*
|
|
78202
|
+
* @param ctx - structural context: the event bus and a logger.
|
|
78203
|
+
* @param deps - the LLM stream, the live target, and the optional directory.
|
|
78204
|
+
* @returns the live handle, or `undefined` on a host without an event bus.
|
|
78205
|
+
*/
|
|
78206
|
+
function installCompactionRoute(ctx, deps) {
|
|
78207
|
+
const on = ctx.on;
|
|
78208
|
+
if (typeof on !== "function") return void 0;
|
|
78209
|
+
let outcome = null;
|
|
78210
|
+
const rerouted = /* @__PURE__ */ new WeakSet();
|
|
78211
|
+
const directory = /* @__PURE__ */ new Map();
|
|
78212
|
+
const factsFor = async (target) => {
|
|
78213
|
+
if (deps.listModels === void 0) return {};
|
|
78214
|
+
const now = Date.now();
|
|
78215
|
+
const cached = directory.get(target.provider);
|
|
78216
|
+
const models = cached !== void 0 && now - cached.at < MODEL_CACHE_MS ? cached.models : await deps.listModels(target.provider).catch(() => []);
|
|
78217
|
+
if (cached === void 0 || now - cached.at >= MODEL_CACHE_MS) directory.set(target.provider, {
|
|
78218
|
+
at: now,
|
|
78219
|
+
models
|
|
78220
|
+
});
|
|
78221
|
+
const entry = models.find((model) => model.id === target.model);
|
|
78222
|
+
return entry === void 0 ? {} : { modalities: entry.inputModalities };
|
|
78223
|
+
};
|
|
78224
|
+
const dispose = on("llm/stream", async function* routeByStream(options, next) {
|
|
78225
|
+
if (options.purpose !== "compaction" || rerouted.has(options)) return yield* next();
|
|
78226
|
+
const target = deps.readTarget();
|
|
78227
|
+
if (target === null) return yield* next();
|
|
78228
|
+
if (target.provider === options.provider && target.model === options.model) return yield* next();
|
|
78229
|
+
const facts = await factsFor(target);
|
|
78230
|
+
const needs = payloadNeeds(options);
|
|
78231
|
+
const skip = compactionSkipReason(facts, needs);
|
|
78232
|
+
if (skip !== void 0) {
|
|
78233
|
+
outcome = {
|
|
78234
|
+
kind: "skipped",
|
|
78235
|
+
at: Date.now(),
|
|
78236
|
+
reason: skip
|
|
78237
|
+
};
|
|
78238
|
+
ctx.logger?.warn(`[dsh-chatgpt-subscription] compaction kept on ${String(options.provider)}/${String(options.model)}: ${target.provider}/${target.model} ${skip}`);
|
|
78239
|
+
return yield* next();
|
|
78240
|
+
}
|
|
78241
|
+
const reroutedOptions = withoutOutputCap(options, target);
|
|
78242
|
+
rerouted.add(reroutedOptions);
|
|
78243
|
+
const attempt = await collect(() => deps.stream(reroutedOptions));
|
|
78244
|
+
if (attempt.ok) {
|
|
78245
|
+
outcome = {
|
|
78246
|
+
kind: "routed",
|
|
78247
|
+
provider: target.provider,
|
|
78248
|
+
model: target.model,
|
|
78249
|
+
at: Date.now(),
|
|
78250
|
+
imagesProjected: needs.image && !compactionRoutesImages(facts)
|
|
78251
|
+
};
|
|
78252
|
+
for (const chunk of attempt.chunks) yield chunk;
|
|
78253
|
+
return;
|
|
78254
|
+
}
|
|
78255
|
+
outcome = {
|
|
78256
|
+
kind: "fell-back",
|
|
78257
|
+
provider: options.provider ?? "",
|
|
78258
|
+
model: options.model ?? "",
|
|
78259
|
+
at: Date.now(),
|
|
78260
|
+
reason: attempt.reason
|
|
78261
|
+
};
|
|
78262
|
+
ctx.logger?.warn(`[dsh-chatgpt-subscription] compaction fell back to ${String(options.provider)}/${String(options.model)}: ${target.provider}/${target.model} failed with ${attempt.reason}`);
|
|
78263
|
+
return yield* next();
|
|
78264
|
+
}, { global: true });
|
|
78265
|
+
return {
|
|
78266
|
+
status: () => outcome,
|
|
78267
|
+
dispose: () => {
|
|
78268
|
+
if (typeof dispose === "function") dispose();
|
|
78269
|
+
}
|
|
78270
|
+
};
|
|
78271
|
+
}
|
|
78272
|
+
/**
|
|
78273
|
+
* Read what the payload actually carries.
|
|
78274
|
+
* @param options - the compaction request.
|
|
78275
|
+
* @returns whether it carries an image or a video block.
|
|
78276
|
+
*/
|
|
78277
|
+
function payloadNeeds(options) {
|
|
78278
|
+
let image = false;
|
|
78279
|
+
let video = false;
|
|
78280
|
+
for (const message of options.messages ?? []) for (const block of message.content ?? []) if (block.type === "image") image = true;
|
|
78281
|
+
else if (block.type === "video") video = true;
|
|
78282
|
+
return {
|
|
78283
|
+
image,
|
|
78284
|
+
video
|
|
78285
|
+
};
|
|
78286
|
+
}
|
|
78287
|
+
/**
|
|
78288
|
+
* Build the request for the chosen target: the same conversation, no output cap.
|
|
78289
|
+
* @param options - the original compaction request.
|
|
78290
|
+
* @param target - the route to send it to.
|
|
78291
|
+
* @returns a detached request object.
|
|
78292
|
+
*/
|
|
78293
|
+
function withoutOutputCap(options, target) {
|
|
78294
|
+
const { maxTokens: _dropped, ...rest } = options;
|
|
78295
|
+
return {
|
|
78296
|
+
...rest,
|
|
78297
|
+
provider: target.provider,
|
|
78298
|
+
model: target.model
|
|
78299
|
+
};
|
|
78300
|
+
}
|
|
78301
|
+
/**
|
|
78302
|
+
* Run one attempt to completion, keeping its chunks only when it finished
|
|
78303
|
+
* cleanly.
|
|
78304
|
+
*
|
|
78305
|
+
* The stream is opened inside the try, not before it: an adapter that rejects
|
|
78306
|
+
* before yielding anything (an exhausted quota, a rejected credential) throws
|
|
78307
|
+
* from the call itself, and that is the same fallback case as a failed stream.
|
|
78308
|
+
*/
|
|
78309
|
+
async function collect(open) {
|
|
78310
|
+
const chunks = [];
|
|
78311
|
+
let finishKind;
|
|
78312
|
+
try {
|
|
78313
|
+
for await (const chunk of open()) {
|
|
78314
|
+
chunks.push(chunk);
|
|
78315
|
+
if (chunk.type === "finish") finishKind = chunk.reason?.kind;
|
|
78316
|
+
}
|
|
78317
|
+
} catch (error) {
|
|
78318
|
+
return {
|
|
78319
|
+
ok: false,
|
|
78320
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
78321
|
+
};
|
|
78322
|
+
}
|
|
78323
|
+
if (finishKind === void 0) return {
|
|
78324
|
+
ok: false,
|
|
78325
|
+
reason: "the stream ended without a finish chunk"
|
|
78326
|
+
};
|
|
78327
|
+
if (finishKind === "error" || finishKind === "aborted") return {
|
|
78328
|
+
ok: false,
|
|
78329
|
+
reason: finishKind
|
|
78330
|
+
};
|
|
78331
|
+
return {
|
|
78332
|
+
ok: true,
|
|
78333
|
+
chunks
|
|
78334
|
+
};
|
|
78335
|
+
}
|
|
78007
78336
|
const DEFAULT_NO_ANSWER_RESUME_OPTIONS = {
|
|
78008
78337
|
maxResumes: 2,
|
|
78009
78338
|
text: "Your previous response ended without an answer and without calling a tool. Continue from where you left off: either state the conclusion you already reached, or make the single next tool call that moves the task forward. Do not restart the analysis."
|
|
@@ -79243,6 +79572,22 @@ function apply(ctx, pluginConfig = {}) {
|
|
|
79243
79572
|
const store = createPlatformTokenStore();
|
|
79244
79573
|
const preferences = registerPreferenceStore(ctx.settings);
|
|
79245
79574
|
preferences.hydrate().catch(() => void 0);
|
|
79575
|
+
ctx.effect(() => {
|
|
79576
|
+
const llm = ctx.llm;
|
|
79577
|
+
const handle = installCompactionRoute({
|
|
79578
|
+
on: (event, listener, options) => ctx.on?.(event, listener, options),
|
|
79579
|
+
logger: ctx.logger
|
|
79580
|
+
}, {
|
|
79581
|
+
stream: (options) => llm.stream(options),
|
|
79582
|
+
listModels: (provider) => llm.listModels(provider),
|
|
79583
|
+
readTarget: () => preferences.status().compactionRoute ?? null
|
|
79584
|
+
});
|
|
79585
|
+
if (handle === void 0) {
|
|
79586
|
+
ctx.logger.warn("[dsh-chatgpt-subscription] compaction route skipped: this harness exposes no event bus");
|
|
79587
|
+
return () => void 0;
|
|
79588
|
+
}
|
|
79589
|
+
return () => handle.dispose();
|
|
79590
|
+
}, "dsh-chatgpt-subscription: compaction route");
|
|
79246
79591
|
const antigravityStore = new FileCredentialStore$3();
|
|
79247
79592
|
const antigravityAccountPool = new AccountPoolStore(void 0, void 0, antigravityStore);
|
|
79248
79593
|
const antigravityModelSettings = new FileModelSettingsStore$2();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import { NS } from './locales.ts';
|
|
3
|
+
/** The package whose page this entry configures. */
|
|
4
|
+
export declare const COMPACTION_ROUTE_PACKAGE = "@eddyskywalker/dsh-chatgpt-subscription";
|
|
5
|
+
/** The view the page asks a configuration entry for. */
|
|
6
|
+
export interface PluginConfigViewLike {
|
|
7
|
+
readonly view: 'summary' | 'page';
|
|
8
|
+
}
|
|
9
|
+
/** Props the plugin-manager bundle page renders a configuration entry with. */
|
|
10
|
+
export type CompactionRouteBundleConfigProps = PropsLocale<typeof NS> & PluginConfigViewLike;
|
|
11
|
+
/**
|
|
12
|
+
* Render the compaction-model card on this package's bundle page only.
|
|
13
|
+
*
|
|
14
|
+
* Split in two so the hooks below never mount for the summary view: that view
|
|
15
|
+
* is a one-liner drawn beside the card, and fetching this plugin's preferences
|
|
16
|
+
* for it would be a request nobody asked for.
|
|
17
|
+
*/
|
|
18
|
+
export declare function CompactionRouteBundleConfig(props: CompactionRouteBundleConfigProps): React.JSX.Element | null;
|
|
19
|
+
//# sourceMappingURL=CompactionRouteBundleConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompactionRouteBundleConfig.d.ts","sourceRoot":"","sources":["../../../src/client/CompactionRouteBundleConfig.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAKjC,oDAAoD;AACpD,eAAO,MAAM,wBAAwB,4CAA4C,CAAA;AAEjF,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAA;CAClC;AAED,+EAA+E;AAC/E,MAAM,MAAM,gCAAgC,GACxC,WAAW,CAAC,OAAO,EAAE,CAAC,GACtB,oBAAoB,CAAA;AAExB;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,gCAAgC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAG7G"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SubscriptionPreferencesDto } from '../shared/contracts.ts';
|
|
2
|
+
import type { SubscriptionApi } from './api.ts';
|
|
3
|
+
/** Labels the settings page supplies, so this card carries no locale of its own. */
|
|
4
|
+
export interface CompactionRouteCardLabels {
|
|
5
|
+
title: string;
|
|
6
|
+
hint: string;
|
|
7
|
+
provider: string;
|
|
8
|
+
model: string;
|
|
9
|
+
save: string;
|
|
10
|
+
clear: string;
|
|
11
|
+
change: string;
|
|
12
|
+
/** Shown as the current value when no route is configured. */
|
|
13
|
+
follow: string;
|
|
14
|
+
saved: string;
|
|
15
|
+
failed: string;
|
|
16
|
+
/** Shown when the chosen model cannot take video, so compaction would fall back. */
|
|
17
|
+
noVideo: string;
|
|
18
|
+
/** Shown when the chosen model cannot take images, so they become placeholders. */
|
|
19
|
+
noImage: string;
|
|
20
|
+
empty: string;
|
|
21
|
+
}
|
|
22
|
+
export interface CompactionRouteCardProps {
|
|
23
|
+
readonly api: SubscriptionApi;
|
|
24
|
+
readonly preferences: SubscriptionPreferencesDto | null;
|
|
25
|
+
readonly disabled?: boolean;
|
|
26
|
+
readonly labels: CompactionRouteCardLabels;
|
|
27
|
+
readonly onSaved: (preferences: SubscriptionPreferencesDto) => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Choose the model an automatic compaction summarizes on.
|
|
31
|
+
*
|
|
32
|
+
* The route lives in this plugin's preferences and is applied by the host's
|
|
33
|
+
* `llm/stream` listener, so a saved choice takes effect on the next compaction
|
|
34
|
+
* without a restart. Both selects are needed together: a model id alone belongs
|
|
35
|
+
* to no route.
|
|
36
|
+
*
|
|
37
|
+
* The picker loads its directory on demand rather than on mount: opening the
|
|
38
|
+
* settings page must not cost a request to every line (that page is opened for
|
|
39
|
+
* unrelated reasons all the time), and the card already knows the saved route
|
|
40
|
+
* from the status it was rendered with.
|
|
41
|
+
*/
|
|
42
|
+
export declare function CompactionRouteCard({ api, preferences, disabled, labels, onSaved }: CompactionRouteCardProps): React.JSX.Element;
|
|
43
|
+
//# sourceMappingURL=CompactionRouteCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompactionRouteCard.d.ts","sourceRoot":"","sources":["../../../src/client/CompactionRouteCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,0BAA0B,EAC3B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,oFAAoF;AACpF,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAA;IACf,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAA;IAC7B,QAAQ,CAAC,WAAW,EAAE,0BAA0B,GAAG,IAAI,CAAA;IACvD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAA;IAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,0BAA0B,KAAK,IAAI,CAAA;CACpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,QAAgB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,wBAAwB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAsIxI"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeviceLoginStartDto, LoginEventDto, LoginStartDto, PluginStatusDto, QuotaStatusDto, ConnectionTestDto, SubscriptionPreferencesDto, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts';
|
|
1
|
+
import type { DeviceLoginStartDto, LoginEventDto, LoginStartDto, PluginStatusDto, QuotaStatusDto, ConnectionTestDto, SubscriptionPreferencesDto, SubscriptionPreferencesUpdateDto, CompactionCandidatesDto } from '../shared/contracts.ts';
|
|
2
2
|
export declare class SubscriptionApi {
|
|
3
3
|
status(): Promise<PluginStatusDto>;
|
|
4
4
|
startLogin(): Promise<LoginStartDto>;
|
|
@@ -52,6 +52,8 @@ export declare class SubscriptionApi {
|
|
|
52
52
|
useResetCredit(): Promise<QuotaStatusDto>;
|
|
53
53
|
testConnection(): Promise<ConnectionTestDto>;
|
|
54
54
|
updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto>;
|
|
55
|
+
/** Every route a compaction summary may be pointed at, read per call. */
|
|
56
|
+
compactionCandidates(): Promise<CompactionCandidatesDto>;
|
|
55
57
|
events(loginId: string): EventSource;
|
|
56
58
|
}
|
|
57
59
|
export declare function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/client/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,0BAA0B,EAC1B,gCAAgC,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/client/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,0BAA0B,EAC1B,gCAAgC,EAChC,uBAAuB,EACxB,MAAM,wBAAwB,CAAA;AAE/B,qBAAa,eAAe;IAC1B,MAAM,IAAI,OAAO,CAAC,eAAe,CAAC;IAIlC,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;IAIpC;;;;;;OAMG;IACH,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAIhD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAI7D,kEAAkE;IAClE,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,aAAa,EAAE,KAAK,CAAA;KAAE,CAAC;IAI7D;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,gBAAgB,GAAG,UAAU,GAAG,SAAS,EAAE,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IAIzM;;;;;;;;OAQG;IACH,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IAI1D,6EAA6E;IAC7E,yBAAyB,IAAI,OAAO,CAAC,eAAe,CAAC;IAIrD;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;IAIzE,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;IAInC,YAAY,IAAI,OAAO,CAAC,cAAc,CAAC;IAIvC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC;IAIzC,cAAc,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI5C,iBAAiB,CAAC,KAAK,EAAE,gCAAgC,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAI/F,yEAAyE;IACzE,oBAAoB,IAAI,OAAO,CAAC,uBAAuB,CAAC;IAIxD,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW;CAGrC;AAmBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,aAAa,GAAG,IAAI,CAOjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAgBnE,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAQ/D,OAAO,EAAoD,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAGtH,OAAO,EAA0C,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAGlG,OAAO,EAAqD,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAExH,OAAO,EAA+C,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAM5G,OAAO,EAAqD,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAKxH,OAAO,EAA0D,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAElI,OAAO,EAA0C,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAElG,OAAO,EAA+C,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAG5G,OAAO,EAAiD,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGhH,OAAO,EAAwC,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAG9F,OAAO,EAAkD,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAMlH,OAAO,EAA6D,KAAK,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAExI,OAAO,QAAQ,kCAAkC,CAAC;IAChD;;;;;;;OAOG;IACH,UAAU,kBAAkB;QAC1B,0BAA0B,EAAE,SAAS,CAAA;QACrC,iBAAiB,EAAE,oBAAoB,CAAA;QACvC,YAAY,EAAE,eAAe,CAAA;QAC7B,kBAAkB,EAAE,oBAAoB,CAAA;QACxC,eAAe,EAAE,iBAAiB,CAAA;QAClC,kBAAkB,EAAE,oBAAoB,CAAA;QACxC,qBAAqB,EAAE,sBAAsB,CAAA;QAC7C,YAAY,EAAE,eAAe,CAAA;QAC7B,eAAe,EAAE,iBAAiB,CAAA;QAClC,gBAAgB,EAAE,kBAAkB,CAAA;QACpC,WAAW,EAAE,cAAc,CAAA;QAC3B,gBAAgB,EAAE,mBAAmB,CAAA;QACrC,sBAAsB,EAAE,wBAAwB,CAAA;KACjD;CACF;AAED,eAAO,MAAM,MAAM,UAQlB,CAAA;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAsO9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../../../src/client/locales-ru/hub.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../../../src/client/locales-ru/hub.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CA4NhD,CAAA"}
|