circle-ir-ai 2.31.0 → 2.32.0

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 CHANGED
@@ -5,6 +5,120 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.32.0] - 2026-07-02
9
+
10
+ ### Added — LLM call throttle + hard cap (cognium-ai#159 + #160, Sprint L4a)
11
+
12
+ Ships the LLM call-throttle escape hatch and the per-scan / per-file
13
+ hard cap. Both are opt-in through env vars — with everything unset the
14
+ runtime behavior is identical to `2.31.1`, so this is additive by
15
+ default. Coordinated with `cognium-ai@2.27.0` (doc-only companion).
16
+
17
+ **cognium-ai#159 — `LLM_CONCURRENCY` alias.**
18
+ `src/llm/ax-client.ts` already ran every LLM call through a shared
19
+ `p-queue` with concurrency read from `LLM_MAX_CONCURRENT` (default
20
+ `10`). The ticket's premise — "LLM calls appear fully serial" —
21
+ turned out to be a naming/discoverability problem rather than a
22
+ missing throttle. The fix is a rename with backward-compat:
23
+
24
+ - **New env var:** `LLM_CONCURRENCY` (positive integer). Preferred
25
+ name going forward.
26
+ - **Legacy env var:** `LLM_MAX_CONCURRENT` continues to work; still
27
+ read when `LLM_CONCURRENCY` is unset. No deprecation warning.
28
+ - **Precedence:** `LLM_CONCURRENCY` > `LLM_MAX_CONCURRENT` > default
29
+ `10`. Both unset preserves the pre-2.32 behavior exactly.
30
+ - **Recommended values:** `4–8` for Ollama, `16+` for cloud
31
+ providers. The default `10` is intentionally conservative.
32
+
33
+ **cognium-ai#160 — `LLM_MAX_CALLS_PER_SCAN` + `LLM_MAX_CALLS_PER_FILE`.**
34
+ New module `src/llm/call-limiter.ts` provides a global counter that
35
+ gates every call at the transport boundary in `chatJSON`. When either
36
+ cap is reached, subsequent calls short-circuit to `null` and the
37
+ caller sees the same "LLM disabled" semantics that already exist for
38
+ provider outages and prefilter rejections (`{ llmSources: [],
39
+ llmSinks: [] }` / `{ verified: [], ... }`). No per-caller changes
40
+ were required.
41
+
42
+ New env vars, all default unset (unbounded, matches `2.31.1`
43
+ behavior):
44
+ - `LLM_MAX_CALLS_PER_SCAN` — total LLM calls per scan.
45
+ - `LLM_MAX_CALLS_PER_FILE` — per-file budget. Independent per file;
46
+ a fresh budget is allocated the first time each file appears in
47
+ the `filePath` context.
48
+
49
+ Behavior on cap-hit:
50
+ 1. Counter is incremented on **acquire**, not on completion, so
51
+ concurrent p-queue firing cannot overshoot the cap.
52
+ 2. Scan cap emits a single `console.warn` (`[call-limit]
53
+ LLM_MAX_CALLS_PER_SCAN=<n> reached; remaining LLM calls skipped,
54
+ files fall back to static-only`). Subsequent skips are silent.
55
+ Per-file cap is silent by design (would spam on large repos).
56
+ 3. Retries inside an already-admitted call bypass the gate
57
+ (`retryCount > 0`), so a retried request does not re-acquire
58
+ budget.
59
+ 4. A synthetic "no-call" JSONL row is written for every skipped call
60
+ with `skippedByCap: true` and `skippedCapReason: 'scan' | 'file'`,
61
+ following the existing `skippedByPrefilter` / `verifyCacheHit`
62
+ pattern. `analyze-llm-log.ts` in cognium-ai already surfaces
63
+ these rows.
64
+
65
+ **Per-scan isolation.** `analyzeFilesSwarm`,
66
+ `analyzeFilesSwarmStream`, and `analyzeFilesInBatches` in
67
+ `src/agents/mastra/swarm.ts` bracket their work with
68
+ `resetLLMCallLimiter(true)` + `markSwarmStart()` on entry, and
69
+ `markSwarmEnd()` in a `finally` block. `analyzeFile` in
70
+ `src/agents/mastra/workflow.ts` calls the unforced
71
+ `resetLLMCallLimiter()`, which is a no-op while a swarm is
72
+ orchestrating — this keeps the per-scan budget intact across
73
+ swarm-nested single-file callers while still resetting for
74
+ standalone single-file invocations.
75
+
76
+ **New exports (also re-exported from `./llm/index.js`):**
77
+ - `checkAndCountCall(ctx?)` — the gate itself. Returns `true` when
78
+ admitted, `false` when either cap fires.
79
+ - `resetLLMCallLimiter(force?)` — swarm-guarded by default; `force`
80
+ bypasses the guard (test hook + swarm-entry use).
81
+ - `markSwarmStart()` / `markSwarmEnd()` — bracket a swarm run to
82
+ suppress nested per-file resets.
83
+ - `getLLMCallStats()` — snapshot for tail summaries: `scanCounter`,
84
+ `scanSkipped`, `perFileSkipped`, `scanCapWarned`,
85
+ `resolvedConcurrency`, `resolvedScanCap`, `resolvedFileCap`.
86
+ - Consts: `LLM_CONCURRENCY`, `LLM_MAX_CALLS_PER_SCAN`,
87
+ `LLM_MAX_CALLS_PER_FILE`.
88
+
89
+ **Rollback:** unset all three env vars → pre-2.32 behavior. The
90
+ fast path in `checkAndCountCall` bails before any allocation when
91
+ both caps are `null`, so there is zero overhead on the default path.
92
+
93
+ **Tests.** New `tests/llm/call-limiter.test.ts` — 8 tests covering
94
+ default unbounded path, scan cap admit/skip counts, WARN
95
+ emit-exactly-once, per-file independent budgets, reset semantics,
96
+ swarm-guard interaction, env-var precedence (new name > legacy >
97
+ default), and scan-cap-precedes-per-file-cap ordering. Full engine
98
+ suite: 1204 pass + 3 skipped (was 1196 pass + 3 skipped on 2.31.1;
99
+ +8 from this ticket).
100
+
101
+ ## [2.31.1] - 2026-07-02
102
+
103
+ ### Changed — circle-ir bump 3.139.0 → 3.144.0 (patch, dep-only)
104
+
105
+ Refresh the pinned `circle-ir` dependency to the current published
106
+ version. Rolls up the 3.140/3.141/3.144 releases (3.142 and 3.143
107
+ were unpublished). No engine or public-API changes in this package.
108
+
109
+ **Test update.** `tests/findings-llm-discovery.test.ts` — the
110
+ "drops type-incompatible LLM pairs via canSourceReachSink gate" case
111
+ previously used `http_param → deserialization` as its incompatible
112
+ example. Upstream circle-ir Sprint 93 / cognium-dev#189 legitimately
113
+ widened `http_param` to include `deserialization` for
114
+ SnakeYAML/Jackson-shape gadget chains (Log4Shell shape). The test now
115
+ uses `env_input → xss` — server-side env vars still cannot reach
116
+ browser DOM contexts, so this pair remains outside the coverage matrix
117
+ and the assertion still exercises the intended gate. This is a
118
+ test-fixture correction, not a behavior change.
119
+
120
+ Suite: 1196 pass + 3 skipped (was 1196 pass + 3 skipped on 3.139.0).
121
+
8
122
  ## [2.31.0] - 2026-07-01
