@eddyskywalker/dsh-chatgpt-subscription 0.12.2 → 0.12.3
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/lib/index.js
CHANGED
|
@@ -43268,6 +43268,16 @@ function installRelayProbe(ctx, options) {
|
|
|
43268
43268
|
* The guard rewrites nothing and appends nothing to the aborted attempt. Its
|
|
43269
43269
|
* only model-visible input is the single resume message it queues afterwards,
|
|
43270
43270
|
* on a fresh turn.
|
|
43271
|
+
*
|
|
43272
|
+
* Agent identity is read from the request, never remembered globally. The loop
|
|
43273
|
+
* stamps every request it builds with its `sessionId`, and `ctx.agents.get`
|
|
43274
|
+
* turns that back into the one Agent that owns the stream. Remembering "the
|
|
43275
|
+
* newest agent this process saw" instead was wrong twice over: a host runs one
|
|
43276
|
+
* Agent per session plus one per subagent, so the newest is usually a different
|
|
43277
|
+
* conversation, and `agent/created` fires once per Agent, so an Agent that
|
|
43278
|
+
* already existed when the guard installed was never reported at all. Both
|
|
43279
|
+
* cases cut the runaway and then resumed nothing, which reads to the user as a
|
|
43280
|
+
* conversation that simply stops mid-answer.
|
|
43271
43281
|
*/
|
|
43272
43282
|
const DEFAULT_GUARD_OPTIONS = {
|
|
43273
43283
|
windowChars: 4096,
|
|
@@ -43372,6 +43382,43 @@ function appendWindow(current, addition, limit) {
|
|
|
43372
43382
|
const combined = current + addition;
|
|
43373
43383
|
return combined.length > limit ? combined.slice(-limit) : combined;
|
|
43374
43384
|
}
|
|
43385
|
+
/** An Agent's session identity as the plain string a request carries. */
|
|
43386
|
+
function agentId(raw) {
|
|
43387
|
+
const id = raw?.id;
|
|
43388
|
+
return typeof id === "string" ? id : void 0;
|
|
43389
|
+
}
|
|
43390
|
+
/**
|
|
43391
|
+
* The host's Agent registry, read defensively.
|
|
43392
|
+
*
|
|
43393
|
+
* A Cordis service that was never injected reads as undefined and a host
|
|
43394
|
+
* without the service at all must not fail this plugin's load, so both the
|
|
43395
|
+
* property read and the later lookup are guarded.
|
|
43396
|
+
*/
|
|
43397
|
+
function agentRegistry(ctx) {
|
|
43398
|
+
try {
|
|
43399
|
+
const registry = ctx.agents;
|
|
43400
|
+
return typeof registry?.get === "function" ? registry : void 0;
|
|
43401
|
+
} catch {
|
|
43402
|
+
return;
|
|
43403
|
+
}
|
|
43404
|
+
}
|
|
43405
|
+
/**
|
|
43406
|
+
* Whether one request is a conversation call the guard may stop and resume.
|
|
43407
|
+
*
|
|
43408
|
+
* The loop marks its own requests, but that marker is reached through a named
|
|
43409
|
+
* export this plugin cannot assume on every generation it supports, so the
|
|
43410
|
+
* guard reads the request's own `purpose` field instead: compaction and
|
|
43411
|
+
* session-title calls are one-shot, own no turn to resume, and a truncated one
|
|
43412
|
+
* is a hard error rather than a runaway. A generation that predates the field
|
|
43413
|
+
* leaves it undefined, which is the pre-existing behaviour.
|
|
43414
|
+
*/
|
|
43415
|
+
function conversationCall(request) {
|
|
43416
|
+
return request.purpose === void 0;
|
|
43417
|
+
}
|
|
43418
|
+
/** Error text for one warn line, without importing a generation-bound helper. */
|
|
43419
|
+
function describeError(error) {
|
|
43420
|
+
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
43421
|
+
}
|
|
43375
43422
|
/**
|
|
43376
43423
|
* Install the reasoning-collapse guard on a Context.
|
|
43377
43424
|
*
|
|
@@ -43380,14 +43427,15 @@ function appendWindow(current, addition, limit) {
|
|
|
43380
43427
|
* load.
|
|
43381
43428
|
*
|
|
43382
43429
|
* Resuming needs the live Agent for `cancel` and `steer`, and no supported
|
|
43383
|
-
* generation hands the agent to `llm/stream`.
|
|
43384
|
-
*
|
|
43385
|
-
*
|
|
43386
|
-
* turn
|
|
43430
|
+
* generation hands the agent to `llm/stream`. The request does, though: every
|
|
43431
|
+
* request the loop builds carries its `sessionId`, so the guard resolves the
|
|
43432
|
+
* owning Agent per request through `ctx.agents.get`, falling back to the map
|
|
43433
|
+
* `agent/created` fills. The per-turn break budget stays keyed on the
|
|
43434
|
+
* request's own abort signal, which exists for a whole turn.
|
|
43387
43435
|
*
|
|
43388
43436
|
* @param ctx - plugin context.
|
|
43389
43437
|
* @param options - see {@link GuardOptions}; validated fail-loud.
|
|
43390
|
-
* @returns a disposer removing
|
|
43438
|
+
* @returns a disposer removing every listener, or undefined when the host
|
|
43391
43439
|
* exposes no event bus.
|
|
43392
43440
|
*/
|
|
43393
43441
|
function installReasoningCollapseGuard(ctx, options = {}) {
|
|
@@ -43395,11 +43443,38 @@ function installReasoningCollapseGuard(ctx, options = {}) {
|
|
|
43395
43443
|
if (typeof ctx.on !== "function") return void 0;
|
|
43396
43444
|
const watched = new Set(resolved.includeModels);
|
|
43397
43445
|
const breakers = /* @__PURE__ */ new WeakMap();
|
|
43398
|
-
|
|
43399
|
-
const
|
|
43400
|
-
|
|
43446
|
+
const known = /* @__PURE__ */ new Map();
|
|
43447
|
+
const releaseCreated = ctx.on("agent/created", (payload) => {
|
|
43448
|
+
remember(payload.agent);
|
|
43449
|
+
});
|
|
43450
|
+
const releaseDisposed = ctx.on("agent/disposed", (payload) => {
|
|
43451
|
+
const id = agentId(payload.agent);
|
|
43452
|
+
if (id !== void 0) known.delete(id);
|
|
43401
43453
|
});
|
|
43402
43454
|
const releaseStream = ctx.on("llm/stream", guardStream, { global: true });
|
|
43455
|
+
function remember(raw) {
|
|
43456
|
+
const agent = raw;
|
|
43457
|
+
if (agent === void 0 || agent === null) return;
|
|
43458
|
+
const id = agentId(agent);
|
|
43459
|
+
if (id !== void 0) known.set(id, agent);
|
|
43460
|
+
}
|
|
43461
|
+
/**
|
|
43462
|
+
* The Agent that owns one guarded request, or undefined when this host
|
|
43463
|
+
* cannot name it.
|
|
43464
|
+
*
|
|
43465
|
+
* The registry is authoritative and is read first: it answers for an Agent
|
|
43466
|
+
* created before this guard was installed, which is exactly the Agent an
|
|
43467
|
+
* `agent/created` listener can never report. Falling back to the newest
|
|
43468
|
+
* Agent this process saw would cancel and resume a different conversation.
|
|
43469
|
+
*/
|
|
43470
|
+
function resolveAgent(sessionId) {
|
|
43471
|
+
if (sessionId === void 0) return void 0;
|
|
43472
|
+
try {
|
|
43473
|
+
const registered = agentRegistry(ctx)?.get(sessionId);
|
|
43474
|
+
if (registered !== void 0 && registered !== null) return registered;
|
|
43475
|
+
} catch {}
|
|
43476
|
+
return known.get(sessionId);
|
|
43477
|
+
}
|
|
43403
43478
|
function breakerFor(key) {
|
|
43404
43479
|
let state = breakers.get(key);
|
|
43405
43480
|
if (state === void 0) {
|
|
@@ -43419,27 +43494,36 @@ function installReasoningCollapseGuard(ctx, options = {}) {
|
|
|
43419
43494
|
* steering submitted while a turn is still unwinding; by the time the
|
|
43420
43495
|
* microtask runs the abort has settled, so the wake lands on a fresh turn that
|
|
43421
43496
|
* inherits the kept inbox.
|
|
43497
|
+
*
|
|
43498
|
+
* With no Agent to address, the runaway is still cut — that half is the whole
|
|
43499
|
+
* point — and the log says so, because a break that cannot resume is
|
|
43500
|
+
* indistinguishable from a broken turn to the user.
|
|
43422
43501
|
*/
|
|
43423
|
-
function breakOff(state, score) {
|
|
43502
|
+
function breakOff(state, score, agent, sessionId) {
|
|
43424
43503
|
state.breaksThisTurn++;
|
|
43425
43504
|
state.lastBreakAt = resolved.now();
|
|
43426
|
-
ctx.logger?.warn(`reasoning-collapse-guard: stopped degenerate reasoning (score ${score.toFixed(3)}, break ${state.breaksThisTurn}/${resolved.maxBreaksPerTurn})`);
|
|
43427
|
-
|
|
43428
|
-
agent
|
|
43505
|
+
ctx.logger?.warn(`reasoning-collapse-guard: stopped degenerate reasoning (score ${score.toFixed(3)}, break ${state.breaksThisTurn}/${resolved.maxBreaksPerTurn}, session ${sessionId ?? "unidentified"}${agent === void 0 ? ", no agent to resume" : ""})`);
|
|
43506
|
+
if (agent === void 0) return;
|
|
43507
|
+
agent.cancel?.({
|
|
43429
43508
|
kind: "hook",
|
|
43430
43509
|
reason: "reasoning-collapse-guard"
|
|
43431
43510
|
}, { keepInbox: true });
|
|
43432
|
-
if (agent === void 0 || state.resuming) return;
|
|
43511
|
+
if (agent.steer === void 0 || state.resuming) return;
|
|
43433
43512
|
state.resuming = true;
|
|
43434
43513
|
const text = state.breaksThisTurn >= 2 ? RESUME_HINT_STRICT : RESUME_HINT;
|
|
43435
43514
|
queueMicrotask(() => {
|
|
43436
43515
|
state.resuming = false;
|
|
43437
|
-
|
|
43516
|
+
try {
|
|
43517
|
+
agent.steer?.(createResumeMessage(text));
|
|
43518
|
+
} catch (error) {
|
|
43519
|
+
ctx.logger?.warn(`reasoning-collapse-guard: could not queue the resume: ${describeError(error)}`);
|
|
43520
|
+
}
|
|
43438
43521
|
});
|
|
43439
43522
|
}
|
|
43440
43523
|
function guardStream(request, next) {
|
|
43441
43524
|
const state = breakerFor(request.signal ?? STATIC_KEY);
|
|
43442
|
-
if (state.exhausted || !watchedModel(request.model)) return next();
|
|
43525
|
+
if (state.exhausted || !watchedModel(request.model) || !conversationCall(request)) return next();
|
|
43526
|
+
const agent = resolveAgent(request.sessionId);
|
|
43443
43527
|
async function* guarded() {
|
|
43444
43528
|
let window = "";
|
|
43445
43529
|
for await (const chunk of next()) {
|
|
@@ -43450,7 +43534,7 @@ function installReasoningCollapseGuard(ctx, options = {}) {
|
|
|
43450
43534
|
const score = collapseScore(window, resolved.ngramSize);
|
|
43451
43535
|
if (score >= resolved.threshold) if (state.breaksThisTurn >= resolved.maxBreaksPerTurn) state.exhausted = true;
|
|
43452
43536
|
else {
|
|
43453
|
-
breakOff(state, score);
|
|
43537
|
+
breakOff(state, score, agent, request.sessionId);
|
|
43454
43538
|
return;
|
|
43455
43539
|
}
|
|
43456
43540
|
}
|
|
@@ -43462,7 +43546,9 @@ function installReasoningCollapseGuard(ctx, options = {}) {
|
|
|
43462
43546
|
}
|
|
43463
43547
|
return () => {
|
|
43464
43548
|
releaseListener(releaseStream);
|
|
43465
|
-
releaseListener(
|
|
43549
|
+
releaseListener(releaseCreated);
|
|
43550
|
+
releaseListener(releaseDisposed);
|
|
43551
|
+
known.clear();
|
|
43466
43552
|
};
|
|
43467
43553
|
}
|
|
43468
43554
|
/** Shared key for the rare request that carries no abort signal. */
|
|
@@ -29,11 +29,32 @@
|
|
|
29
29
|
* The guard rewrites nothing and appends nothing to the aborted attempt. Its
|
|
30
30
|
* only model-visible input is the single resume message it queues afterwards,
|
|
31
31
|
* on a fresh turn.
|
|
32
|
+
*
|
|
33
|
+
* Agent identity is read from the request, never remembered globally. The loop
|
|
34
|
+
* stamps every request it builds with its `sessionId`, and `ctx.agents.get`
|
|
35
|
+
* turns that back into the one Agent that owns the stream. Remembering "the
|
|
36
|
+
* newest agent this process saw" instead was wrong twice over: a host runs one
|
|
37
|
+
* Agent per session plus one per subagent, so the newest is usually a different
|
|
38
|
+
* conversation, and `agent/created` fires once per Agent, so an Agent that
|
|
39
|
+
* already existed when the guard installed was never reported at all. Both
|
|
40
|
+
* cases cut the runaway and then resumed nothing, which reads to the user as a
|
|
41
|
+
* conversation that simply stops mid-answer.
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* The subset of `llm/stream` options this guard reads.
|
|
45
|
+
*
|
|
46
|
+
* `sessionId` is what binds a stream to the Agent that owns it, and
|
|
47
|
+
* `purpose` tells a conversation call from an auxiliary one (compaction,
|
|
48
|
+
* session title) that owns no turn to resume. Both are plain request fields:
|
|
49
|
+
* the guard adds no generation-bound named import to learn them.
|
|
32
50
|
*/
|
|
33
|
-
/** The subset of `llm/stream` options this guard reads. */
|
|
34
51
|
export interface GuardStreamOptions {
|
|
35
52
|
readonly model?: string | undefined;
|
|
36
53
|
readonly signal?: AbortSignal | undefined;
|
|
54
|
+
/** Stamped by the agent loop on every request it builds. */
|
|
55
|
+
readonly sessionId?: string | undefined;
|
|
56
|
+
/** Absent on an ordinary conversation request; set on an auxiliary call. */
|
|
57
|
+
readonly purpose?: string | undefined;
|
|
37
58
|
}
|
|
38
59
|
/** A chunk as it crosses the stream boundary; only the reasoning delta is read. */
|
|
39
60
|
export interface GuardChunk {
|
|
@@ -42,6 +63,8 @@ export interface GuardChunk {
|
|
|
42
63
|
}
|
|
43
64
|
/** Live Agent methods the guard calls. Optional so an older shape stays loadable. */
|
|
44
65
|
export interface GuardAgentLike {
|
|
66
|
+
/** The Agent's session identity — the same value the loop stamps on requests. */
|
|
67
|
+
readonly id?: unknown;
|
|
45
68
|
cancel?(cause: {
|
|
46
69
|
kind: 'hook';
|
|
47
70
|
reason: string;
|
|
@@ -52,12 +75,12 @@ export interface GuardAgentLike {
|
|
|
52
75
|
}
|
|
53
76
|
/** The `llm/stream` waterfall listener the guard registers. */
|
|
54
77
|
export type GuardStreamListener = (options: GuardStreamOptions, next: () => AsyncIterable<GuardChunk>) => AsyncIterable<GuardChunk>;
|
|
55
|
-
/** The `agent/created` listener the guard registers. */
|
|
56
|
-
export type
|
|
78
|
+
/** The `agent/created` / `agent/disposed` listener the guard registers. */
|
|
79
|
+
export type GuardAgentEventListener = (payload: {
|
|
57
80
|
agent: unknown;
|
|
58
81
|
}) => void;
|
|
59
82
|
/** Either listener {@link ReasoningCollapseContext.on} accepts. */
|
|
60
|
-
export type GuardListener = GuardStreamListener |
|
|
83
|
+
export type GuardListener = GuardStreamListener | GuardAgentEventListener;
|
|
61
84
|
/** Listener options accepted by the harness event bus. */
|
|
62
85
|
export interface GuardListenerOptions {
|
|
63
86
|
/** Receive the event regardless of context filter checks. */
|
|
@@ -68,10 +91,18 @@ export interface GuardListenerOptions {
|
|
|
68
91
|
* every supported harness generation without importing generation-bound types.
|
|
69
92
|
*/
|
|
70
93
|
export interface ReasoningCollapseContext {
|
|
71
|
-
on?: (event: 'llm/stream' | 'agent/created', listener: GuardListener, options?: GuardListenerOptions) => unknown;
|
|
94
|
+
on?: (event: 'llm/stream' | 'agent/created' | 'agent/disposed', listener: GuardListener, options?: GuardListenerOptions) => unknown;
|
|
72
95
|
logger?: {
|
|
73
96
|
warn(message: string): void;
|
|
74
97
|
} | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* The harness Agent registry, read once so a guard installed after an Agent
|
|
100
|
+
* was created can still resolve it. A host without the service degrades to
|
|
101
|
+
* the `agent/created` map rather than failing this plugin's load.
|
|
102
|
+
*/
|
|
103
|
+
readonly agents?: {
|
|
104
|
+
get(id: unknown): unknown;
|
|
105
|
+
} | undefined;
|
|
75
106
|
}
|
|
76
107
|
/** Configuration for {@link installReasoningCollapseGuard}. */
|
|
77
108
|
export interface GuardOptions {
|
|
@@ -131,14 +162,15 @@ export declare const RESUME_HINT_STRICT: string;
|
|
|
131
162
|
* load.
|
|
132
163
|
*
|
|
133
164
|
* Resuming needs the live Agent for `cancel` and `steer`, and no supported
|
|
134
|
-
* generation hands the agent to `llm/stream`.
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
* turn
|
|
165
|
+
* generation hands the agent to `llm/stream`. The request does, though: every
|
|
166
|
+
* request the loop builds carries its `sessionId`, so the guard resolves the
|
|
167
|
+
* owning Agent per request through `ctx.agents.get`, falling back to the map
|
|
168
|
+
* `agent/created` fills. The per-turn break budget stays keyed on the
|
|
169
|
+
* request's own abort signal, which exists for a whole turn.
|
|
138
170
|
*
|
|
139
171
|
* @param ctx - plugin context.
|
|
140
172
|
* @param options - see {@link GuardOptions}; validated fail-loud.
|
|
141
|
-
* @returns a disposer removing
|
|
173
|
+
* @returns a disposer removing every listener, or undefined when the host
|
|
142
174
|
* exposes no event bus.
|
|
143
175
|
*/
|
|
144
176
|
export declare function installReasoningCollapseGuard(ctx: ReasoningCollapseContext, options?: GuardOptions): (() => void) | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/host/reasoning-collapse-guard/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/host/reasoning-collapse-guard/index.ts"],"names":[],"mappings":"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"}
|