@askalf/dario 3.38.1 → 3.38.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/dist/cli.js CHANGED
@@ -261,6 +261,14 @@ async function proxy() {
261
261
  const thinkTimeMaxMs = parsePositiveIntFlag('--think-time-max=');
262
262
  const sessionStartMinMs = parsePositiveIntFlag('--session-start-min=');
263
263
  const sessionStartJitterMs = parsePositiveIntFlag('--session-start-jitter=');
264
+ // --stealth flips all three pacing layers (pace, think, session-start)
265
+ // into their behavioral-stealth presets so the request inter-arrival
266
+ // distribution matches real interactive CC. One knob instead of six.
267
+ // Per-knob explicit flags / env vars still win, so operators can
268
+ // toggle stealth on and then tune individual axes.
269
+ const stealth = args.includes('--stealth')
270
+ || parseBooleanEnv(process.env['DARIO_STEALTH'])
271
+ || undefined;
264
272
  // --drain-on-close (v3.25, direction #5). When set, a client
265
273
  // disconnect no longer aborts the upstream SSE — dario keeps
266
274
  // draining the stream to EOF so Anthropic sees the CC-shaped
@@ -399,7 +407,7 @@ async function proxy() {
399
407
  console.error(`[dario] Override (not recommended): pass --unsafe-no-auth if you have out-of-band network controls and accept the risk.`);
400
408
  process.exit(1);
401
409
  }
402
- await startProxy({ port, host, verbose, verboseBodies, model, passthrough, preserveTools, hybridTools, mergeTools, noAutoDetect, strictTls, pacingMinMs, pacingJitterMs, thinkTimeBaseMs, thinkTimePerTokenMs, thinkTimeJitterMs, thinkTimeMaxMs, sessionStartMinMs, sessionStartJitterMs, drainOnClose, sessionIdleRotateMs, sessionRotateJitterMs, sessionMaxAgeMs, sessionPerClient, preserveOrchestrationTags, noLiveCapture, strictTemplate, maxConcurrent, maxQueued, queueTimeoutMs, effort, maxTokens, logFile, passthroughBetas, systemPrompt });
410
+ await startProxy({ port, host, verbose, verboseBodies, model, passthrough, preserveTools, hybridTools, mergeTools, noAutoDetect, strictTls, pacingMinMs, pacingJitterMs, thinkTimeBaseMs, thinkTimePerTokenMs, thinkTimeJitterMs, thinkTimeMaxMs, sessionStartMinMs, sessionStartJitterMs, stealth, drainOnClose, sessionIdleRotateMs, sessionRotateJitterMs, sessionMaxAgeMs, sessionPerClient, preserveOrchestrationTags, noLiveCapture, strictTemplate, maxConcurrent, maxQueued, queueTimeoutMs, effort, maxTokens, logFile, passthroughBetas, systemPrompt });
403
411
  }