9
123
 
10
124
  ### Added — large-repo architectural knobs (cognium-ai#165 + #166 L3)
@@ -5,8 +5,8 @@
5
5
  * createStep() API with Zod schemas for type safety.
6
6
  */
7
7
  export declare const patternMatchStep: import("@mastra/core/workflows").Step<"pattern-match", unknown, {
8
- sourceCode: string;
9
8
  filePath: string;
9
+ sourceCode: string;
10
10
  language?: string | undefined;
11
11
  }, {
12
12
  imports: string[];
@@ -40,9 +40,9 @@ export declare const patternMatchStep: import("@mastra/core/workflows").Step<"pa
40
40
  }[];
41
41
  }, unknown, unknown, import("@mastra/core/workflows").DefaultEngineType, unknown>;
42
42
  export declare const enrichStep: import("@mastra/core/workflows").Step<"enrich", unknown, {
43
+ filePath: string;
43
44
  imports: string[];
44
45
  sourceCode: string;
45
- filePath: string;
46
46
  patternSources: {
47
47
  type: string;
48
48
  line: number;
@@ -160,8 +160,8 @@ export declare const mergeStep: import("@mastra/core/workflows").Step<"merge", u
160
160
  }[];
161
161
  }, unknown, unknown, import("@mastra/core/workflows").DefaultEngineType, unknown>;
162
162
  export declare const verifyStep: import("@mastra/core/workflows").Step<"verify", unknown, {
163
- sourceCode: string;
164
163
  filePath: string;
164
+ sourceCode: string;
165
165
  types: {
166
166
  kind: "class" | "interface" | "enum";
167
167
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"swarm.d.ts","sourceRoot":"","sources":["../../../src/agents/mastra/swarm.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"swarm.d.ts","sourceRoot":"","sources":["../../../src/agents/mastra/swarm.ts"],"names":[],"mappings":"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"}