@nexus-cortex/core 4.108.11 → 4.108.13
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/.env.defaults +14 -0
- package/dist/orchestrator/CortexOrchestrator.d.ts +5 -0
- package/dist/orchestrator/CortexOrchestrator.d.ts.map +1 -1
- package/dist/orchestrator/CortexOrchestrator.js +61 -12
- package/dist/orchestrator/CortexOrchestrator.js.map +1 -1
- package/dist/orchestrator/loopToolBlock.d.ts +16 -0
- package/dist/orchestrator/loopToolBlock.d.ts.map +1 -1
- package/dist/orchestrator/loopToolBlock.js +19 -0
- package/dist/orchestrator/loopToolBlock.js.map +1 -1
- package/dist/training/DecisionStore.d.ts +1 -1
- package/dist/training/DecisionStore.d.ts.map +1 -1
- package/dist/training/DecisionStore.js.map +1 -1
- package/dist/training/commandIdentity.d.ts +29 -0
- package/dist/training/commandIdentity.d.ts.map +1 -0
- package/dist/training/commandIdentity.js +370 -0
- package/dist/training/commandIdentity.js.map +1 -0
- package/dist/training/loopLadder.d.ts +26 -8
- package/dist/training/loopLadder.d.ts.map +1 -1
- package/dist/training/loopLadder.js +84 -16
- package/dist/training/loopLadder.js.map +1 -1
- package/dist/training/pollPattern.d.ts +15 -0
- package/dist/training/pollPattern.d.ts.map +1 -0
- package/dist/training/pollPattern.js +287 -0
- package/dist/training/pollPattern.js.map +1 -0
- package/dist/training/toolOutcome.d.ts +8 -0
- package/dist/training/toolOutcome.d.ts.map +1 -1
- package/dist/training/toolOutcome.js +6 -0
- package/dist/training/toolOutcome.js.map +1 -1
- package/package.json +3 -3
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* detector remains as the fast path for byte-identical spam.)
|
|
7
7
|
*/
|
|
8
8
|
import { type ToolOutcome } from './toolOutcome.js';
|
|
9
|
-
export type LadderAction = 'none' | 'remind' | 'diversify' | 'break';
|
|
9
|
+
export type LadderAction = 'none' | 'remind' | 'diversify' | 'break' | 'poll_steer';
|
|
10
10
|
export interface LadderResult {
|
|
11
11
|
action: LadderAction;
|
|
12
12
|
/** Consecutive not-ok observations for this (tool, approach). */
|
|
@@ -14,6 +14,12 @@ export interface LadderResult {
|
|
|
14
14
|
family?: string;
|
|
15
15
|
/** Which lens produced a 'neardup' result: 'hash' (approachHash equality) or 'similarity' (HB-LOOP-NEARDUP). */
|
|
16
16
|
trigger?: 'hash' | 'similarity';
|
|
17
|
+
/** R135 HB-POLL-LOOP: set on a 'poll_steer' result — the probe identity and the consecutive poll streak. */
|
|
18
|
+
poll?: {
|
|
19
|
+
probe: string;
|
|
20
|
+
waits: number;
|
|
21
|
+
waitSec?: number;
|
|
22
|
+
};
|
|
17
23
|
}
|
|
18
24
|
export interface LoopLadderThresholds {
|
|
19
25
|
remindAt?: number;
|
|
@@ -40,14 +46,22 @@ export declare class LoopLadder {
|
|
|
40
46
|
private readonly recentKeys;
|
|
41
47
|
private readonly nearDupNudged;
|
|
42
48
|
private readonly lastChunk;
|
|
49
|
+
private lastPollKey;
|
|
50
|
+
private pollStreak;
|
|
51
|
+
private pollWaitSum;
|
|
52
|
+
private pollWaitN;
|
|
53
|
+
private readonly lastProbe;
|
|
43
54
|
constructor(thresholds?: LoopLadderThresholds);
|
|
44
|
-
/** HB-LOOP-NEARDUP: windowed similarity count for an executing tool's normalized text.
|
|
55
|
+
/** HB-LOOP-NEARDUP: windowed similarity count for an executing tool's normalized text. R136: script identity
|
|
56
|
+
* dominates wrapper shape — entries whose identity differs are skipped before the text comparison. */
|
|
45
57
|
private observeSimilar;
|
|
46
58
|
/** 14b: outcome-agnostic windowed near-dup check. Returns a result when the
|
|
47
59
|
* same normalized approach recurs >= nudgeAt (diversify, once per key) or
|
|
48
60
|
* >= 2x nudgeAt (break) within the sliding window. */
|
|
49
61
|
private observeNearDup;
|
|
50
|
-
|
|
62
|
+
/** R135: true when this observation is a poll (a wait + read-only probe, or a bare probe repeating the tool's previous probe). */
|
|
63
|
+
private notePoll;
|
|
64
|
+
observe(toolName: string, outcome: Pick<ToolOutcome, 'status' | 'approachHash' | 'family' | 'approachText' | 'chunkRead' | 'commandIdentity' | 'poll'>): LadderResult;
|
|
51
65
|
}
|
|
52
66
|
/**
|
|
53
67
|
* Format the tool-result signal text for a ladder escalation. `null` for
|
|
@@ -90,17 +104,21 @@ export declare class ExactRepeatTracker {
|
|
|
90
104
|
private resultStreak;
|
|
91
105
|
/** A poll was observed and its result has not been reported yet (noteResult never called). */
|
|
92
106
|
private pendingResult;
|
|
107
|
+
/** R135b: the current key is poll-shaped — a POLL_TOOL_NAMES tool, or a Bash poll-and-wait (observe hint). */
|
|
108
|
+
private lastIsPoll;
|
|
93
109
|
/** Returns the CONSECUTIVE occurrence count for this exact call. For poll tools
|
|
94
110
|
* (POLL_TOOL_NAMES) the count is the trailing run of byte-identical stalled results + 1 —
|
|
95
111
|
* a live process or changing output never accumulates (falls back to the raw consecutive
|
|
96
112
|
* count when results were never reported via noteResult). */
|
|
97
|
-
observe(toolName: string, inputHash: string
|
|
98
|
-
|
|
113
|
+
observe(toolName: string, inputHash: string, opts?: {
|
|
114
|
+
isPoll?: boolean;
|
|
115
|
+
}): number;
|
|
116
|
+
/** Report the RESULT of the most recently observed call (poll-shaped keys only; other keys are ignored). */
|
|
99
117
|
noteResult(toolName: string, inputHash: string, content: string, metadata?: Record<string, unknown>): void;
|
|
100
118
|
}
|
|
101
|
-
/** Orchestrator glue (both tool loops): feed a batch's results back to the tracker. Non-poll
|
|
102
|
-
*
|
|
103
|
-
* the observe() call used. */
|
|
119
|
+
/** Orchestrator glue (both tool loops): feed a batch's results back to the tracker. Non-poll keys
|
|
120
|
+
* (neither a POLL_TOOL_NAMES tool nor a Bash poll hinted at observe) are ignored inside noteResult;
|
|
121
|
+
* the inputHash must be the same JSON.stringify(input) the observe() call used. */
|
|
104
122
|
export declare function notePollResults(tracker: ExactRepeatTracker, toolUseBlocks: ReadonlyArray<{
|
|
105
123
|
id: string;
|
|
106
124
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopLadder.d.ts","sourceRoot":"","sources":["../../src/training/loopLadder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"loopLadder.d.ts","sourceRoot":"","sources":["../../src/training/loopLadder.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { diceSimilarity } from './toolOutcome.js';
|
|
9
9
|
import { isChunkProgression } from './chunkReadProgression.js';
|
|
10
|
-
|
|
10
|
+
import { commandIdentityDiffers, commandIdentityDigest } from './commandIdentity.js';
|
|
11
|
+
const RANK = { none: 0, remind: 1, diversify: 2, break: 3, poll_steer: 1 };
|
|
11
12
|
function envInt(name, fallback) {
|
|
12
13
|
const v = parseInt(process.env[name] ?? '', 10);
|
|
13
14
|
return Number.isNaN(v) || v <= 0 ? fallback : v;
|
|
@@ -45,6 +46,8 @@ export class LoopLadder {
|
|
|
45
46
|
// 7; no PASSING session did (max 6 = healthy test iteration). Diversify at NEARDUP_SIM_AT (7), break at 2×.
|
|
46
47
|
nearDupSim;
|
|
47
48
|
nearDupSimAt;
|
|
49
|
+
// R136 HB-NEARDUP-SCRIPT-SHAPE: each entry carries the command identity (script paths / inline body);
|
|
50
|
+
// a DIFFERENT identity is never a near-duplicate no matter how similar the shared shell wrapper is.
|
|
48
51
|
recentSim = [];
|
|
49
52
|
simNudged = new Set();
|
|
50
53
|
recentKeys = [];
|
|
@@ -53,6 +56,17 @@ export class LoopLadder {
|
|
|
53
56
|
// gets a range-suffixed key (a NEW approach for the hash lens, poll guard and failure ladder) and
|
|
54
57
|
// skips the similarity lens; an identical/overlapping/backwards range keeps the plain hash key.
|
|
55
58
|
lastChunk = new Map();
|
|
59
|
+
// R135 HB-POLL-LOOP (2026-09-13): an OK poll-and-wait (sleep N; read-only probe — classifyToolOutcome's
|
|
60
|
+
// outcome.poll) is monitoring, not a stuck approach. It feeds NEITHER near-dup lens NOR the failure
|
|
61
|
+
// ladder; consecutive same-probe polls are counted here and answered with a 'poll_steer' nudge at the
|
|
62
|
+
// 3rd (then every 10th): move the wait into a background job + BashOutput. A bare read-only probe that
|
|
63
|
+
// immediately repeats the previous probe of the same tool is a poll too. Failing polls (curl exit 7)
|
|
64
|
+
// still climb the failure ladder as before. The old CORTEX_POLL_GUARD busy-wait remind is untouched.
|
|
65
|
+
lastPollKey = null;
|
|
66
|
+
pollStreak = 0;
|
|
67
|
+
pollWaitSum = 0;
|
|
68
|
+
pollWaitN = 0;
|
|
69
|
+
lastProbe = new Map();
|
|
56
70
|
constructor(thresholds = {}) {
|
|
57
71
|
this.remindAt = thresholds.remindAt ?? envInt('LOOP_REMIND_AT', 2);
|
|
58
72
|
this.diversifyAt = thresholds.diversifyAt ?? envInt('LOOP_DIVERSIFY_AT', 4);
|
|
@@ -75,12 +89,13 @@ export class LoopLadder {
|
|
|
75
89
|
const sim = parseFloat(process.env.NEARDUP_SIM ?? '');
|
|
76
90
|
this.nearDupSim = Number.isFinite(sim) && sim > 0 && sim <= 1 ? sim : 0.9;
|
|
77
91
|
}
|
|
78
|
-
/** HB-LOOP-NEARDUP: windowed similarity count for an executing tool's normalized text.
|
|
79
|
-
|
|
92
|
+
/** HB-LOOP-NEARDUP: windowed similarity count for an executing tool's normalized text. R136: script identity
|
|
93
|
+
* dominates wrapper shape — entries whose identity differs are skipped before the text comparison. */
|
|
94
|
+
observeSimilar(toolName, text, identity) {
|
|
80
95
|
if (!this.nearDupEnabled || !text)
|
|
81
96
|
return null;
|
|
82
|
-
const count = 1 + this.recentSim.filter((e) => e.tool === toolName && (e.text === text || diceSimilarity(e.text, text) >= this.nearDupSim)).length;
|
|
83
|
-
this.recentSim.push({ tool: toolName, text });
|
|
97
|
+
const count = 1 + this.recentSim.filter((e) => e.tool === toolName && !commandIdentityDiffers(e.identity, identity, this.nearDupSim) && (e.text === text || diceSimilarity(e.text, text) >= this.nearDupSim)).length;
|
|
98
|
+
this.recentSim.push({ tool: toolName, text, ...(identity ? { identity } : {}) });
|
|
84
99
|
if (this.recentSim.length > this.nearDupWindow)
|
|
85
100
|
this.recentSim.shift();
|
|
86
101
|
if (count >= this.nearDupSimAt * 2)
|
|
@@ -111,8 +126,23 @@ export class LoopLadder {
|
|
|
111
126
|
}
|
|
112
127
|
return null;
|
|
113
128
|
}
|
|
129
|
+
/** R135: true when this observation is a poll (a wait + read-only probe, or a bare probe repeating the tool's previous probe). */
|
|
130
|
+
notePoll(toolName, poll) {
|
|
131
|
+
const probe = poll?.probe;
|
|
132
|
+
const bareRepeat = !!poll && !poll.isPoll && !!probe && this.lastProbe.get(toolName) === probe;
|
|
133
|
+
if (probe)
|
|
134
|
+
this.lastProbe.set(toolName, probe);
|
|
135
|
+
else
|
|
136
|
+
this.lastProbe.delete(toolName);
|
|
137
|
+
return !!poll && (poll.isPoll || bareRepeat);
|
|
138
|
+
}
|
|
114
139
|
observe(toolName, outcome) {
|
|
115
140
|
let key = `${toolName}\n${outcome.approachHash}`;
|
|
141
|
+
// R136b: script identity (executed file / inline body) is part of the approach for the hash lens and the
|
|
142
|
+
// failure ladder — different scripts under one wrapper are different approaches; no identity = plain key.
|
|
143
|
+
const ident = commandIdentityDigest(outcome.commandIdentity);
|
|
144
|
+
if (ident)
|
|
145
|
+
key += `\n@${ident}`;
|
|
116
146
|
let progression = false;
|
|
117
147
|
if (outcome.chunkRead) {
|
|
118
148
|
const chunkKey = `${toolName}\n${outcome.chunkRead.file}`;
|
|
@@ -121,8 +151,35 @@ export class LoopLadder {
|
|
|
121
151
|
if (progression)
|
|
122
152
|
key += `\n${outcome.chunkRead.start}-${outcome.chunkRead.end}`;
|
|
123
153
|
}
|
|
154
|
+
const isPoll = this.notePoll(toolName, outcome.poll);
|
|
155
|
+
if (isPoll && outcome.status === 'ok') {
|
|
156
|
+
this.counts.delete(key); // an ok still resets the failure rung of this approach
|
|
157
|
+
const pkey = `${toolName}\n${outcome.poll.probe}`;
|
|
158
|
+
if (pkey === this.lastPollKey)
|
|
159
|
+
this.pollStreak += 1;
|
|
160
|
+
else {
|
|
161
|
+
this.lastPollKey = pkey;
|
|
162
|
+
this.pollStreak = 1;
|
|
163
|
+
this.pollWaitSum = 0;
|
|
164
|
+
this.pollWaitN = 0;
|
|
165
|
+
}
|
|
166
|
+
if (typeof outcome.poll.waitSec === 'number') {
|
|
167
|
+
this.pollWaitSum += outcome.poll.waitSec;
|
|
168
|
+
this.pollWaitN += 1;
|
|
169
|
+
}
|
|
170
|
+
if (this.pollStreak === 3 || (this.pollStreak > 3 && this.pollStreak % 10 === 0)) {
|
|
171
|
+
return {
|
|
172
|
+
action: 'poll_steer', count: this.pollStreak, family: 'poll',
|
|
173
|
+
poll: { probe: outcome.poll.probe, waits: this.pollStreak, ...(this.pollWaitN ? { waitSec: Math.round(this.pollWaitSum / this.pollWaitN) } : {}) },
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return { action: 'none', count: 0 };
|
|
177
|
+
}
|
|
178
|
+
// A non-poll call of the same tool ends the consecutive streak (a failing poll keeps it).
|
|
179
|
+
if (!isPoll && this.lastPollKey?.startsWith(`${toolName}\n`))
|
|
180
|
+
this.lastPollKey = null;
|
|
124
181
|
const hashDup = this.observeNearDup(key);
|
|
125
|
-
const simDup = this.observeSimilar(toolName, progression ? undefined : outcome.approachText);
|
|
182
|
+
const simDup = this.observeSimilar(toolName, progression ? undefined : outcome.approachText, outcome.commandIdentity);
|
|
126
183
|
// the more severe of the two near-dup lenses
|
|
127
184
|
const nearDup = hashDup && simDup ? (RANK[simDup.action] >= RANK[hashDup.action] ? simDup : hashDup) : (simDup ?? hashDup);
|
|
128
185
|
if (outcome.status === 'ok') {
|
|
@@ -172,6 +229,14 @@ export class LoopLadder {
|
|
|
172
229
|
* already cover the remind rung; the ladder speaks only when it must.
|
|
173
230
|
*/
|
|
174
231
|
export function formatLadderSignal(toolName, result) {
|
|
232
|
+
// R135 HB-POLL-LOOP: a poll-and-wait streak — steer the wait off the turn; the executor stays available.
|
|
233
|
+
if (result.action === 'poll_steer') {
|
|
234
|
+
const p = result.poll;
|
|
235
|
+
const waits = p?.waitSec !== undefined ? `${p.waits} waits of ~${p.waitSec} s on ${p.probe}` : `${p?.waits ?? result.count} repeats of ${p?.probe ?? toolName}`;
|
|
236
|
+
return (`<system-reminder>\nPolling pattern detected (${waits}). Move the wait off the turn: launch the probe loop with ` +
|
|
237
|
+
`run_in_background (or \`persistentSession\`) and read it with BashOutput when you need it; keep any foreground wait <= 60 s. ` +
|
|
238
|
+
`${toolName} stays available.\n</system-reminder>`);
|
|
239
|
+
}
|
|
175
240
|
// Poll guard (run3 busy-wait class): a remind with family 'poll' is a
|
|
176
241
|
// SUCCEEDING-repeat nudge, not a failure escalation — inject its own text.
|
|
177
242
|
if (result.action === 'remind' && result.family === 'poll') {
|
|
@@ -254,11 +319,13 @@ export class ExactRepeatTracker {
|
|
|
254
319
|
resultStreak = 0;
|
|
255
320
|
/** A poll was observed and its result has not been reported yet (noteResult never called). */
|
|
256
321
|
pendingResult = false;
|
|
322
|
+
/** R135b: the current key is poll-shaped — a POLL_TOOL_NAMES tool, or a Bash poll-and-wait (observe hint). */
|
|
323
|
+
lastIsPoll = false;
|
|
257
324
|
/** Returns the CONSECUTIVE occurrence count for this exact call. For poll tools
|
|
258
325
|
* (POLL_TOOL_NAMES) the count is the trailing run of byte-identical stalled results + 1 —
|
|
259
326
|
* a live process or changing output never accumulates (falls back to the raw consecutive
|
|
260
327
|
* count when results were never reported via noteResult). */
|
|
261
|
-
observe(toolName, inputHash) {
|
|
328
|
+
observe(toolName, inputHash, opts) {
|
|
262
329
|
const key = `${toolName}\u0000${inputHash}`;
|
|
263
330
|
if (key === this.lastKey) {
|
|
264
331
|
this.count += 1;
|
|
@@ -270,17 +337,18 @@ export class ExactRepeatTracker {
|
|
|
270
337
|
this.resultStreak = 0;
|
|
271
338
|
this.pendingResult = false;
|
|
272
339
|
}
|
|
273
|
-
|
|
340
|
+
// R135b HB-POLL-LOOP: a Bash poll-and-wait (outcome.poll.isPoll, hinted by the caller) gets the same
|
|
341
|
+
// result-aware count as BashOutput — identical polls with CHANGING results are progress, not a repeat.
|
|
342
|
+
this.lastIsPoll = POLL_TOOL_NAMES.has(toolName) || opts?.isPoll === true;
|
|
343
|
+
if (!this.lastIsPoll)
|
|
274
344
|
return this.count;
|
|
275
345
|
const effective = this.count > 1 && this.pendingResult ? this.count : this.resultStreak + 1;
|
|
276
346
|
this.pendingResult = true;
|
|
277
347
|
return effective;
|
|
278
348
|
}
|
|
279
|
-
/** Report the RESULT of the most recently observed call (poll
|
|
349
|
+
/** Report the RESULT of the most recently observed call (poll-shaped keys only; other keys are ignored). */
|
|
280
350
|
noteResult(toolName, inputHash, content, metadata) {
|
|
281
|
-
if (!
|
|
282
|
-
return;
|
|
283
|
-
if (`${toolName}\u0000${inputHash}` !== this.lastKey)
|
|
351
|
+
if (`${toolName}\u0000${inputHash}` !== this.lastKey || !this.lastIsPoll)
|
|
284
352
|
return;
|
|
285
353
|
this.pendingResult = false;
|
|
286
354
|
if (isPollResultRunning(toolName, content, metadata)) {
|
|
@@ -293,13 +361,13 @@ export class ExactRepeatTracker {
|
|
|
293
361
|
this.lastResultHash = h;
|
|
294
362
|
}
|
|
295
363
|
}
|
|
296
|
-
/** Orchestrator glue (both tool loops): feed a batch's results back to the tracker. Non-poll
|
|
297
|
-
*
|
|
298
|
-
* the observe() call used. */
|
|
364
|
+
/** Orchestrator glue (both tool loops): feed a batch's results back to the tracker. Non-poll keys
|
|
365
|
+
* (neither a POLL_TOOL_NAMES tool nor a Bash poll hinted at observe) are ignored inside noteResult;
|
|
366
|
+
* the inputHash must be the same JSON.stringify(input) the observe() call used. */
|
|
299
367
|
export function notePollResults(tracker, toolUseBlocks, toolResults) {
|
|
300
368
|
const inputById = new Map(toolUseBlocks.map((b) => [b.id, b.input]));
|
|
301
369
|
for (const tr of toolResults) {
|
|
302
|
-
if (!POLL_TOOL_NAMES.has(tr.tool_name))
|
|
370
|
+
if (!POLL_TOOL_NAMES.has(tr.tool_name) && tr.tool_name !== 'Bash')
|
|
303
371
|
continue;
|
|
304
372
|
if (!inputById.has(tr.tool_use_id))
|
|
305
373
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loopLadder.js","sourceRoot":"","sources":["../../src/training/loopLadder.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"loopLadder.js","sourceRoot":"","sources":["../../src/training/loopLadder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAoB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAkB,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAwB,MAAM,sBAAsB,CAAC;AAe3G,MAAM,IAAI,GAAiC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AAQzG,SAAS,MAAM,CAAC,IAAY,EAAE,QAAgB;IAC5C,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,OAAO,UAAU;IACJ,QAAQ,CAAS;IACjB,WAAW,CAAS;IACpB,OAAO,CAAS;IAChB,MAAM,GAAG,IAAI,GAAG,EAA8C,CAAC;IAChF,wEAAwE;IACxE,4EAA4E;IAC5E,qEAAqE;IACrE,8DAA8D;IAC9D,2EAA2E;IAC3E,0EAA0E;IAC1E,yEAAyE;IACxD,MAAM,CAAS;IACf,WAAW,CAAU;IAC9B,SAAS,GAAkB,IAAI,CAAC;IAChC,QAAQ,GAAG,CAAC,CAAC;IACb,UAAU,GAAG,KAAK,CAAC;IAC3B,0EAA0E;IAC1E,2EAA2E;IAC3E,4EAA4E;IAC5E,0EAA0E;IAC1E,qEAAqE;IACpD,cAAc,CAAU;IACxB,aAAa,CAAS;IACtB,cAAc,CAAS;IACxC,gGAAgG;IAChG,qGAAqG;IACrG,qGAAqG;IACrG,iGAAiG;IACjG,wGAAwG;IACxG,4GAA4G;IAC3F,UAAU,CAAS;IACnB,YAAY,CAAS;IACtC,sGAAsG;IACtG,oGAAoG;IACnF,SAAS,GAAsE,EAAE,CAAC;IAClF,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,UAAU,GAAa,EAAE,CAAC;IAC1B,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACnD,+FAA+F;IAC/F,kGAAkG;IAClG,gGAAgG;IAC/E,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1D,wGAAwG;IACxG,oGAAoG;IACpG,sGAAsG;IACtG,uGAAuG;IACvG,qGAAqG;IACrG,qGAAqG;IAC7F,WAAW,GAAkB,IAAI,CAAC;IAClC,UAAU,GAAG,CAAC,CAAC;IACf,WAAW,GAAG,CAAC,CAAC;IAChB,SAAS,GAAG,CAAC,CAAC;IACL,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvD,YAAY,aAAmC,EAAE;QAC/C,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QACnE,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,WAAW,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;QACzF,IAAI,CAAC,cAAc,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;QACjG,6EAA6E;QAC7E,0EAA0E;QAC1E,8EAA8E;QAC9E,gFAAgF;QAChF,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAClD,mFAAmF;QACnF,mFAAmF;QACnF,6EAA6E;QAC7E,iFAAiF;QACjF,4EAA4E;QAC5E,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5E,CAAC;IAED;2GACuG;IAC/F,cAAc,CAAC,QAAgB,EAAE,IAAwB,EAAE,QAA0B;QAC3F,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAC/C,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,CAC9J,CAAC,MAAM,CAAC;QACT,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACjF,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa;YAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvE,IAAI,KAAK,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAChH,MAAM,QAAQ,GAAG,GAAG,QAAQ,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACrD,IAAI,KAAK,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAClF,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;2DAEuD;IAC/C,cAAc,CAAC,GAAW;QAChC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa;YAAE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACzE,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QAC5D,IAAI,KAAK,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACxE,CAAC;QACD,IAAI,KAAK,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC5E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kIAAkI;IAC1H,QAAQ,CAAC,QAAgB,EAAE,IAAyB;QAC1D,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;QAC1B,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC;QAC/F,IAAI,KAAK;YAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;;YAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrF,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,QAAgB,EAAE,OAA4H;QACpJ,IAAI,GAAG,GAAG,GAAG,QAAQ,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC;QACjD,yGAAyG;QACzG,0GAA0G;QAC1G,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,KAAK;YAAE,GAAG,IAAI,MAAM,KAAK,EAAE,CAAC;QAChC,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,GAAG,QAAQ,KAAK,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YAC1D,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YAClF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;YAChD,IAAI,WAAW;gBAAE,GAAG,IAAI,KAAK,OAAO,CAAC,SAAS,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;QAClF,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,uDAAuD;YAChF,MAAM,IAAI,GAAG,GAAG,QAAQ,KAAK,OAAO,CAAC,IAAK,CAAC,KAAK,EAAE,CAAC;YACnD,IAAI,IAAI,KAAK,IAAI,CAAC,WAAW;gBAAE,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;iBAC/C,CAAC;gBAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;gBAAC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;gBAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;YAAC,CAAC;YAChG,IAAI,OAAO,OAAO,CAAC,IAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAAC,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,IAAK,CAAC,OAAO,CAAC;gBAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;YAAC,CAAC;YAClH,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;gBACjF,OAAO;oBACL,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM;oBAC5D,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,IAAK,CAAC,KAAM,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;iBACrJ,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACtC,CAAC;QACD,0FAA0F;QAC1F,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,GAAG,QAAQ,IAAI,CAAC;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACtF,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QACtH,6CAA6C;QAC7C,MAAM,OAAO,GAAG,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC;QAC3H,IAAI,OAAO,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,IAAI,GAAG,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC3B,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;oBACrB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;oBAClB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;gBAC1B,CAAC;gBACD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;oBACrD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;oBACvB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;gBACpE,CAAC;YACH,CAAC;YACD,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;QACjB,IAAI,OAAO,CAAC,MAAM;YAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE5B,IAAI,MAAM,GAAiB,MAAM,CAAC;QAClC,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,GAAG,OAAO,CAAC;aAC7C,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW;YAAE,MAAM,GAAG,WAAW,CAAC;aAC1D,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,GAAG,QAAQ,CAAC;QACzD,2FAA2F;QAC3F,uFAAuF;QACvF,IAAI,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,OAAO,CAAC;QACnE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3F,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,MAAoB;IACvE,yGAAyG;IACzG,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QACtB,MAAM,KAAK,GAAG,CAAC,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,OAAO,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,eAAe,CAAC,EAAE,KAAK,IAAI,QAAQ,EAAE,CAAC;QAChK,OAAO,CACL,gDAAgD,KAAK,4DAA4D;YACjH,+HAA+H;YAC/H,GAAG,QAAQ,uCAAuC,CACnD,CAAC;IACJ,CAAC;IACD,sEAAsE;IACtE,2EAA2E;IAC3E,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3D,OAAO,CACL,kEAAkE,QAAQ,WAAW;YACrF,GAAG,MAAM,CAAC,KAAK,2EAA2E;YAC1F,4FAA4F;YAC5F,uEAAuE,CACxE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjE,OAAO,CACL,8CAA8C,MAAM,CAAC,KAAK,mBAAmB,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,qCAAqC,QAAQ,YAAY;YAChL,2GAA2G;YAC3G,qGAAqG,CACtG,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7D,OAAO,CACL,qDAAqD,QAAQ,0BAA0B,MAAM,CAAC,KAAK,uDAAuD;YAC1J,iLAAiL,CAClL,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,sBAAsB,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,CACL,4CAA4C,QAAQ,wBAAwB,MAAM,CAAC,KAAK,GAAG;YAC3F,oBAAoB,GAAG,iEAAiE;YACxF,sFAAsF;YACtF,0FAA0F;YAC1F,oEAAoE,CACrE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO,CACL,2DAA2D,MAAM,CAAC,KAAK,qBAAqB;YAC5F,qFAAqF;YACrF,0FAA0F;YAC1F,qGAAqG,CACtG,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAE9F;;sBAEsB;AACtB,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,OAAe,EAAE,QAAkC;IACvG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,2FAA2F;AAC3F,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC,GAAG,IAAI,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,OAAO,kBAAkB;IACrB,OAAO,GAAkB,IAAI,CAAC;IAC9B,KAAK,GAAG,CAAC,CAAC;IAClB,sFAAsF;IAC9E,cAAc,GAAkB,IAAI,CAAC;IAC7C,6FAA6F;IACrF,YAAY,GAAG,CAAC,CAAC;IACzB,8FAA8F;IACtF,aAAa,GAAG,KAAK,CAAC;IAC9B,8GAA8G;IACtG,UAAU,GAAG,KAAK,CAAC;IAE3B;;;kEAG8D;IAC9D,OAAO,CAAC,QAAgB,EAAE,SAAiB,EAAE,IAA2B;QACtE,MAAM,GAAG,GAAG,GAAG,QAAQ,SAAS,SAAS,EAAE,CAAC;QAC5C,IAAI,GAAG,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;YACf,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC7B,CAAC;QACD,qGAAqG;QACrG,uGAAuG;QACvG,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACzE,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAC5F,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,4GAA4G;IAC5G,UAAU,CAAC,QAAgB,EAAE,SAAiB,EAAE,OAAe,EAAE,QAAkC;QACjG,IAAI,GAAG,QAAQ,SAAS,SAAS,EAAE,KAAK,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QACjF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;YACrD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,CAAC,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF;AAED;;oFAEoF;AACpF,MAAM,UAAU,eAAe,CAC7B,OAA2B,EAC3B,aAA0E,EAC1E,WAA2H;IAE3H,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrE,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,SAAS,KAAK,MAAM;YAAE,SAAS;QAC5E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC;YAAE,SAAS;QAC7C,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;IACjH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PollPattern {
|
|
2
|
+
/** A wait combined with a read-only probe (and nothing else). */
|
|
3
|
+
isPoll: boolean;
|
|
4
|
+
/** Total foreground wait in seconds when known (sum of sleeps; the per-iteration sleep of a loop). */
|
|
5
|
+
waitSec?: number;
|
|
6
|
+
/** Stable identity of the probe (`curl localhost:5000/api/v1/config`, `tail /tmp/train.log`, …); set for
|
|
7
|
+
* bare read-only probes too so an immediate repeat can be recognized as a poll. */
|
|
8
|
+
probe?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Recognize a poll-and-wait command. `isPoll` requires at least one wait AND at least one read-only probe
|
|
12
|
+
* and NO unsafe segment; `probe` is the identity of the first probe (set for bare probes too).
|
|
13
|
+
*/
|
|
14
|
+
export declare function detectPollPattern(command: string): PollPattern;
|
|
15
|
+
//# sourceMappingURL=pollPattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pollPattern.d.ts","sourceRoot":"","sources":["../../src/training/pollPattern.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,MAAM,EAAE,OAAO,CAAC;IAChB,sGAAsG;IACtG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;wFACoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmLD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAc9D"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pollPattern — R135 HB-POLL-LOOP (2026-09-13).
|
|
3
|
+
*
|
|
4
|
+
* Terminal-Bench 4.0 ctr-optimization (a 48-sim-hour task, 1 sim hour = 6 real minutes): the model had to
|
|
5
|
+
* observe an eval window hours later and polled with `sleep 115; curl -s …/config | python3 -c "…print(…)"`
|
|
6
|
+
* variants. The near-dup similarity lens scored every poll as a repeat: loop_escalation diversify x3 →
|
|
7
|
+
* loop_tool_block neardup-similarity x3 (redirect Read/Write/Edit) → "Bash is disabled" → the model routed
|
|
8
|
+
* around via CreateArtifactTool oneshot x14 and finalized WITHOUT observing its eval window.
|
|
9
|
+
*
|
|
10
|
+
* ONE pure helper: recognize a POLL — a WAIT (`sleep N`, `timeout N` wrapping a wait, `until`/`while … sleep`
|
|
11
|
+
* loop) combined with a READ-ONLY probe (curl/wget/http GET, cat/tail/ls/stat/ps/pgrep/docker ps|logs/
|
|
12
|
+
* kubectl get/systemctl status/nc -z/ss/netstat/test -f, `python3 -c` bodies that only GET and print). A
|
|
13
|
+
* bare read-only probe with NO wait is reported with its probe identity (isPoll=false) so the ladder can
|
|
14
|
+
* treat an immediate repeat of the same probe as a poll. CONSERVATIVE: any write verb (POST/PUT/DELETE,
|
|
15
|
+
* `-d`, a `>` redirect outside /tmp, rm/mv/cp, git commit/push, installs, build/test runners, scripts that
|
|
16
|
+
* are not obviously probes) or anything unrecognized → NOT a poll.
|
|
17
|
+
*/
|
|
18
|
+
import { splitSegments } from './commandIdentity.js';
|
|
19
|
+
const LOOP_KEYWORDS = /^(until|while|done|do|then|else|elif|fi|if|for|in)\b\s*|^!\s*/;
|
|
20
|
+
const WRAPPERS = new Set(['time', 'nice', 'nohup', 'stdbuf', 'command', 'env', 'sudo']);
|
|
21
|
+
const NEUTRAL_HEADS = new Set(['cd', 'echo', 'printf', 'true', ':', 'export', 'set', 'date', 'pwd', 'sync']);
|
|
22
|
+
// Read-only probe heads (first token). Verbs of multi-verb tools are checked separately below.
|
|
23
|
+
const PROBE_HEADS = new Set([
|
|
24
|
+
'cat', 'tail', 'head', 'ls', 'stat', 'wc', 'ps', 'pgrep', 'ss', 'netstat', 'lsof', 'df', 'du', 'free', 'uptime',
|
|
25
|
+
'test', '[', '[[', 'grep', 'egrep', 'fgrep', 'rg', 'jq', 'nvidia-smi', 'top', 'nc', 'ncat', 'ping', 'dig', 'nslookup',
|
|
26
|
+
'journalctl', 'id', 'whoami', 'hostname', 'file', 'find', 'md5sum', 'sha256sum', 'sqlite3',
|
|
27
|
+
]);
|
|
28
|
+
const STATUS_HEADS = new Set(['tail', 'cat', 'ps', 'pgrep', 'ss', 'netstat', 'nc', 'ncat', 'lsof', 'nvidia-smi', 'top', 'journalctl', 'ping', 'df', 'free', 'uptime']);
|
|
29
|
+
const VERB_TOOLS = {
|
|
30
|
+
docker: new Set(['ps', 'logs', 'inspect', 'stats', 'top', 'port', 'images', 'version', 'info']),
|
|
31
|
+
kubectl: new Set(['get', 'describe', 'logs', 'top', 'version']),
|
|
32
|
+
systemctl: new Set(['status', 'is-active', 'is-enabled', 'is-failed', 'show', 'list-units']),
|
|
33
|
+
git: new Set(['status', 'log', 'diff', 'show', 'branch', 'rev-parse']),
|
|
34
|
+
podman: new Set(['ps', 'logs', 'inspect', 'stats']),
|
|
35
|
+
'docker-compose': new Set(['ps', 'logs']),
|
|
36
|
+
};
|
|
37
|
+
const CURL_WRITE_FLAGS = /^(-d|--data(-\w+)?|-F|--form|-T|--upload-file|--json)$/;
|
|
38
|
+
const WGET_WRITE_FLAGS = /^(--post-data|--post-file|--method|--body-data|--body-file)/;
|
|
39
|
+
const URL_RE = /(?:https?:\/\/[^\s'"|;&)]+|\b(?:localhost|127\.0\.0\.1|0\.0\.0\.0)(?::\d+)?(?:\/[^\s'"|;&)]*)?)/;
|
|
40
|
+
const PY_WRITE_RE = /\b(requests\.(post|put|delete|patch)|urllib\.request\.Request\([^)]*data=|urlopen\([^)]*data=|method\s*=\s*['"](POST|PUT|DELETE|PATCH)|open\([^)]*['"][wax][b+]*['"]|\.write\(|json\.dump\(|subprocess|os\.system|os\.(remove|unlink|rename|makedirs|mkdir)|shutil\.|Popen|pickle\.dump\()/;
|
|
41
|
+
const PY_PROBE_RE = /\b(print\(|requests\.(get|head)\(|urlopen\(|sys\.stdin|json\.load\()/;
|
|
42
|
+
/** `sleep 115` → 115, `sleep 2m` → 120, `sleep 1.5` → 1.5; undefined when not a literal. */
|
|
43
|
+
function parseSeconds(tok) {
|
|
44
|
+
if (!tok)
|
|
45
|
+
return undefined;
|
|
46
|
+
const m = /^(\d+(?:\.\d+)?)([smhd]?)$/.exec(tok);
|
|
47
|
+
if (!m)
|
|
48
|
+
return undefined;
|
|
49
|
+
const n = parseFloat(m[1]);
|
|
50
|
+
const mult = { '': 1, s: 1, m: 60, h: 3600, d: 86400 }[m[2]];
|
|
51
|
+
return n * mult;
|
|
52
|
+
}
|
|
53
|
+
/** Whitespace tokenizer keeping quoted spans (unquoted text) as one token. */
|
|
54
|
+
function tokenize(seg) {
|
|
55
|
+
const toks = [];
|
|
56
|
+
let cur = '';
|
|
57
|
+
let inTok = false;
|
|
58
|
+
let quote = null;
|
|
59
|
+
for (let i = 0; i < seg.length; i++) {
|
|
60
|
+
const ch = seg[i];
|
|
61
|
+
if (quote) {
|
|
62
|
+
if (ch === quote) {
|
|
63
|
+
quote = null;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (ch === '\\' && quote === '"' && i + 1 < seg.length) {
|
|
67
|
+
cur += seg[++i];
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
cur += ch;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (ch === '"' || ch === "'") {
|
|
74
|
+
quote = ch;
|
|
75
|
+
inTok = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (ch === '\\' && i + 1 < seg.length) {
|
|
79
|
+
cur += seg[++i];
|
|
80
|
+
inTok = true;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (/\s/.test(ch)) {
|
|
84
|
+
if (inTok) {
|
|
85
|
+
toks.push(cur);
|
|
86
|
+
cur = '';
|
|
87
|
+
inTok = false;
|
|
88
|
+
}
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
cur += ch;
|
|
92
|
+
inTok = true;
|
|
93
|
+
}
|
|
94
|
+
if (inTok)
|
|
95
|
+
toks.push(cur);
|
|
96
|
+
return toks;
|
|
97
|
+
}
|
|
98
|
+
/** A `>`/`>>` redirect to anything but /dev/null or /tmp is a write. Returns the segment with redirects stripped, or null. */
|
|
99
|
+
function stripRedirects(seg) {
|
|
100
|
+
let unsafe = false;
|
|
101
|
+
const out = seg.replace(/(?:\d*|&)>{1,2}\s*([^\s;|&]+)/g, (_m, target) => {
|
|
102
|
+
if (target === '/dev/null' || target === '&1' || target === '&2' || target.startsWith('/tmp/'))
|
|
103
|
+
return ' ';
|
|
104
|
+
unsafe = true;
|
|
105
|
+
return ' ';
|
|
106
|
+
}).replace(/<\s*[^\s;|&]+/g, ' ');
|
|
107
|
+
return unsafe ? null : out;
|
|
108
|
+
}
|
|
109
|
+
function outputTargetOk(target) {
|
|
110
|
+
return !!target && (target === '-' || target === '/dev/null' || target.startsWith('/tmp/'));
|
|
111
|
+
}
|
|
112
|
+
function probeId(head, args) {
|
|
113
|
+
const url = URL_RE.exec(args.join(' '))?.[0];
|
|
114
|
+
if (url)
|
|
115
|
+
return `${head} ${url.replace(/^https?:\/\//, '')}`;
|
|
116
|
+
const target = args.find((a) => !a.startsWith('-'));
|
|
117
|
+
return target ? `${head} ${target}` : head;
|
|
118
|
+
}
|
|
119
|
+
function classifyCurl(args) {
|
|
120
|
+
for (let i = 0; i < args.length; i++) {
|
|
121
|
+
const a = args[i];
|
|
122
|
+
if (CURL_WRITE_FLAGS.test(a))
|
|
123
|
+
return { kind: 'unsafe' };
|
|
124
|
+
if (a === '-X' || a === '--request') {
|
|
125
|
+
if (!/^(GET|HEAD)$/i.test(args[i + 1] ?? ''))
|
|
126
|
+
return { kind: 'unsafe' };
|
|
127
|
+
i++;
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (/^(-X|--request=)/.test(a) && !/^(-X|--request=)(GET|HEAD)$/i.test(a))
|
|
131
|
+
return { kind: 'unsafe' };
|
|
132
|
+
if (a === '-o' || a === '--output') {
|
|
133
|
+
if (!outputTargetOk(args[i + 1]))
|
|
134
|
+
return { kind: 'unsafe' };
|
|
135
|
+
i++;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (a === '-O' || a === '--remote-name')
|
|
139
|
+
return { kind: 'unsafe' };
|
|
140
|
+
}
|
|
141
|
+
return { kind: 'probe', probe: probeId('curl', args), status: true };
|
|
142
|
+
}
|
|
143
|
+
function classifyWget(args) {
|
|
144
|
+
let stdout = false;
|
|
145
|
+
for (let i = 0; i < args.length; i++) {
|
|
146
|
+
const a = args[i];
|
|
147
|
+
if (WGET_WRITE_FLAGS.test(a))
|
|
148
|
+
return { kind: 'unsafe' };
|
|
149
|
+
if (a === '--spider')
|
|
150
|
+
stdout = true;
|
|
151
|
+
if (a === '-O' || a === '--output-document') {
|
|
152
|
+
if (!outputTargetOk(args[i + 1]))
|
|
153
|
+
return { kind: 'unsafe' };
|
|
154
|
+
stdout = true;
|
|
155
|
+
i++;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (/^-q?O-$/.test(a) || /^--output-document=/.test(a)) {
|
|
159
|
+
if (a.endsWith('-') || outputTargetOk(a.split('=')[1]))
|
|
160
|
+
stdout = true;
|
|
161
|
+
else
|
|
162
|
+
return { kind: 'unsafe' };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return stdout ? { kind: 'probe', probe: probeId('wget', args), status: true } : { kind: 'unsafe' }; // a plain wget downloads a file into cwd
|
|
166
|
+
}
|
|
167
|
+
function classifyHttpie(args) {
|
|
168
|
+
const method = /^[A-Z]+$/.test(args[0] ?? '') ? args[0] : 'GET';
|
|
169
|
+
if (!/^(GET|HEAD)$/.test(method))
|
|
170
|
+
return { kind: 'unsafe' };
|
|
171
|
+
if (args.some((a) => /^[\w-]+(:=|=)(?!=)/.test(a) && !a.includes(':')))
|
|
172
|
+
return { kind: 'unsafe' }; // request items = an implicit POST
|
|
173
|
+
return { kind: 'probe', probe: probeId('http', args), status: true };
|
|
174
|
+
}
|
|
175
|
+
/** `python3 -c BODY`: a probe only when the body GETs/prints and never writes. */
|
|
176
|
+
function classifyPythonInline(body) {
|
|
177
|
+
if (PY_WRITE_RE.test(body))
|
|
178
|
+
return { kind: 'unsafe' };
|
|
179
|
+
const sleep = /time\.sleep\(\s*(\d+(?:\.\d+)?)\s*\)/.exec(body);
|
|
180
|
+
if (!PY_PROBE_RE.test(body)) {
|
|
181
|
+
return sleep && /^\s*import\s+time\s*;?\s*time\.sleep\([^)]*\)\s*$/.test(body) ? { kind: 'wait', waitSec: parseFloat(sleep[1]) } : { kind: 'unsafe' };
|
|
182
|
+
}
|
|
183
|
+
const url = URL_RE.exec(body)?.[0];
|
|
184
|
+
return { kind: 'probe', probe: url ? `python3 ${url.replace(/^https?:\/\//, '')}` : 'python3 -c probe', ...(sleep ? { waitSec: parseFloat(sleep[1]) } : {}) };
|
|
185
|
+
}
|
|
186
|
+
function classifySegment(raw) {
|
|
187
|
+
let bare = raw.trim();
|
|
188
|
+
if (/^for\s+\w+\s+in\b/.test(bare))
|
|
189
|
+
return { kind: 'neutral' }; // `for i in 1 2 3` header (the body segments are classified on their own)
|
|
190
|
+
for (let prev = ''; prev !== bare;) {
|
|
191
|
+
prev = bare;
|
|
192
|
+
bare = bare.replace(LOOP_KEYWORDS, '').trim();
|
|
193
|
+
}
|
|
194
|
+
const stripped = stripRedirects(bare);
|
|
195
|
+
if (stripped === null)
|
|
196
|
+
return { kind: 'unsafe' };
|
|
197
|
+
let toks = tokenize(stripped.trim());
|
|
198
|
+
while (toks.length && /^[A-Za-z_]\w*=/.test(toks[0]))
|
|
199
|
+
toks = toks.slice(1); // VAR=x prefix
|
|
200
|
+
if (toks.length === 0)
|
|
201
|
+
return { kind: 'neutral' };
|
|
202
|
+
let head = toks[0];
|
|
203
|
+
// Wrappers: `timeout N cmd` is a wait only when cmd is itself a wait / blocking probe; other wrappers are transparent.
|
|
204
|
+
let timeoutSec;
|
|
205
|
+
for (;;) {
|
|
206
|
+
if (head === 'timeout') {
|
|
207
|
+
let j = 1;
|
|
208
|
+
while (toks[j]?.startsWith('-'))
|
|
209
|
+
j += /^(-s|--signal|-k|--kill-after)$/.test(toks[j]) ? 2 : 1;
|
|
210
|
+
timeoutSec = parseSeconds(toks[j]);
|
|
211
|
+
toks = toks.slice(j + 1);
|
|
212
|
+
head = toks[0] ?? '';
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (WRAPPERS.has(head)) {
|
|
216
|
+
toks = toks.slice(1);
|
|
217
|
+
while (toks[0]?.startsWith('-'))
|
|
218
|
+
toks = toks.slice(1);
|
|
219
|
+
head = toks[0] ?? '';
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
if (!head)
|
|
225
|
+
return { kind: 'neutral' };
|
|
226
|
+
const args = toks.slice(1);
|
|
227
|
+
if (head === 'sleep')
|
|
228
|
+
return { kind: 'wait', waitSec: parseSeconds(args[0]) };
|
|
229
|
+
if (/^(bash|sh|zsh|dash)$/.test(head) && args[0] === '-c' && args[1]) {
|
|
230
|
+
const inner = detectPollPattern(args[1]);
|
|
231
|
+
if (inner.isPoll)
|
|
232
|
+
return { kind: 'probe', probe: inner.probe, waitSec: inner.waitSec ?? timeoutSec, status: true };
|
|
233
|
+
return { kind: 'unsafe' };
|
|
234
|
+
}
|
|
235
|
+
if (/^(python[\d.]*|pypy[\d]*)$/.test(head)) {
|
|
236
|
+
const c = args.indexOf('-c');
|
|
237
|
+
return c >= 0 && args[c + 1] ? classifyPythonInline(args[c + 1]) : { kind: 'unsafe' };
|
|
238
|
+
}
|
|
239
|
+
if (head === 'curl')
|
|
240
|
+
return classifyCurl(args);
|
|
241
|
+
if (head === 'wget')
|
|
242
|
+
return classifyWget(args);
|
|
243
|
+
if (head === 'http' || head === 'https' || head === 'xh')
|
|
244
|
+
return classifyHttpie(args);
|
|
245
|
+
if (NEUTRAL_HEADS.has(head))
|
|
246
|
+
return { kind: 'neutral' };
|
|
247
|
+
const verbs = VERB_TOOLS[head];
|
|
248
|
+
if (verbs)
|
|
249
|
+
return verbs.has(args[0] ?? '') ? { kind: 'probe', probe: probeId(`${head} ${args[0]}`, args.slice(1)), status: head !== 'git' } : { kind: 'unsafe' };
|
|
250
|
+
if (PROBE_HEADS.has(head)) {
|
|
251
|
+
if (head === 'sqlite3' && !args.some((a) => /^\s*select\b/i.test(a)))
|
|
252
|
+
return { kind: 'unsafe' };
|
|
253
|
+
if ((head === 'nc' || head === 'ncat') && !args.includes('-z'))
|
|
254
|
+
return { kind: 'unsafe' };
|
|
255
|
+
if (head === 'find' && args.some((a) => /^-(delete|exec|execdir|ok)$/.test(a)))
|
|
256
|
+
return { kind: 'unsafe' };
|
|
257
|
+
if (head === 'grep' && args.includes('-r') && args.length > 8)
|
|
258
|
+
return { kind: 'unsafe' }; // a scan, not a status probe
|
|
259
|
+
const blocking = head === 'tail' && args.some((a) => /^-[a-zA-Z]*[fF]/.test(a));
|
|
260
|
+
return { kind: 'probe', probe: probeId(head, args), status: STATUS_HEADS.has(head), ...(blocking && timeoutSec ? { waitSec: timeoutSec } : {}) };
|
|
261
|
+
}
|
|
262
|
+
return { kind: 'unsafe' };
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Recognize a poll-and-wait command. `isPoll` requires at least one wait AND at least one read-only probe
|
|
266
|
+
* and NO unsafe segment; `probe` is the identity of the first probe (set for bare probes too).
|
|
267
|
+
*/
|
|
268
|
+
export function detectPollPattern(command) {
|
|
269
|
+
const cmd = String(command ?? '').trim();
|
|
270
|
+
if (!cmd)
|
|
271
|
+
return { isPoll: false };
|
|
272
|
+
const loop = /\b(until|while)\b[\s\S]*\bdo\b[\s\S]*\bdone\b/.test(cmd);
|
|
273
|
+
const segs = splitSegments(cmd).map(classifySegment);
|
|
274
|
+
if (segs.some((s) => s.kind === 'unsafe'))
|
|
275
|
+
return { isPoll: false };
|
|
276
|
+
const probes = segs.filter((s) => s.kind === 'probe');
|
|
277
|
+
const probe = probes[0]?.probe;
|
|
278
|
+
const waits = segs.filter((s) => s.kind === 'wait' || s.waitSec !== undefined);
|
|
279
|
+
if (probes.length === 0)
|
|
280
|
+
return { isPoll: false };
|
|
281
|
+
if (waits.length === 0 && !loop)
|
|
282
|
+
return { isPoll: false, ...(probes[0].status ? { probe } : {}) }; // bare status probe: identity only
|
|
283
|
+
const known = waits.map((w) => w.waitSec).filter((n) => typeof n === 'number' && Number.isFinite(n));
|
|
284
|
+
const waitSec = known.length ? (loop ? Math.max(...known) : known.reduce((a, b) => a + b, 0)) : undefined;
|
|
285
|
+
return { isPoll: true, ...(waitSec !== undefined ? { waitSec } : {}), probe };
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=pollPattern.js.map
|