404
412
  /**
405
413
  * Parse `--system-prompt=<verbatim|partial|aggressive|filepath>` (or the
@@ -1014,6 +1022,17 @@ async function help() {
1014
1022
  from a stock CC request. Install Bun
1015
1023
  (https://bun.sh) so dario auto-relaunches
1016
1024
  under it, or use shim mode. (v3.23)
1025
+ --stealth Single-flag behavioral-stealth preset.
1026
+ Flips pace-jitter, think-time, and
1027
+ session-start defaults from 0 to non-zero
1028
+ values sized for real-CC inter-arrival
1029
+ statistics (pace-jitter=300, think
1030
+ base/perToken/jitter=800/4/1500 capped at
1031
+ 25s, session-start min/jitter=1200/3000).
1032
+ Per-knob --pace-jitter / --think-time-* /
1033
+ --session-start-* flags and env vars
1034
+ still win — flip stealth on, tune any
1035
+ axis afterwards. Env: DARIO_STEALTH.
1017
1036
  --pace-min=MS Minimum ms between upstream requests
1018
1037
  (default: 500). Prevents request floods
1019
1038
  that are distinguishable from human-paced
package/dist/pacing.d.ts CHANGED
@@ -51,7 +51,12 @@ export declare function computePacingDelay(now: number, lastRequestTime: number,
51
51
  * 2. DARIO_PACE_MIN_MS / DARIO_PACE_JITTER_MS env vars
52
52
  * 3. Legacy DARIO_MIN_INTERVAL_MS env var (minGap only — matches v3.23
53
53
  * behavior so existing setups don't regress silently)
54
- * 4. Defaults: minGap=500, jitter=0
54
+ * 4. Defaults: minGap=500, jitter=0 (or jitter=300 under stealth)
55
+ *
56
+ * `stealth` enables a behavioral-stealth preset: when true and the
57
+ * specific knob isn't overridden by explicit/env, fall through to a
58
+ * non-zero default that adds inter-request jitter. The minGap floor is
59
+ * already 500ms by default and isn't touched.
55
60
  *
56
61
  * Invalid strings (non-numeric, negative) are ignored and fall through to
57
62
  * the next source — a typoed env var shouldn't fail-loud at startup.
@@ -59,6 +64,7 @@ export declare function computePacingDelay(now: number, lastRequestTime: number,
59
64
  export declare function resolvePacingConfig(explicit?: {
60
65
  minGapMs?: number;
61
66
  jitterMs?: number;
67
+ stealth?: boolean;
62
68
  }, env?: NodeJS.ProcessEnv): PacingConfig;
63
69
  /**
64
70
  * Post-response "think time" simulation (behavioral smoothing extension).
@@ -104,6 +110,7 @@ export declare function resolveThinkTimeConfig(explicit?: {
104
110
  perTokenMs?: number;
105
111
  jitterMs?: number;
106
112
  maxMs?: number;
113
+ stealth?: boolean;
107
114
  }, env?: NodeJS.ProcessEnv): ThinkTimeConfig;
108
115
  /**
109
116
  * Session-start delay (behavioral smoothing extension).
@@ -132,4 +139,5 @@ export declare function computeSessionStartDelay(cfg: SessionStartConfig, rng?:
132
139
  export declare function resolveSessionStartConfig(explicit?: {
133
140
  minMs?: number;
134
141
  jitterMs?: number;
142
+ stealth?: boolean;
135
143
  }, env?: NodeJS.ProcessEnv): SessionStartConfig;
package/dist/pacing.js CHANGED
@@ -56,14 +56,20 @@ export function computePacingDelay(now, lastRequestTime, cfg, rng = Math.random)
56
56
  * 2. DARIO_PACE_MIN_MS / DARIO_PACE_JITTER_MS env vars
57
57
  * 3. Legacy DARIO_MIN_INTERVAL_MS env var (minGap only — matches v3.23
58
58
  * behavior so existing setups don't regress silently)
59
- * 4. Defaults: minGap=500, jitter=0
59
+ * 4. Defaults: minGap=500, jitter=0 (or jitter=300 under stealth)
60
+ *
61
+ * `stealth` enables a behavioral-stealth preset: when true and the
62
+ * specific knob isn't overridden by explicit/env, fall through to a
63
+ * non-zero default that adds inter-request jitter. The minGap floor is
64
+ * already 500ms by default and isn't touched.
60
65
  *
61
66
  * Invalid strings (non-numeric, negative) are ignored and fall through to
62
67
  * the next source — a typoed env var shouldn't fail-loud at startup.
63
68
  */
64
69
  export function resolvePacingConfig(explicit = {}, env = process.env) {
70
+ const stealth = explicit.stealth === true;
65
71
  const minGap = pickNonNegativeInt(explicit.minGapMs, env.DARIO_PACE_MIN_MS, env.DARIO_MIN_INTERVAL_MS) ?? 500;
66
- const jitter = pickNonNegativeInt(explicit.jitterMs, env.DARIO_PACE_JITTER_MS) ?? 0;
72
+ const jitter = pickNonNegativeInt(explicit.jitterMs, env.DARIO_PACE_JITTER_MS) ?? (stealth ? 300 : 0);
67
73
  return { minGapMs: minGap, jitterMs: jitter };
68
74
  }
