@eddyskywalker/dsh-chatgpt-subscription 0.48.0 → 0.48.2
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 +19 -0
- package/lib/client.js.map +1 -1
- package/lib/index.js +523 -77
- package/lib/types/compat.d.ts +1 -1
- package/lib/types/host/compaction-policy-guard.d.ts.map +1 -1
- package/lib/types/host/plan-mode-cache-guard.d.ts.map +1 -1
- package/lib/types/host/ptc-sdk-cache-guard.d.ts.map +1 -1
- package/lib/types/host/tool-result-pruner-guard.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -145,7 +145,7 @@ const ROUTE_PREFIX$5 = "/api/dsh-chatgpt-subscription";
|
|
|
145
145
|
* `test/responses-client.test.ts` asserts the two agree, so a release that
|
|
146
146
|
* forgets this constant fails the suite instead of shipping quietly.
|
|
147
147
|
*/
|
|
148
|
-
const PLUGIN_VERSION = "0.48.
|
|
148
|
+
const PLUGIN_VERSION = "0.48.2";
|
|
149
149
|
const CODEX_CHATGPT_PROVIDER_ID = "codex-chatgpt";
|
|
150
150
|
const CODEX_API_BASE = "https://chatgpt.com/backend-api/codex";
|
|
151
151
|
const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses`;
|
|
@@ -80832,10 +80832,11 @@ function installCompactionPrompt(ctx) {
|
|
|
80832
80832
|
* realm 的 `ctx.reflect.store` 里,宿主平面根本看不到它,也就没有地方把
|
|
80833
80833
|
* "这场会话的 provider 该不该修剪" 插进去。
|
|
80834
80834
|
*
|
|
80835
|
-
*
|
|
80835
|
+
* 这一层守卫因此待在**宿主平面**:它不替换任何行,只在下述时机把已经挂载
|
|
80836
80836
|
* 的 `toolResultPruner` 实例的 `pruneSession` 包一层 provider 短路 ——
|
|
80837
|
-
* 安装时先扫一遍,此后每个 agent 开始一步(`agent/pre-step
|
|
80838
|
-
* (`agent/request-error
|
|
80837
|
+
* 安装时先扫一遍,此后每个 agent 开始一步(`agent/pre-step`)、每次发起请求
|
|
80838
|
+
* (`agent/request`)或撞上上下文溢出(`agent/request-error`)时再扫一遍。
|
|
80839
|
+
* 三个事件都是 Cordis **瀑布**事件,监听器必须转交 `next()`(见下)。两个位置都要看:
|
|
80839
80840
|
*
|
|
80840
80841
|
* - `ctx.reflect.store`(宿主平面自己的服务记录,含安装后才挂上的实例);
|
|
80841
80842
|
* - `agent.ctx.get('toolResultPruner')` 与 `agent.ctx.reflect.store`
|
|
@@ -80844,6 +80845,17 @@ function installCompactionPrompt(ctx) {
|
|
|
80844
80845
|
* 包装按 `WeakSet` 幂等,重复事件不会叠第二层;`dispose()` 逐条还原原方法并
|
|
80845
80846
|
* 摘掉监听器。
|
|
80846
80847
|
*
|
|
80848
|
+
* ## 瀑布事件必须转交 `next()`
|
|
80849
|
+
*
|
|
80850
|
+
* `agent/pre-step` / `agent/request` / `agent/request-error` 是 Cordis **瀑布**事件
|
|
80851
|
+
* (`ctx.waterfall`),最后一个参数就是 `next`。瀑布的返回值是**最外层监听器的返回值**:不调用 `next()`
|
|
80852
|
+
* 等于替整条链做了决定——后续监听器(连同内置的默认行为)一个都不跑,瀑布的返回值
|
|
80853
|
+
* 也变成监听器自己的返回值。于是 `agent-loop` 读 `decision.kind` 时拿到
|
|
80854
|
+
* `undefined`,每一轮都炸成
|
|
80855
|
+
* `TypeError: Cannot read properties of undefined (reading 'kind')`。
|
|
80856
|
+
* 本守卫是旁路,扫描失败只吞掉扫描本身,但 `next()` 在所有分支上都要被调用并原样
|
|
80857
|
+
* 交回去。
|
|
80858
|
+
*
|
|
80847
80859
|
* ## 只做短路,不改语义
|
|
80848
80860
|
*
|
|
80849
80861
|
* 包装后的 `pruneSession` 只有一条分支:`shouldSkipPruningForSession` 命中就
|
|
@@ -80852,8 +80864,12 @@ function installCompactionPrompt(ctx) {
|
|
|
80852
80864
|
*
|
|
80853
80865
|
* @module @eddyskywalker/dsh-chatgpt-subscription/host/tool-result-pruner-guard
|
|
80854
80866
|
*/
|
|
80855
|
-
/**
|
|
80856
|
-
const GUARDED_EVENTS$1 = [
|
|
80867
|
+
/** 会先跑一遍扫描的宿主事件(全部是 Cordis 瀑布事件,监听器必须转交 `next()`)。 */
|
|
80868
|
+
const GUARDED_EVENTS$1 = [
|
|
80869
|
+
"agent/pre-step",
|
|
80870
|
+
"agent/request",
|
|
80871
|
+
"agent/request-error"
|
|
80872
|
+
];
|
|
80857
80873
|
/**
|
|
80858
80874
|
* 安装跨 preset 守卫。
|
|
80859
80875
|
*
|
|
@@ -80869,6 +80885,8 @@ function installToolResultPrunerGuard(ctx, options = {}) {
|
|
|
80869
80885
|
const skipSet = resolveSkipProviders(options.skipProviders ?? DEFAULT_SKIP_PROVIDERS);
|
|
80870
80886
|
/** 已包装过的实例(幂等标记)。 */
|
|
80871
80887
|
const alreadyWrapped = /* @__PURE__ */ new WeakSet();
|
|
80888
|
+
/** 已包装过的「方法宿主 + 方法名」:同一个原型不叠第二层包装。 */
|
|
80889
|
+
const patchedMethods = /* @__PURE__ */ new WeakMap();
|
|
80872
80890
|
/** 已包装的方法,销毁时逐条还原。 */
|
|
80873
80891
|
const restores = [];
|
|
80874
80892
|
/** 事件监听的 disposer。 */
|
|
@@ -80883,22 +80901,25 @@ function installToolResultPrunerGuard(ctx, options = {}) {
|
|
|
80883
80901
|
const wrapPruner = (pruner) => {
|
|
80884
80902
|
if (disposed || !isRecord$8(pruner)) return false;
|
|
80885
80903
|
if (alreadyWrapped.has(pruner)) return false;
|
|
80886
|
-
const target = pruner;
|
|
80887
|
-
|
|
80888
|
-
if (
|
|
80889
|
-
|
|
80904
|
+
const target = resolveMethodTarget$3(pruner, "pruneSession");
|
|
80905
|
+
if (target === void 0) return false;
|
|
80906
|
+
if (alreadyPatched$3(patchedMethods, target.holder, target.name)) {
|
|
80907
|
+
alreadyWrapped.add(pruner);
|
|
80908
|
+
return false;
|
|
80909
|
+
}
|
|
80910
|
+
const original = target.original;
|
|
80890
80911
|
const replacement = function(session) {
|
|
80891
80912
|
if (shouldSkipPruningForSession(session, skipSet)) return {
|
|
80892
80913
|
pruned: [],
|
|
80893
80914
|
charsRemoved: 0
|
|
80894
80915
|
};
|
|
80895
|
-
return original.call(this, session);
|
|
80916
|
+
return original.call(this ?? pruner, session);
|
|
80896
80917
|
};
|
|
80897
|
-
target
|
|
80918
|
+
if (!installMethod$3(target, replacement)) return false;
|
|
80919
|
+
markPatched$3(patchedMethods, target.holder, target.name);
|
|
80898
80920
|
alreadyWrapped.add(pruner);
|
|
80899
|
-
restores.push({
|
|
80900
|
-
target
|
|
80901
|
-
original
|
|
80921
|
+
restores.push(() => {
|
|
80922
|
+
restoreMethod$3(target);
|
|
80902
80923
|
});
|
|
80903
80924
|
return true;
|
|
80904
80925
|
};
|
|
@@ -80965,16 +80986,32 @@ function installToolResultPrunerGuard(ctx, options = {}) {
|
|
|
80965
80986
|
/**
|
|
80966
80987
|
* 事件回调:先扫宿主平面,再扫事件里那个 agent 自己的 realm。
|
|
80967
80988
|
*
|
|
80968
|
-
*
|
|
80989
|
+
* ## 瀑布必须转交
|
|
80990
|
+
*
|
|
80991
|
+
* `agent/pre-step` / `agent/request` / `agent/request-error` 在 DSH 里是 Cordis
|
|
80992
|
+
* **瀑布**事件(`ctx.waterfall`),最后一个参数就是 `next`。瀑布的返回值是**最外层监听器
|
|
80993
|
+
* 的返回值**:不调用 `next()` 等于替整条链做了决定——后续监听器(连同内置的
|
|
80994
|
+
* 默认行为)一个都不会跑,瀑布的返回值也变成监听器自己的返回值(这里是
|
|
80995
|
+
* `undefined`)。`agent-loop` 随后读 `decision.kind`,于是每一轮都炸成
|
|
80996
|
+
* `TypeError: Cannot read properties of undefined (reading 'kind')`。
|
|
80997
|
+
*
|
|
80998
|
+
* 所以扫描照旧做(扫描失败也只吞掉扫描本身),但 `next()` **必须**在所有分支上
|
|
80999
|
+
* 被调用,并把它的结果原样交回去。
|
|
81000
|
+
*
|
|
81001
|
+
* @param args - 事件参数(最后一个参数可能是 `next`)。
|
|
81002
|
+
* @returns `next()` 的结果;没有 `next` 时为 `undefined`。
|
|
80969
81003
|
*/
|
|
80970
81004
|
const handleAgentEvent = (...args) => {
|
|
81005
|
+
const next = args.length > 0 && typeof args[args.length - 1] === "function" ? args[args.length - 1] : void 0;
|
|
80971
81006
|
try {
|
|
80972
81007
|
scanAndWrap();
|
|
80973
81008
|
const agentCtx = findAgentContext$1(args);
|
|
80974
|
-
if (agentCtx
|
|
80975
|
-
|
|
80976
|
-
|
|
81009
|
+
if (agentCtx !== void 0) {
|
|
81010
|
+
scanStore(agentCtx);
|
|
81011
|
+
wrapServiceFrom(agentCtx, PRUNER_SERVICE_NAME);
|
|
81012
|
+
}
|
|
80977
81013
|
} catch {}
|
|
81014
|
+
return next === void 0 ? void 0 : next();
|
|
80978
81015
|
};
|
|
80979
81016
|
for (const event of GUARDED_EVENTS$1) {
|
|
80980
81017
|
const disposer = subscribe$3(host, event, handleAgentEvent);
|
|
@@ -80989,7 +81026,9 @@ function installToolResultPrunerGuard(ctx, options = {}) {
|
|
|
80989
81026
|
for (const disposer of disposers.splice(0)) try {
|
|
80990
81027
|
disposer();
|
|
80991
81028
|
} catch {}
|
|
80992
|
-
for (const
|
|
81029
|
+
for (const restore of restores.splice(0)) try {
|
|
81030
|
+
restore();
|
|
81031
|
+
} catch {}
|
|
80993
81032
|
}
|
|
80994
81033
|
};
|
|
80995
81034
|
}
|
|
@@ -81082,6 +81121,103 @@ function readContext$1(value) {
|
|
|
81082
81121
|
function isRecord$8(value) {
|
|
81083
81122
|
return typeof value === "object" && value !== null;
|
|
81084
81123
|
}
|
|
81124
|
+
/**
|
|
81125
|
+
* 定位一个待包装的方法。
|
|
81126
|
+
*
|
|
81127
|
+
* Cordis 的 `Service` 代理在读属性时会把方法**绑定到读取它的那一层作用域**
|
|
81128
|
+
* (`Reflect.get(target, prop, receiver).bind(receiver)`)。于是
|
|
81129
|
+
* `const original = tools.register` 拿到的是一份**已经绑到根作用域**的函数;再
|
|
81130
|
+
* `original.call(tools, …)` 就把根作用域硬塞回每一个 preset 的注册里,全局层
|
|
81131
|
+
* 于是撞上 "already registered"。
|
|
81132
|
+
*
|
|
81133
|
+
* 真正要的是**原型上那份未绑定的方法**:包装器用 `original.call(this, …)` 把
|
|
81134
|
+
* 调用方自己的 receiver 传下去,服务里的 `this.ctx` 才留在调用方那一层作用域
|
|
81135
|
+
* (child ctx)里。方法挂在原型上时(真实 Cordis `Service`),包装也写在原型上;
|
|
81136
|
+
* 只有普通假对象(单测)才把方法作为自有属性挂在实例上。
|
|
81137
|
+
*
|
|
81138
|
+
* @param service - 服务实例(可以是 Cordis 的跟踪代理)。
|
|
81139
|
+
* @param name - 方法名。
|
|
81140
|
+
* @returns 目标;方法不存在时为 `undefined`。
|
|
81141
|
+
*/
|
|
81142
|
+
function resolveMethodTarget$3(service, name) {
|
|
81143
|
+
if (typeof service !== "object" || service === null) return void 0;
|
|
81144
|
+
const own = service;
|
|
81145
|
+
if (Object.prototype.hasOwnProperty.call(own, name)) {
|
|
81146
|
+
const original = own[name];
|
|
81147
|
+
if (typeof original !== "function") return void 0;
|
|
81148
|
+
return {
|
|
81149
|
+
holder: own,
|
|
81150
|
+
name,
|
|
81151
|
+
original,
|
|
81152
|
+
descriptor: Object.getOwnPropertyDescriptor(own, name)
|
|
81153
|
+
};
|
|
81154
|
+
}
|
|
81155
|
+
const proto = Object.getPrototypeOf(service);
|
|
81156
|
+
if (proto === null) return void 0;
|
|
81157
|
+
if (proto === Object.prototype || proto === Function.prototype) return void 0;
|
|
81158
|
+
const original = proto[name];
|
|
81159
|
+
if (typeof original !== "function") return void 0;
|
|
81160
|
+
return {
|
|
81161
|
+
holder: proto,
|
|
81162
|
+
name,
|
|
81163
|
+
original,
|
|
81164
|
+
descriptor: Object.getOwnPropertyDescriptor(proto, name)
|
|
81165
|
+
};
|
|
81166
|
+
}
|
|
81167
|
+
/**
|
|
81168
|
+
* 把一个包装写到方法所在的位置上。
|
|
81169
|
+
*
|
|
81170
|
+
* @param target - 目标。
|
|
81171
|
+
* @param replacement - 包装实现。
|
|
81172
|
+
* @returns 是否装上了。
|
|
81173
|
+
*/
|
|
81174
|
+
function installMethod$3(target, replacement) {
|
|
81175
|
+
try {
|
|
81176
|
+
Object.defineProperty(target.holder, target.name, {
|
|
81177
|
+
value: replacement,
|
|
81178
|
+
configurable: true,
|
|
81179
|
+
writable: true,
|
|
81180
|
+
enumerable: target.descriptor?.enumerable ?? false
|
|
81181
|
+
});
|
|
81182
|
+
return true;
|
|
81183
|
+
} catch {
|
|
81184
|
+
return false;
|
|
81185
|
+
}
|
|
81186
|
+
}
|
|
81187
|
+
/**
|
|
81188
|
+
* 还原方法所在位置上原来的实现。
|
|
81189
|
+
*
|
|
81190
|
+
* @param target - 目标。
|
|
81191
|
+
*/
|
|
81192
|
+
function restoreMethod$3(target) {
|
|
81193
|
+
try {
|
|
81194
|
+
if (target.descriptor === void 0) Reflect.deleteProperty(target.holder, target.name);
|
|
81195
|
+
else Object.defineProperty(target.holder, target.name, target.descriptor);
|
|
81196
|
+
} catch {}
|
|
81197
|
+
}
|
|
81198
|
+
/**
|
|
81199
|
+
* 判断某个「方法宿主 + 方法名」是不是已经被本守卫包过。
|
|
81200
|
+
*
|
|
81201
|
+
* @param patched - 已包装记录。
|
|
81202
|
+
* @param holder - 方法宿主。
|
|
81203
|
+
* @param name - 方法名。
|
|
81204
|
+
* @returns 是否已经包过。
|
|
81205
|
+
*/
|
|
81206
|
+
function alreadyPatched$3(patched, holder, name) {
|
|
81207
|
+
return patched.get(holder)?.has(name) === true;
|
|
81208
|
+
}
|
|
81209
|
+
/**
|
|
81210
|
+
* 记下某个「方法宿主 + 方法名」已经被本守卫包过。
|
|
81211
|
+
*
|
|
81212
|
+
* @param patched - 已包装记录。
|
|
81213
|
+
* @param holder - 方法宿主。
|
|
81214
|
+
* @param name - 方法名。
|
|
81215
|
+
*/
|
|
81216
|
+
function markPatched$3(patched, holder, name) {
|
|
81217
|
+
const names = patched.get(holder);
|
|
81218
|
+
if (names === void 0) patched.set(holder, /* @__PURE__ */ new Set([name]));
|
|
81219
|
+
else names.add(name);
|
|
81220
|
+
}
|
|
81085
81221
|
//#endregion
|
|
81086
81222
|
//#region src/host/plan-mode-cache-guard.ts
|
|
81087
81223
|
/** 没有 scope 的装配(会话标题之类)用的桶键。 */
|
|
@@ -81136,6 +81272,8 @@ function subscribe$2(ctx, event, listener) {
|
|
|
81136
81272
|
function installPlanModeCacheGuard(ctx) {
|
|
81137
81273
|
const states = /* @__PURE__ */ new WeakMap();
|
|
81138
81274
|
const restores = [];
|
|
81275
|
+
/** 已包装过的「方法宿主 + 方法名」:同一个原型不叠第二层包装。 */
|
|
81276
|
+
const patchedMethods = /* @__PURE__ */ new WeakMap();
|
|
81139
81277
|
let closed = false;
|
|
81140
81278
|
/**
|
|
81141
81279
|
* 取(或建)一个桶的状态。
|
|
@@ -81210,22 +81348,25 @@ function installPlanModeCacheGuard(ctx) {
|
|
|
81210
81348
|
offPreStep();
|
|
81211
81349
|
});
|
|
81212
81350
|
const wrap = (tools) => {
|
|
81213
|
-
if (tools === void 0
|
|
81214
|
-
const
|
|
81215
|
-
|
|
81351
|
+
if (tools === void 0) return;
|
|
81352
|
+
const target = resolveMethodTarget$2(tools, "register");
|
|
81353
|
+
if (target === void 0) return;
|
|
81354
|
+
if (alreadyPatched$2(patchedMethods, target.holder, target.name)) return;
|
|
81355
|
+
const original = target.original;
|
|
81356
|
+
const wrapped = function(...args) {
|
|
81357
|
+
const receiver = this ?? tools;
|
|
81358
|
+
const definition = args[0];
|
|
81359
|
+
const options = args[1];
|
|
81216
81360
|
if (definition?.name === "exit_plan_mode" && options !== void 0 && options !== null && "when" in options) {
|
|
81217
81361
|
const { when: _dropped, ...rest } = options;
|
|
81218
|
-
return original.call(
|
|
81362
|
+
return original.call(receiver, definition, rest);
|
|
81219
81363
|
}
|
|
81220
|
-
return original.call(
|
|
81364
|
+
return original.call(receiver, definition, options);
|
|
81221
81365
|
};
|
|
81222
|
-
|
|
81223
|
-
|
|
81224
|
-
} catch {
|
|
81225
|
-
return;
|
|
81226
|
-
}
|
|
81366
|
+
if (!installMethod$2(target, wrapped)) return;
|
|
81367
|
+
markPatched$2(patchedMethods, target.holder, target.name);
|
|
81227
81368
|
restores.push(() => {
|
|
81228
|
-
|
|
81369
|
+
restoreMethod$2(target);
|
|
81229
81370
|
});
|
|
81230
81371
|
if (typeof tools.get === "function") try {
|
|
81231
81372
|
if (tools.get("exit_plan_mode") !== void 0) logWarn(ctx, "[dsh-chatgpt-subscription] plan-mode cache guard was installed after exit_plan_mode was already registered; this session keeps the conditional admission");
|
|
@@ -81281,6 +81422,103 @@ function logWarn(ctx, message) {
|
|
|
81281
81422
|
logger?.warn(message);
|
|
81282
81423
|
} catch {}
|
|
81283
81424
|
}
|
|
81425
|
+
/**
|
|
81426
|
+
* 定位一个待包装的方法。
|
|
81427
|
+
*
|
|
81428
|
+
* Cordis 的 `Service` 代理在读属性时会把方法**绑定到读取它的那一层作用域**
|
|
81429
|
+
* (`Reflect.get(target, prop, receiver).bind(receiver)`)。于是
|
|
81430
|
+
* `const original = tools.register` 拿到的是一份**已经绑到根作用域**的函数;再
|
|
81431
|
+
* `original.call(tools, …)` 就把根作用域硬塞回每一个 preset 的注册里,全局层
|
|
81432
|
+
* 于是撞上 "already registered"。
|
|
81433
|
+
*
|
|
81434
|
+
* 真正要的是**原型上那份未绑定的方法**:包装器用 `original.call(this, …)` 把
|
|
81435
|
+
* 调用方自己的 receiver 传下去,服务里的 `this.ctx` 才留在调用方那一层作用域
|
|
81436
|
+
* (child ctx)里。方法挂在原型上时(真实 Cordis `Service`),包装也写在原型上;
|
|
81437
|
+
* 只有普通假对象(单测)才把方法作为自有属性挂在实例上。
|
|
81438
|
+
*
|
|
81439
|
+
* @param service - 服务实例(可以是 Cordis 的跟踪代理)。
|
|
81440
|
+
* @param name - 方法名。
|
|
81441
|
+
* @returns 目标;方法不存在时为 `undefined`。
|
|
81442
|
+
*/
|
|
81443
|
+
function resolveMethodTarget$2(service, name) {
|
|
81444
|
+
if (typeof service !== "object" || service === null) return void 0;
|
|
81445
|
+
const own = service;
|
|
81446
|
+
if (Object.prototype.hasOwnProperty.call(own, name)) {
|
|
81447
|
+
const original = own[name];
|
|
81448
|
+
if (typeof original !== "function") return void 0;
|
|
81449
|
+
return {
|
|
81450
|
+
holder: own,
|
|
81451
|
+
name,
|
|
81452
|
+
original,
|
|
81453
|
+
descriptor: Object.getOwnPropertyDescriptor(own, name)
|
|
81454
|
+
};
|
|
81455
|
+
}
|
|
81456
|
+
const proto = Object.getPrototypeOf(service);
|
|
81457
|
+
if (proto === null) return void 0;
|
|
81458
|
+
if (proto === Object.prototype || proto === Function.prototype) return void 0;
|
|
81459
|
+
const original = proto[name];
|
|
81460
|
+
if (typeof original !== "function") return void 0;
|
|
81461
|
+
return {
|
|
81462
|
+
holder: proto,
|
|
81463
|
+
name,
|
|
81464
|
+
original,
|
|
81465
|
+
descriptor: Object.getOwnPropertyDescriptor(proto, name)
|
|
81466
|
+
};
|
|
81467
|
+
}
|
|
81468
|
+
/**
|
|
81469
|
+
* 把一个包装写到方法所在的位置上。
|
|
81470
|
+
*
|
|
81471
|
+
* @param target - 目标。
|
|
81472
|
+
* @param replacement - 包装实现。
|
|
81473
|
+
* @returns 是否装上了。
|
|
81474
|
+
*/
|
|
81475
|
+
function installMethod$2(target, replacement) {
|
|
81476
|
+
try {
|
|
81477
|
+
Object.defineProperty(target.holder, target.name, {
|
|
81478
|
+
value: replacement,
|
|
81479
|
+
configurable: true,
|
|
81480
|
+
writable: true,
|
|
81481
|
+
enumerable: target.descriptor?.enumerable ?? false
|
|
81482
|
+
});
|
|
81483
|
+
return true;
|
|
81484
|
+
} catch {
|
|
81485
|
+
return false;
|
|
81486
|
+
}
|
|
81487
|
+
}
|
|
81488
|
+
/**
|
|
81489
|
+
* 还原方法所在位置上原来的实现。
|
|
81490
|
+
*
|
|
81491
|
+
* @param target - 目标。
|
|
81492
|
+
*/
|
|
81493
|
+
function restoreMethod$2(target) {
|
|
81494
|
+
try {
|
|
81495
|
+
if (target.descriptor === void 0) Reflect.deleteProperty(target.holder, target.name);
|
|
81496
|
+
else Object.defineProperty(target.holder, target.name, target.descriptor);
|
|
81497
|
+
} catch {}
|
|
81498
|
+
}
|
|
81499
|
+
/**
|
|
81500
|
+
* 判断某个「方法宿主 + 方法名」是不是已经被本守卫包过。
|
|
81501
|
+
*
|
|
81502
|
+
* @param patched - 已包装记录。
|
|
81503
|
+
* @param holder - 方法宿主。
|
|
81504
|
+
* @param name - 方法名。
|
|
81505
|
+
* @returns 是否已经包过。
|
|
81506
|
+
*/
|
|
81507
|
+
function alreadyPatched$2(patched, holder, name) {
|
|
81508
|
+
return patched.get(holder)?.has(name) === true;
|
|
81509
|
+
}
|
|
81510
|
+
/**
|
|
81511
|
+
* 记下某个「方法宿主 + 方法名」已经被本守卫包过。
|
|
81512
|
+
*
|
|
81513
|
+
* @param patched - 已包装记录。
|
|
81514
|
+
* @param holder - 方法宿主。
|
|
81515
|
+
* @param name - 方法名。
|
|
81516
|
+
*/
|
|
81517
|
+
function markPatched$2(patched, holder, name) {
|
|
81518
|
+
const names = patched.get(holder);
|
|
81519
|
+
if (names === void 0) patched.set(holder, /* @__PURE__ */ new Set([name]));
|
|
81520
|
+
else names.add(name);
|
|
81521
|
+
}
|
|
81284
81522
|
/** PTC 生成的 SDK 段名。 */
|
|
81285
81523
|
const PTC_SDK_SECTION_NAME = "tools:sdk";
|
|
81286
81524
|
/** 没有 scope 的装配(会话标题之类)用的桶键。 */
|
|
@@ -81337,6 +81575,8 @@ function installPtcSdkCacheGuard(ctx, options = {}) {
|
|
|
81337
81575
|
const providers = new Set(options.providers ?? ["kimi-code"]);
|
|
81338
81576
|
/** 已包装过的实例(幂等标记)。 */
|
|
81339
81577
|
const alreadyWrapped = /* @__PURE__ */ new WeakSet();
|
|
81578
|
+
/** 已包装过的「方法宿主 + 方法名」:同一个原型不叠第二层包装。 */
|
|
81579
|
+
const patchedMethods = /* @__PURE__ */ new WeakMap();
|
|
81340
81580
|
/** 每个 scope 的 SDK 段缓存。 */
|
|
81341
81581
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
81342
81582
|
/** 事件监听的 disposer。 */
|
|
@@ -81363,11 +81603,11 @@ function installPtcSdkCacheGuard(ctx, options = {}) {
|
|
|
81363
81603
|
*/
|
|
81364
81604
|
const toolFingerprint = (tools, scope) => {
|
|
81365
81605
|
if (!isRecord$7(tools)) return "";
|
|
81366
|
-
const
|
|
81367
|
-
if (
|
|
81606
|
+
const target = resolveMethodTarget$1(tools, "definitions");
|
|
81607
|
+
if (target === void 0) return "";
|
|
81368
81608
|
let list;
|
|
81369
81609
|
try {
|
|
81370
|
-
list =
|
|
81610
|
+
list = target.original.call(tools, scope, void 0);
|
|
81371
81611
|
} catch {
|
|
81372
81612
|
return "";
|
|
81373
81613
|
}
|
|
@@ -81383,33 +81623,26 @@ function installPtcSdkCacheGuard(ctx, options = {}) {
|
|
|
81383
81623
|
const wrapToolsService = (tools) => {
|
|
81384
81624
|
if (disposed || !isRecord$7(tools)) return false;
|
|
81385
81625
|
if (alreadyWrapped.has(tools)) return false;
|
|
81386
|
-
const
|
|
81387
|
-
if (
|
|
81388
|
-
|
|
81626
|
+
const target = resolveMethodTarget$1(tools, "definitions");
|
|
81627
|
+
if (target === void 0) return false;
|
|
81628
|
+
if (alreadyPatched$1(patchedMethods, target.holder, target.name)) {
|
|
81629
|
+
alreadyWrapped.add(tools);
|
|
81630
|
+
return false;
|
|
81631
|
+
}
|
|
81632
|
+
const original = target.original;
|
|
81389
81633
|
const replacement = function(scope, toolSet) {
|
|
81634
|
+
const receiver = this ?? tools;
|
|
81390
81635
|
if (toolSet !== void 0) {
|
|
81391
81636
|
const provider = readScopeProvider(scope);
|
|
81392
|
-
if (provider !== void 0 && providers.has(provider)) return original.call(
|
|
81637
|
+
if (provider !== void 0 && providers.has(provider)) return original.call(receiver, scope, void 0);
|
|
81393
81638
|
}
|
|
81394
|
-
return original.call(
|
|
81639
|
+
return original.call(receiver, scope, toolSet);
|
|
81395
81640
|
};
|
|
81396
|
-
|
|
81397
|
-
|
|
81398
|
-
Object.defineProperty(tools, "definitions", {
|
|
81399
|
-
value: replacement,
|
|
81400
|
-
configurable: true,
|
|
81401
|
-
writable: true,
|
|
81402
|
-
enumerable: descriptor?.enumerable ?? false
|
|
81403
|
-
});
|
|
81404
|
-
} catch {
|
|
81405
|
-
return false;
|
|
81406
|
-
}
|
|
81641
|
+
if (!installMethod$1(target, replacement)) return false;
|
|
81642
|
+
markPatched$1(patchedMethods, target.holder, target.name);
|
|
81407
81643
|
alreadyWrapped.add(tools);
|
|
81408
81644
|
restores.push(() => {
|
|
81409
|
-
|
|
81410
|
-
if (descriptor === void 0) delete tools["definitions"];
|
|
81411
|
-
else Object.defineProperty(tools, "definitions", descriptor);
|
|
81412
|
-
} catch {}
|
|
81645
|
+
restoreMethod$1(target);
|
|
81413
81646
|
});
|
|
81414
81647
|
return true;
|
|
81415
81648
|
};
|
|
@@ -81537,6 +81770,103 @@ function subscribe$1(host, event, listener) {
|
|
|
81537
81770
|
function isRecord$7(value) {
|
|
81538
81771
|
return typeof value === "object" && value !== null;
|
|
81539
81772
|
}
|
|
81773
|
+
/**
|
|
81774
|
+
* 定位一个待包装的方法。
|
|
81775
|
+
*
|
|
81776
|
+
* Cordis 的 `Service` 代理在读属性时会把方法**绑定到读取它的那一层作用域**
|
|
81777
|
+
* (`Reflect.get(target, prop, receiver).bind(receiver)`)。于是
|
|
81778
|
+
* `const original = tools.register` 拿到的是一份**已经绑到根作用域**的函数;再
|
|
81779
|
+
* `original.call(tools, …)` 就把根作用域硬塞回每一个 preset 的注册里,全局层
|
|
81780
|
+
* 于是撞上 "already registered"。
|
|
81781
|
+
*
|
|
81782
|
+
* 真正要的是**原型上那份未绑定的方法**:包装器用 `original.call(this, …)` 把
|
|
81783
|
+
* 调用方自己的 receiver 传下去,服务里的 `this.ctx` 才留在调用方那一层作用域
|
|
81784
|
+
* (child ctx)里。方法挂在原型上时(真实 Cordis `Service`),包装也写在原型上;
|
|
81785
|
+
* 只有普通假对象(单测)才把方法作为自有属性挂在实例上。
|
|
81786
|
+
*
|
|
81787
|
+
* @param service - 服务实例(可以是 Cordis 的跟踪代理)。
|
|
81788
|
+
* @param name - 方法名。
|
|
81789
|
+
* @returns 目标;方法不存在时为 `undefined`。
|
|
81790
|
+
*/
|
|
81791
|
+
function resolveMethodTarget$1(service, name) {
|
|
81792
|
+
if (typeof service !== "object" || service === null) return void 0;
|
|
81793
|
+
const own = service;
|
|
81794
|
+
if (Object.prototype.hasOwnProperty.call(own, name)) {
|
|
81795
|
+
const original = own[name];
|
|
81796
|
+
if (typeof original !== "function") return void 0;
|
|
81797
|
+
return {
|
|
81798
|
+
holder: own,
|
|
81799
|
+
name,
|
|
81800
|
+
original,
|
|
81801
|
+
descriptor: Object.getOwnPropertyDescriptor(own, name)
|
|
81802
|
+
};
|
|
81803
|
+
}
|
|
81804
|
+
const proto = Object.getPrototypeOf(service);
|
|
81805
|
+
if (proto === null) return void 0;
|
|
81806
|
+
if (proto === Object.prototype || proto === Function.prototype) return void 0;
|
|
81807
|
+
const original = proto[name];
|
|
81808
|
+
if (typeof original !== "function") return void 0;
|
|
81809
|
+
return {
|
|
81810
|
+
holder: proto,
|
|
81811
|
+
name,
|
|
81812
|
+
original,
|
|
81813
|
+
descriptor: Object.getOwnPropertyDescriptor(proto, name)
|
|
81814
|
+
};
|
|
81815
|
+
}
|
|
81816
|
+
/**
|
|
81817
|
+
* 把一个包装写到方法所在的位置上。
|
|
81818
|
+
*
|
|
81819
|
+
* @param target - 目标。
|
|
81820
|
+
* @param replacement - 包装实现。
|
|
81821
|
+
* @returns 是否装上了。
|
|
81822
|
+
*/
|
|
81823
|
+
function installMethod$1(target, replacement) {
|
|
81824
|
+
try {
|
|
81825
|
+
Object.defineProperty(target.holder, target.name, {
|
|
81826
|
+
value: replacement,
|
|
81827
|
+
configurable: true,
|
|
81828
|
+
writable: true,
|
|
81829
|
+
enumerable: target.descriptor?.enumerable ?? false
|
|
81830
|
+
});
|
|
81831
|
+
return true;
|
|
81832
|
+
} catch {
|
|
81833
|
+
return false;
|
|
81834
|
+
}
|
|
81835
|
+
}
|
|
81836
|
+
/**
|
|
81837
|
+
* 还原方法所在位置上原来的实现。
|
|
81838
|
+
*
|
|
81839
|
+
* @param target - 目标。
|
|
81840
|
+
*/
|
|
81841
|
+
function restoreMethod$1(target) {
|
|
81842
|
+
try {
|
|
81843
|
+
if (target.descriptor === void 0) Reflect.deleteProperty(target.holder, target.name);
|
|
81844
|
+
else Object.defineProperty(target.holder, target.name, target.descriptor);
|
|
81845
|
+
} catch {}
|
|
81846
|
+
}
|
|
81847
|
+
/**
|
|
81848
|
+
* 判断某个「方法宿主 + 方法名」是不是已经被本守卫包过。
|
|
81849
|
+
*
|
|
81850
|
+
* @param patched - 已包装记录。
|
|
81851
|
+
* @param holder - 方法宿主。
|
|
81852
|
+
* @param name - 方法名。
|
|
81853
|
+
* @returns 是否已经包过。
|
|
81854
|
+
*/
|
|
81855
|
+
function alreadyPatched$1(patched, holder, name) {
|
|
81856
|
+
return patched.get(holder)?.has(name) === true;
|
|
81857
|
+
}
|
|
81858
|
+
/**
|
|
81859
|
+
* 记下某个「方法宿主 + 方法名」已经被本守卫包过。
|
|
81860
|
+
*
|
|
81861
|
+
* @param patched - 已包装记录。
|
|
81862
|
+
* @param holder - 方法宿主。
|
|
81863
|
+
* @param name - 方法名。
|
|
81864
|
+
*/
|
|
81865
|
+
function markPatched$1(patched, holder, name) {
|
|
81866
|
+
const names = patched.get(holder);
|
|
81867
|
+
if (names === void 0) patched.set(holder, /* @__PURE__ */ new Set([name]));
|
|
81868
|
+
else names.add(name);
|
|
81869
|
+
}
|
|
81540
81870
|
//#endregion
|
|
81541
81871
|
//#region src/host/compaction-policy-guard.ts
|
|
81542
81872
|
/**
|
|
@@ -81595,6 +81925,17 @@ function isRecord$7(value) {
|
|
|
81595
81925
|
* `agent.options`),把确切的 provider/model 登记进来——于是匹配用的是 100%
|
|
81596
81926
|
* 标准的普通对象,没有一行依赖 Proxy 的巧合。
|
|
81597
81927
|
*
|
|
81928
|
+
* ## 瀑布事件必须转交 `next()`
|
|
81929
|
+
*
|
|
81930
|
+
* `agent/pre-step` / `agent/request` / `agent/request-error` 是 Cordis **瀑布**事件
|
|
81931
|
+
* (`ctx.waterfall`),最后一个参数就是 `next`。瀑布的返回值是**最外层监听器的
|
|
81932
|
+
* 返回值**:不调用 `next()` 等于替整条链做了决定——后续监听器(连同内置的默认行为)
|
|
81933
|
+
* 一个都不跑,瀑布的返回值也变成监听器自己的返回值。于是 `agent-loop` 读
|
|
81934
|
+
* `decision.kind` / `proposedConfig.provider` 时拿到 `undefined`,每一轮都炸成
|
|
81935
|
+
* `TypeError: Cannot read properties of undefined (reading 'kind')`。
|
|
81936
|
+
* 本守卫是旁路,观测与扫描失败只吞掉它们自己,但 `next()` 在所有分支上都要被调用
|
|
81937
|
+
* 并原样交回去。
|
|
81938
|
+
*
|
|
81598
81939
|
* @module @eddyskywalker/dsh-chatgpt-subscription/host/compaction-policy-guard
|
|
81599
81940
|
*/
|
|
81600
81941
|
/** 压缩服务的名字(`ctx.reflect.store` 与 `ctx.get` 都用它)。 */
|
|
@@ -81655,6 +81996,8 @@ function installCompactionPolicyGuard(ctx, options = {}) {
|
|
|
81655
81996
|
const observed = /* @__PURE__ */ new Map();
|
|
81656
81997
|
/** 已改写的引擎(幂等标记)与还原动作。 */
|
|
81657
81998
|
const patched = /* @__PURE__ */ new WeakMap();
|
|
81999
|
+
/** 已包装过的「方法宿主 + 方法名」:同一个原型不叠第二层包装。 */
|
|
82000
|
+
const patchedMethods = /* @__PURE__ */ new WeakMap();
|
|
81658
82001
|
const restores = [];
|
|
81659
82002
|
/** 事件监听的 disposer。 */
|
|
81660
82003
|
const disposers = [];
|
|
@@ -81825,10 +82168,10 @@ function installCompactionPolicyGuard(ctx, options = {}) {
|
|
|
81825
82168
|
"compact",
|
|
81826
82169
|
"summarize"
|
|
81827
82170
|
]) {
|
|
81828
|
-
const
|
|
81829
|
-
if (
|
|
81830
|
-
|
|
81831
|
-
const
|
|
82171
|
+
const target = resolveMethodTarget(engine, name);
|
|
82172
|
+
if (target === void 0) continue;
|
|
82173
|
+
if (alreadyPatched(patchedMethods, target.holder, target.name)) continue;
|
|
82174
|
+
const original = target.original;
|
|
81832
82175
|
const replacement = function(...args) {
|
|
81833
82176
|
observeFrom(args[0]);
|
|
81834
82177
|
observeFrom(args[1]);
|
|
@@ -81846,23 +82189,12 @@ function installCompactionPolicyGuard(ctx, options = {}) {
|
|
|
81846
82189
|
}
|
|
81847
82190
|
}
|
|
81848
82191
|
}
|
|
81849
|
-
return original.apply(this, nextArgs);
|
|
82192
|
+
return original.apply(this ?? engine, nextArgs);
|
|
81850
82193
|
};
|
|
81851
|
-
|
|
81852
|
-
|
|
81853
|
-
value: replacement,
|
|
81854
|
-
configurable: true,
|
|
81855
|
-
writable: true,
|
|
81856
|
-
enumerable: Object.getOwnPropertyDescriptor(engine, name)?.enumerable ?? false
|
|
81857
|
-
});
|
|
81858
|
-
} catch {
|
|
81859
|
-
continue;
|
|
81860
|
-
}
|
|
82194
|
+
if (!installMethod(target, replacement)) continue;
|
|
82195
|
+
markPatched(patchedMethods, target.holder, target.name);
|
|
81861
82196
|
restoresForEngine.push(() => {
|
|
81862
|
-
|
|
81863
|
-
if (methodDescriptor === void 0) delete engine[name];
|
|
81864
|
-
else Object.defineProperty(engine, name, methodDescriptor);
|
|
81865
|
-
} catch {}
|
|
82197
|
+
restoreMethod(target);
|
|
81866
82198
|
});
|
|
81867
82199
|
}
|
|
81868
82200
|
const restore = () => {
|
|
@@ -81946,9 +82278,24 @@ function installCompactionPolicyGuard(ctx, options = {}) {
|
|
|
81946
82278
|
/**
|
|
81947
82279
|
* 事件回调:先观测模型,再扫宿主平面与 agent 自己的 realm。
|
|
81948
82280
|
*
|
|
81949
|
-
*
|
|
82281
|
+
* ## 瀑布必须转交
|
|
82282
|
+
*
|
|
82283
|
+
* `agent/pre-step` / `agent/request` / `agent/request-error` 在 DSH 里是
|
|
82284
|
+
* Cordis **瀑布**事件(`ctx.waterfall`),最后一个参数就是 `next`。瀑布的返回值
|
|
82285
|
+
* 是**最外层监听器的返回值**:不调用 `next()` 等于替整条链做了决定——后续监听器
|
|
82286
|
+
* (连同内置的默认行为)一个都不会跑,瀑布的返回值也变成监听器自己的返回值
|
|
82287
|
+
* (这里是 `undefined`)。`agent-loop` 随后读 `decision.kind` 与
|
|
82288
|
+
* `proposedConfig.provider`,于是每一轮都炸成
|
|
82289
|
+
* `TypeError: Cannot read properties of undefined (reading 'kind')`。
|
|
82290
|
+
*
|
|
82291
|
+
* 所以观测与扫描照旧做(失败也只吞掉扫描本身),但 `next()` **必须**在所有分支上
|
|
82292
|
+
* 被调用,并把它的结果原样交回去。
|
|
82293
|
+
*
|
|
82294
|
+
* @param args - 事件参数(最后一个参数可能是 `next`)。
|
|
82295
|
+
* @returns `next()` 的结果;没有 `next` 时为 `undefined`。
|
|
81950
82296
|
*/
|
|
81951
82297
|
const handleAgentEvent = (...args) => {
|
|
82298
|
+
const next = args.length > 0 && typeof args[args.length - 1] === "function" ? args[args.length - 1] : void 0;
|
|
81952
82299
|
try {
|
|
81953
82300
|
for (const arg of args) {
|
|
81954
82301
|
observeFrom(arg);
|
|
@@ -81956,10 +82303,12 @@ function installCompactionPolicyGuard(ctx, options = {}) {
|
|
|
81956
82303
|
}
|
|
81957
82304
|
scanAndPatch();
|
|
81958
82305
|
const agentCtx = findAgentContext(args);
|
|
81959
|
-
if (agentCtx
|
|
81960
|
-
|
|
81961
|
-
|
|
82306
|
+
if (agentCtx !== void 0) {
|
|
82307
|
+
scanStore(agentCtx);
|
|
82308
|
+
patchServiceFrom(agentCtx, COMPACTION_SERVICE_NAME);
|
|
82309
|
+
}
|
|
81962
82310
|
} catch {}
|
|
82311
|
+
return next === void 0 ? void 0 : next();
|
|
81963
82312
|
};
|
|
81964
82313
|
for (const event of GUARDED_EVENTS) {
|
|
81965
82314
|
const disposer = subscribe(host, event, handleAgentEvent);
|
|
@@ -82062,6 +82411,103 @@ function subscribe(host, event, listener) {
|
|
|
82062
82411
|
function isRecord$6(value) {
|
|
82063
82412
|
return typeof value === "object" && value !== null;
|
|
82064
82413
|
}
|
|
82414
|
+
/**
|
|
82415
|
+
* 定位一个待包装的方法。
|
|
82416
|
+
*
|
|
82417
|
+
* Cordis 的 `Service` 代理在读属性时会把方法**绑定到读取它的那一层作用域**
|
|
82418
|
+
* (`Reflect.get(target, prop, receiver).bind(receiver)`)。于是
|
|
82419
|
+
* `const original = tools.register` 拿到的是一份**已经绑到根作用域**的函数;再
|
|
82420
|
+
* `original.call(tools, …)` 就把根作用域硬塞回每一个 preset 的注册里,全局层
|
|
82421
|
+
* 于是撞上 "already registered"。
|
|
82422
|
+
*
|
|
82423
|
+
* 真正要的是**原型上那份未绑定的方法**:包装器用 `original.call(this, …)` 把
|
|
82424
|
+
* 调用方自己的 receiver 传下去,服务里的 `this.ctx` 才留在调用方那一层作用域
|
|
82425
|
+
* (child ctx)里。方法挂在原型上时(真实 Cordis `Service`),包装也写在原型上;
|
|
82426
|
+
* 只有普通假对象(单测)才把方法作为自有属性挂在实例上。
|
|
82427
|
+
*
|
|
82428
|
+
* @param service - 服务实例(可以是 Cordis 的跟踪代理)。
|
|
82429
|
+
* @param name - 方法名。
|
|
82430
|
+
* @returns 目标;方法不存在时为 `undefined`。
|
|
82431
|
+
*/
|
|
82432
|
+
function resolveMethodTarget(service, name) {
|
|
82433
|
+
if (typeof service !== "object" || service === null) return void 0;
|
|
82434
|
+
const own = service;
|
|
82435
|
+
if (Object.prototype.hasOwnProperty.call(own, name)) {
|
|
82436
|
+
const original = own[name];
|
|
82437
|
+
if (typeof original !== "function") return void 0;
|
|
82438
|
+
return {
|
|
82439
|
+
holder: own,
|
|
82440
|
+
name,
|
|
82441
|
+
original,
|
|
82442
|
+
descriptor: Object.getOwnPropertyDescriptor(own, name)
|
|
82443
|
+
};
|
|
82444
|
+
}
|
|
82445
|
+
const proto = Object.getPrototypeOf(service);
|
|
82446
|
+
if (proto === null) return void 0;
|
|
82447
|
+
if (proto === Object.prototype || proto === Function.prototype) return void 0;
|
|
82448
|
+
const original = proto[name];
|
|
82449
|
+
if (typeof original !== "function") return void 0;
|
|
82450
|
+
return {
|
|
82451
|
+
holder: proto,
|
|
82452
|
+
name,
|
|
82453
|
+
original,
|
|
82454
|
+
descriptor: Object.getOwnPropertyDescriptor(proto, name)
|
|
82455
|
+
};
|
|
82456
|
+
}
|
|
82457
|
+
/**
|
|
82458
|
+
* 把一个包装写到方法所在的位置上。
|
|
82459
|
+
*
|
|
82460
|
+
* @param target - 目标。
|
|
82461
|
+
* @param replacement - 包装实现。
|
|
82462
|
+
* @returns 是否装上了。
|
|
82463
|
+
*/
|
|
82464
|
+
function installMethod(target, replacement) {
|
|
82465
|
+
try {
|
|
82466
|
+
Object.defineProperty(target.holder, target.name, {
|
|
82467
|
+
value: replacement,
|
|
82468
|
+
configurable: true,
|
|
82469
|
+
writable: true,
|
|
82470
|
+
enumerable: target.descriptor?.enumerable ?? false
|
|
82471
|
+
});
|
|
82472
|
+
return true;
|
|
82473
|
+
} catch {
|
|
82474
|
+
return false;
|
|
82475
|
+
}
|
|
82476
|
+
}
|
|
82477
|
+
/**
|
|
82478
|
+
* 还原方法所在位置上原来的实现。
|
|
82479
|
+
*
|
|
82480
|
+
* @param target - 目标。
|
|
82481
|
+
*/
|
|
82482
|
+
function restoreMethod(target) {
|
|
82483
|
+
try {
|
|
82484
|
+
if (target.descriptor === void 0) Reflect.deleteProperty(target.holder, target.name);
|
|
82485
|
+
else Object.defineProperty(target.holder, target.name, target.descriptor);
|
|
82486
|
+
} catch {}
|
|
82487
|
+
}
|
|
82488
|
+
/**
|
|
82489
|
+
* 判断某个「方法宿主 + 方法名」是不是已经被本守卫包过。
|
|
82490
|
+
*
|
|
82491
|
+
* @param patched - 已包装记录。
|
|
82492
|
+
* @param holder - 方法宿主。
|
|
82493
|
+
* @param name - 方法名。
|
|
82494
|
+
* @returns 是否已经包过。
|
|
82495
|
+
*/
|
|
82496
|
+
function alreadyPatched(patched, holder, name) {
|
|
82497
|
+
return patched.get(holder)?.has(name) === true;
|
|
82498
|
+
}
|
|
82499
|
+
/**
|
|
82500
|
+
* 记下某个「方法宿主 + 方法名」已经被本守卫包过。
|
|
82501
|
+
*
|
|
82502
|
+
* @param patched - 已包装记录。
|
|
82503
|
+
* @param holder - 方法宿主。
|
|
82504
|
+
* @param name - 方法名。
|
|
82505
|
+
*/
|
|
82506
|
+
function markPatched(patched, holder, name) {
|
|
82507
|
+
const names = patched.get(holder);
|
|
82508
|
+
if (names === void 0) patched.set(holder, /* @__PURE__ */ new Set([name]));
|
|
82509
|
+
else names.add(name);
|
|
82510
|
+
}
|
|
82065
82511
|
//#endregion
|
|
82066
82512
|
//#region src/host/preset-sync.ts
|
|
82067
82513
|
/**
|