69
75
  function pickNonNegativeInt(...candidates) {
@@ -105,10 +111,17 @@ export function computeThinkTimeDelay(now, lastResponseTime, lastResponseTokens,
105
111
  * since the short-circuit above returns 0 first.
106
112
  */
107
113
  export function resolveThinkTimeConfig(explicit = {}, env = process.env) {
108
- const base = pickNonNegativeInt(explicit.baseMs, env.DARIO_THINK_TIME_BASE_MS) ?? 0;
109
- const perToken = pickNonNegativeInt(explicit.perTokenMs, env.DARIO_THINK_TIME_PER_TOKEN_MS) ?? 0;
110
- const jitter = pickNonNegativeInt(explicit.jitterMs, env.DARIO_THINK_TIME_JITTER_MS) ?? 0;
111
- const max = pickNonNegativeInt(explicit.maxMs, env.DARIO_THINK_TIME_MAX_MS) ?? 30000;
114
+ // Behavioral-stealth preset: when `stealth` is on and the specific
115
+ // knob isn't overridden by explicit/env, fall through to non-zero
116
+ // defaults sized for typical interactive CC pacing — ~800ms minimum
117
+ // read time, ~4ms per output token (skimming speed), ±1500ms jitter,
118
+ // capped at 25s so a 5000-token response doesn't pause for half a
119
+ // minute. Defaults all stay 0 (off) when stealth isn't set.
120
+ const stealth = explicit.stealth === true;
121
+ const base = pickNonNegativeInt(explicit.baseMs, env.DARIO_THINK_TIME_BASE_MS) ?? (stealth ? 800 : 0);
122
+ const perToken = pickNonNegativeInt(explicit.perTokenMs, env.DARIO_THINK_TIME_PER_TOKEN_MS) ?? (stealth ? 4 : 0);
123
+ const jitter = pickNonNegativeInt(explicit.jitterMs, env.DARIO_THINK_TIME_JITTER_MS) ?? (stealth ? 1500 : 0);
124
+ const max = pickNonNegativeInt(explicit.maxMs, env.DARIO_THINK_TIME_MAX_MS) ?? (stealth ? 25000 : 30000);
112
125
  return { baseMs: base, perTokenMs: perToken, jitterMs: jitter, maxMs: max };
113
126
  }
114
127
  export function computeSessionStartDelay(cfg, rng = Math.random) {
@@ -120,7 +133,10 @@ export function computeSessionStartDelay(cfg, rng = Math.random) {
120
133
  return min + jitterAdd;
121
134
  }
122
135
  export function resolveSessionStartConfig(explicit = {}, env = process.env) {
123
- const min = pickNonNegativeInt(explicit.minMs, env.DARIO_SESSION_START_MIN_MS) ?? 0;
124
- const jitter = pickNonNegativeInt(explicit.jitterMs, env.DARIO_SESSION_START_JITTER_MS) ?? 0;
136
+ // Stealth preset: 1200ms floor + up to 3000ms uniform jitter ≈ 1.2s–4.2s
137
+ // first-request latency, matching observed real-CC session-open ranges.
138
+ const stealth = explicit.stealth === true;
139
+ const min = pickNonNegativeInt(explicit.minMs, env.DARIO_SESSION_START_MIN_MS) ?? (stealth ? 1200 : 0);
140
+ const jitter = pickNonNegativeInt(explicit.jitterMs, env.DARIO_SESSION_START_JITTER_MS) ?? (stealth ? 3000 : 0);
125
141
  return { minMs: min, jitterMs: jitter };
126
142
  }
package/dist/proxy.d.ts CHANGED
@@ -68,6 +68,7 @@ interface ProxyOptions {
68
68
  thinkTimeMaxMs?: number;
69
69
  sessionStartMinMs?: number;
70
70
  sessionStartJitterMs?: number;
71
+ stealth?: boolean;
71
72
  drainOnClose?: boolean;
72
73
  sessionIdleRotateMs?: number;
73
74
  sessionRotateJitterMs?: number;
package/dist/proxy.js CHANGED
@@ -726,23 +726,33 @@ export async function startProxy(opts = {}) {
726
726
  // feeds the inter-request floor).
727
727
  let lastResponseTime = 0;
728
728
  let lastResponseTokens = 0;
729
+ // --stealth toggles the behavioral-stealth preset across all three
730
+ // pacing layers (pace, think-time, session-start). When on, each
731
+ // resolver's zero-default flips to its stealth preset; explicit flags
732
+ // and env vars still win.
733
+ const stealth = Boolean(opts.stealth);
729
734
  const pacingCfg = resolvePacingConfig({
730
735
  minGapMs: opts.pacingMinMs,
731
736
  jitterMs: opts.pacingJitterMs,
737
+ stealth,
732
738
  });
733
739
  const thinkTimeCfg = resolveThinkTimeConfig({
734
740
  baseMs: opts.thinkTimeBaseMs,
735
741
  perTokenMs: opts.thinkTimePerTokenMs,
736
742
  jitterMs: opts.thinkTimeJitterMs,
737
743
  maxMs: opts.thinkTimeMaxMs,
744
+ stealth,
738
745
  });
739
746
  const sessionStartCfg = resolveSessionStartConfig({
740
747
  minMs: opts.sessionStartMinMs,
741
748
  jitterMs: opts.sessionStartJitterMs,
749
+ stealth,
742
750
  });
743
751
  const thinkTimeEnabled = thinkTimeCfg.baseMs > 0 || thinkTimeCfg.perTokenMs > 0 || thinkTimeCfg.jitterMs > 0;
744
752
  const sessionStartEnabled = sessionStartCfg.minMs > 0 || sessionStartCfg.jitterMs > 0;
745
753
  if (verbose) {
754
+ if (stealth)
755
+ console.log('[dario] stealth: behavioral-stealth preset active (pace+think+session-start defaults non-zero)');
746
756
  console.log(`[dario] pacing: min=${pacingCfg.minGapMs}ms jitter=${pacingCfg.jitterMs}ms`);
747
757
  if (thinkTimeEnabled) {
748
758
  console.log(`[dario] think-time: base=${thinkTimeCfg.baseMs}ms perToken=${thinkTimeCfg.perTokenMs}ms jitter=${thinkTimeCfg.jitterMs}ms max=${thinkTimeCfg.maxMs}ms`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "3.38.1",
3
+ "version": "3.38.2",
4
4
  "description": "A local LLM router. One endpoint, every provider — Claude subscriptions, OpenAI, OpenRouter, Groq, local LiteLLM, any OpenAI-compat endpoint — your tools don't need to change.",
5
5
  "type": "module",
6
6
  "bin": {