opencode-swarm 7.154.2 → 7.155.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/dist/cli/{coder-settlement-xqs49g07.js → coder-settlement-2kdtysrg.js} +7 -7
- package/dist/cli/{config-doctor-69eebk90.js → config-doctor-s6p9aqfv.js} +2 -2
- package/dist/cli/{core-dyp14hcb.js → core-ev2ebc4v.js} +1 -1
- package/dist/cli/{curation-policy-jm9jsxtt.js → curation-policy-jabphe51.js} +4 -4
- package/dist/cli/{curator-he8n9z9n.js → curator-adp0dsv4.js} +28 -28
- package/dist/cli/{curator-drift-h57z6tm3.js → curator-drift-g6w4ga1q.js} +1 -1
- package/dist/cli/{curator-llm-factory-5tq9c4v5.js → curator-llm-factory-kd8v16jj.js} +28 -28
- package/dist/cli/{evidence-summary-service-05s5y8d6.js → evidence-summary-service-kpjpd86j.js} +10 -10
- package/dist/cli/{gate-evidence-3ptr9af3.js → gate-evidence-etbcms2v.js} +5 -5
- package/dist/cli/{guardrail-explain-tebk344k.js → guardrail-explain-wqb5h7kk.js} +29 -29
- package/dist/cli/{guardrail-log-x3gz3x17.js → guardrail-log-614g1pta.js} +3 -3
- package/dist/cli/{guardrail-reset-716pdyf5.js → guardrail-reset-0wdj53cp.js} +28 -28
- package/dist/cli/{hive-promoter-nvwpj2t9.js → hive-promoter-b1wv52fs.js} +28 -28
- package/dist/cli/{index-4xqa0sgz.js → index-0q8kywcf.js} +2 -2
- package/dist/cli/{index-8v69hfpt.js → index-26cvxrym.js} +3 -3
- package/dist/cli/{index-bxvkn0ye.js → index-2gfe61qp.js} +345 -221
- package/dist/cli/{index-57t97rtr.js → index-34wn2ztk.js} +5 -2
- package/dist/cli/{index-kemxyzc0.js → index-6bqqzfbe.js} +2 -2
- package/dist/cli/{index-dm9tc6qb.js → index-79qymsxf.js} +1 -1
- package/dist/cli/{index-r0dactw2.js → index-85p1850w.js} +1 -1
- package/dist/cli/{index-14bz2t7b.js → index-aqg7c1z9.js} +1 -1
- package/dist/cli/{index-xq2v52tt.js → index-c590qxts.js} +1 -1
- package/dist/cli/{index-fv9ddfta.js → index-c9nabqzd.js} +1 -1
- package/dist/cli/{index-nh4axsxc.js → index-caqe8x14.js} +2 -2
- package/dist/cli/{index-n0gqre56.js → index-ctsct3hy.js} +6 -6
- package/dist/cli/{index-4cgee5vh.js → index-dtn0pne5.js} +20 -1
- package/dist/cli/{index-ynvw5kxc.js → index-dw2q720x.js} +2 -2
- package/dist/cli/{index-xt6jx41g.js → index-e90g4dsw.js} +4 -4
- package/dist/cli/{index-9avdncr2.js → index-egnpzfe3.js} +5 -5
- package/dist/cli/{index-j6q3k628.js → index-ew6fykvv.js} +1 -1
- package/dist/cli/{index-6rns7b2m.js → index-fjcm6wwf.js} +2 -2
- package/dist/cli/{index-mnxtkt8s.js → index-ketfp4rv.js} +3 -3
- package/dist/cli/{index-f6qmar4k.js → index-kgdbtwfm.js} +5 -5
- package/dist/cli/{index-399e8aze.js → index-kyc2c7hq.js} +1 -1
- package/dist/cli/{index-07n87ctw.js → index-mm7ase9k.js} +1 -1
- package/dist/cli/{index-p7ey2w90.js → index-qj9jrjvr.js} +6 -6
- package/dist/cli/{index-v2ryvr8k.js → index-qzqpq75z.js} +30 -30
- package/dist/cli/{index-v9585wjc.js → index-rb4t72we.js} +2 -2
- package/dist/cli/{index-2w6vy9a9.js → index-spbxf9vn.js} +1 -1
- package/dist/cli/{index-6qwp46k0.js → index-t3xqpece.js} +3 -3
- package/dist/cli/{index-pj2nycpg.js → index-veajr5x7.js} +1 -1
- package/dist/cli/{index-vhhdj49x.js → index-wwv3cbv1.js} +8 -9
- package/dist/cli/{index-7tw116n6.js → index-x9tbe9v7.js} +2 -2
- package/dist/cli/{index-6rcx6vr6.js → index-xn23xnnk.js} +4 -4
- package/dist/cli/{index-dsqat5pg.js → index-zvp68qx6.js} +1 -1
- package/dist/cli/index.js +28 -28
- package/dist/cli/{knowledge-escalator-s0tye368.js → knowledge-escalator-z09aqvfe.js} +10 -10
- package/dist/cli/{knowledge-events-eyy9yf6b.js → knowledge-events-03f1rwm8.js} +8 -8
- package/dist/cli/{knowledge-link-rb11f06y.js → knowledge-link-4frk38w8.js} +3 -3
- package/dist/cli/{knowledge-store-zjq5mz2d.js → knowledge-store-sn28k13f.js} +4 -4
- package/dist/cli/{knowledge-validator-yw5qqqpd.js → knowledge-validator-rwrt3yja.js} +6 -6
- package/dist/cli/{pending-delegations-rdzjq3nw.js → pending-delegations-qe16vfrj.js} +2 -2
- package/dist/cli/{pr-subscriptions-2f5fne6z.js → pr-subscriptions-00evnffe.js} +3 -3
- package/dist/cli/{runner-yaqrj388.js → runner-k1rkbjm8.js} +4 -4
- package/dist/cli/{scan-cursor-8f0s883y.js → scan-cursor-h3mfzjc9.js} +5 -5
- package/dist/cli/{schema-2xw94dh3.js → schema-c37h5xw4.js} +1 -1
- package/dist/cli/{scope-persistence-tap2q94x.js → scope-persistence-35z42pj5.js} +5 -5
- package/dist/cli/{skill-generator-2xbfryqb.js → skill-generator-60px2mvb.js} +12 -12
- package/dist/cli/{worktree-collision-ownership-5gwey8ms.js → worktree-collision-ownership-2pc20ypq.js} +4 -4
- package/dist/cli/{worktree-isolation-xsy14t5a.js → worktree-isolation-w4yamc3b.js} +28 -28
- package/dist/commands/close.d.ts +2 -0
- package/dist/config/schema.d.ts +8 -0
- package/dist/hooks/final-context-accounting.d.ts +60 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/knowledge-injector.d.ts +1 -1
- package/dist/hooks/repo-graph-injection.d.ts +40 -0
- package/dist/hooks/system-enhancer.d.ts +13 -0
- package/dist/hooks/utils.d.ts +11 -0
- package/dist/index.js +414 -389
- package/dist/memory/reflection-service.d.ts +8 -2
- package/dist/memory/schema.d.ts +4 -4
- package/dist/services/compaction-service.d.ts +9 -3
- package/dist/services/context-budget-service.d.ts +7 -3
- package/dist/services/injection-budget.d.ts +103 -26
- package/dist/state.d.ts +69 -0
- package/dist/summaries/summarizer.d.ts +34 -3
- package/dist/tools/repo-graph/indexed-storage.d.ts +136 -0
- package/dist/tools/repo-graph/query.d.ts +7 -0
- package/package.json +3 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { queryNodeByFile, resolveGraphStorageMode } from '../tools/repo-graph/indexed-storage';
|
|
2
|
+
import type { RepoGraph } from '../tools/repo-graph/types';
|
|
1
3
|
import { type MemoryConfig } from './config';
|
|
2
4
|
import { type MemoryGateway, type RecordMemoryOutcomeInput } from './gateway';
|
|
3
|
-
import { type ReflectionDigest } from './reflection';
|
|
4
|
-
import type { MemoryOutcome, MemoryRecord } from './types';
|
|
5
|
+
import { type ReflectionAnchorStatus, type ReflectionDigest } from './reflection';
|
|
6
|
+
import type { MemoryAnchor, MemoryOutcome, MemoryRecord } from './types';
|
|
5
7
|
interface OutcomeWriteThroughBase {
|
|
6
8
|
record: MemoryRecord;
|
|
7
9
|
eventId: string;
|
|
@@ -49,12 +51,16 @@ export declare const _test_exports: {
|
|
|
49
51
|
isReflectionEligible: typeof isReflectionEligible;
|
|
50
52
|
prepareWriteThroughEntry: typeof prepareWriteThroughEntry;
|
|
51
53
|
sanitizeReflectionRecord: typeof sanitizeReflectionRecord;
|
|
54
|
+
createAnchorResolver: typeof createAnchorResolver;
|
|
52
55
|
};
|
|
53
56
|
export declare const _internals: {
|
|
54
57
|
withReflectionLock: typeof withReflectionLock;
|
|
55
58
|
serializeDigestArtifacts: typeof serializeDigestArtifacts;
|
|
56
59
|
boundDigest: typeof boundDigest;
|
|
60
|
+
resolveGraphStorageMode: typeof resolveGraphStorageMode;
|
|
61
|
+
queryNodeByFile: typeof queryNodeByFile;
|
|
57
62
|
};
|
|
63
|
+
declare function createAnchorResolver(directory: string, graph: RepoGraph | null): (anchor: MemoryAnchor) => ReflectionAnchorStatus;
|
|
58
64
|
declare function withReflectionLock<T>(directory: string, fn: () => Promise<T>): Promise<T>;
|
|
59
65
|
interface ReflectionArtifactPair {
|
|
60
66
|
markdown: string;
|
package/dist/memory/schema.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ export declare const MemoryScopeTypeSchema: z.ZodEnum<{
|
|
|
10
10
|
project: "project";
|
|
11
11
|
workspace: "workspace";
|
|
12
12
|
run: "run";
|
|
13
|
-
global_user: "global_user";
|
|
14
13
|
repository: "repository";
|
|
14
|
+
global_user: "global_user";
|
|
15
15
|
cohort: "cohort";
|
|
16
16
|
}>;
|
|
17
17
|
export declare const MemoryScopeRefSchema: z.ZodObject<{
|
|
@@ -20,8 +20,8 @@ export declare const MemoryScopeRefSchema: z.ZodObject<{
|
|
|
20
20
|
project: "project";
|
|
21
21
|
workspace: "workspace";
|
|
22
22
|
run: "run";
|
|
23
|
-
global_user: "global_user";
|
|
24
23
|
repository: "repository";
|
|
24
|
+
global_user: "global_user";
|
|
25
25
|
cohort: "cohort";
|
|
26
26
|
}>;
|
|
27
27
|
userId: z.ZodOptional<z.ZodString>;
|
|
@@ -77,8 +77,8 @@ export declare const MemoryRecordSchema: z.ZodObject<{
|
|
|
77
77
|
project: "project";
|
|
78
78
|
workspace: "workspace";
|
|
79
79
|
run: "run";
|
|
80
|
-
global_user: "global_user";
|
|
81
80
|
repository: "repository";
|
|
81
|
+
global_user: "global_user";
|
|
82
82
|
cohort: "cohort";
|
|
83
83
|
}>;
|
|
84
84
|
userId: z.ZodOptional<z.ZodString>;
|
|
@@ -171,8 +171,8 @@ export declare const MemoryProposalSchema: z.ZodObject<{
|
|
|
171
171
|
project: "project";
|
|
172
172
|
workspace: "workspace";
|
|
173
173
|
run: "run";
|
|
174
|
-
global_user: "global_user";
|
|
175
174
|
repository: "repository";
|
|
175
|
+
global_user: "global_user";
|
|
176
176
|
cohort: "cohort";
|
|
177
177
|
}>;
|
|
178
178
|
userId: z.ZodOptional<z.ZodString>;
|
|
@@ -7,9 +7,15 @@
|
|
|
7
7
|
* - Reflection (default 60%): re-summarise into tighter format
|
|
8
8
|
* - Emergency (default 80%): hard truncation to system + current task + last N turns
|
|
9
9
|
*
|
|
10
|
-
* Consumes the per-session
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* Consumes the per-session FINAL PROMPT PRESSURE recorded by the final
|
|
11
|
+
* context-accounting step (#2107 §3) after every injector has run
|
|
12
|
+
* (`getFinalPromptPressure`); before that step has run for a session it falls
|
|
13
|
+
* back to the legacy injection-footprint pct (`getSessionBudgetPct`) so the
|
|
14
|
+
* tiers never go dark.
|
|
15
|
+
* Never throws. Advisory system message injection via callback. These tiers
|
|
16
|
+
* ADVISE the model to compact — they never compact anything themselves and
|
|
17
|
+
* never claim a compaction was performed (only the physical pruning in
|
|
18
|
+
* src/hooks/context-budget.ts actually removes content).
|
|
13
19
|
*/
|
|
14
20
|
import type { CompactionConfig } from '../config/schema';
|
|
15
21
|
export type { CompactionConfig };
|
|
@@ -74,10 +74,14 @@ export interface BudgetState {
|
|
|
74
74
|
*/
|
|
75
75
|
export declare const DEFAULT_CONTEXT_BUDGET_CONFIG: ContextBudgetConfig;
|
|
76
76
|
/**
|
|
77
|
-
* Estimate token count for text using character-based
|
|
77
|
+
* Estimate token count for text using the canonical character-based heuristic.
|
|
78
78
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
79
|
+
* Delegates to `estimateTokens` in src/hooks/utils.ts (issue #1616/#2107). This
|
|
80
|
+
* used to be an independent ÷3.5 formula, which made the user-facing budget
|
|
81
|
+
* report disagree ~15% with the injection-admission path (0.33 tok/char) on
|
|
82
|
+
* the same text. The export is kept for existing importers (capsule-builder,
|
|
83
|
+
* the services barrel); it is a heuristic — provider-reported token usage is
|
|
84
|
+
* authoritative when available.
|
|
81
85
|
*/
|
|
82
86
|
export declare function estimateTokens(text: string): number;
|
|
83
87
|
/**
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unified Injection Budget Service (FR-002).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* system-enhancer + knowledge-injector injection
|
|
4
|
+
* Two responsibilities: (1) the pure, side-effect-free FR-002 allocation
|
|
5
|
+
* function for the combined system-enhancer + knowledge-injector injection
|
|
6
|
+
* ceiling, and (2) the per-session/per-turn producer ledger (#2107 §2) that
|
|
7
|
+
* every model-visible producer claims from or records emissions into.
|
|
6
8
|
*
|
|
7
9
|
* Allocation strategy: proportional share.
|
|
8
10
|
* - When combined demand fits within the budget, each component receives its
|
|
@@ -20,8 +22,8 @@
|
|
|
20
22
|
* Priority-based allocation would require an arbitrary component ranking
|
|
21
23
|
* not specified by the acceptance criteria.
|
|
22
24
|
*
|
|
23
|
-
* Char-to-token conversion
|
|
24
|
-
* (
|
|
25
|
+
* Char-to-token conversion goes through the canonical estimator
|
|
26
|
+
* (`estimateTokensFromCharCount` in src/hooks/utils.ts — issue #1616/#2107).
|
|
25
27
|
*/
|
|
26
28
|
/**
|
|
27
29
|
* Allocation result for a single turn's unified injection budget.
|
|
@@ -59,40 +61,115 @@ export interface InjectionBudgetConfig {
|
|
|
59
61
|
*/
|
|
60
62
|
export declare function allocateInjectionBudget(systemEnhancerDemandTokens: number, knowledgeInjectorDemandChars: number, config: InjectionBudgetConfig): InjectionBudgetAllocation;
|
|
61
63
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
+
* Producers that contribute to the model-visible request surface. The
|
|
65
|
+
* `surface` on each accounting entry records WHERE the producer's bytes live:
|
|
66
|
+
* `'system'` entries are pushed to `output.system` in the system.transform
|
|
67
|
+
* chain (invisible to the messages chain and to final accounting's direct
|
|
68
|
+
* measurement of `output.messages` — they MUST be added to the final total via
|
|
69
|
+
* this ledger); `'messages'` entries are spliced into `output.messages` and are
|
|
70
|
+
* therefore already inside the final measurement (attribution only — adding
|
|
71
|
+
* them again would double-count).
|
|
64
72
|
*/
|
|
65
|
-
export
|
|
73
|
+
export type InjectionProducer = 'system-enhancer' | 'knowledge-injector' | 'context-capsule' | 'memory-recall' | 'advisory-queue' | 'swarm-command-banner' | 'linked-cohort-advisory' | 'spec-drift-advisory' | 'final-accounting-warning';
|
|
74
|
+
export type InjectionSurface = 'system' | 'messages';
|
|
75
|
+
export interface ProducerAccounting {
|
|
76
|
+
/** Tokens the producer asked the ledger for this turn (claims only). */
|
|
77
|
+
requested: number;
|
|
78
|
+
/** Tokens the ledger granted under the ceiling + local max (claims only). */
|
|
79
|
+
granted: number;
|
|
80
|
+
/** Tokens actually emitted to the model-visible surface. */
|
|
81
|
+
emitted: number;
|
|
82
|
+
/** Tokens the producer wanted but did not emit (its own pruning). */
|
|
83
|
+
truncated: number;
|
|
84
|
+
surface: InjectionSurface;
|
|
85
|
+
}
|
|
86
|
+
export interface TurnLedgerSummary {
|
|
87
|
+
generation: number;
|
|
88
|
+
totalBudget: number;
|
|
89
|
+
/** Ceiling enforcement is only active when `unified_injection_tokens` is configured. */
|
|
90
|
+
ceilingActive: boolean;
|
|
91
|
+
used: number;
|
|
92
|
+
producers: Array<{
|
|
93
|
+
producer: InjectionProducer;
|
|
94
|
+
} & ProducerAccounting>;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Begin a new turn ledger for a session: reset exactly once at the start of
|
|
98
|
+
* composing that request (the system-enhancer is the first producer and calls
|
|
99
|
+
* this). Mints a fresh generation, so any stale claim from a prior composition
|
|
100
|
+
* is discarded. `ceilingActive` is only true when
|
|
101
|
+
* `context_budget.unified_injection_tokens` is configured; when false the
|
|
102
|
+
* ledger records accounting but never denies a claim (default configs keep
|
|
103
|
+
* their pre-#2107 behavior).
|
|
104
|
+
*/
|
|
105
|
+
export declare function beginTurnLedger(sessionID: string, totalBudget: number, ceilingActive: boolean): number;
|
|
106
|
+
/**
|
|
107
|
+
* Claim tokens from the turn ledger. The grant is bounded by the producer's
|
|
108
|
+
* own local maximum (`localMaxTokens`) and, only when the ceiling is active,
|
|
109
|
+
* by what remains of the unified ceiling. When NO ledger exists for the session
|
|
110
|
+
* (system-enhancer never ran this turn — native agent, first turn, or hook
|
|
111
|
+
* disabled), the claim fails open to the local maximum and is not recorded,
|
|
112
|
+
* preserving #1617's fail-open contract; the caller is expected to report that
|
|
113
|
+
* the hard ceiling was unavailable.
|
|
114
|
+
*/
|
|
115
|
+
export declare function claimTurnBudget(sessionID: string, producer: InjectionProducer, requestedTokens: number, opts?: {
|
|
116
|
+
localMaxTokens?: number;
|
|
117
|
+
surface?: InjectionSurface;
|
|
118
|
+
}): {
|
|
119
|
+
granted: number;
|
|
120
|
+
ledgerPresent: boolean;
|
|
121
|
+
ceilingActive: boolean;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Record a producer's grant without claiming through `claimTurnBudget`.
|
|
125
|
+
*
|
|
126
|
+
* The system-enhancer and knowledge-injector enforce their split through the
|
|
127
|
+
* pure `allocateInjectionBudget` (FR-002 contract, pinned by tests) rather than
|
|
128
|
+
* sequential claims; this books their allocator-derived grants into the shared
|
|
129
|
+
* ceiling so later claimants (capsule, memory recall) draw from what actually
|
|
130
|
+
* remains. When the ceiling is inactive the grant is recorded but deducts
|
|
131
|
+
* nothing. The deduction is clamped to the remaining budget so `used` can never
|
|
132
|
+
* exceed `totalBudget`.
|
|
133
|
+
*/
|
|
134
|
+
export declare function recordProducerGrant(sessionID: string, producer: InjectionProducer, requestedTokens: number, grantedTokens: number, surface: InjectionSurface): void;
|
|
66
135
|
/**
|
|
67
|
-
*
|
|
136
|
+
* Record what a producer actually emitted (and pruned itself) this turn.
|
|
137
|
+
* Producers that never claim (fixed/base content: advisory queue, banners,
|
|
138
|
+
* the context-budget warning, the final-accounting warning) still record their
|
|
139
|
+
* emission here so the final accounting can include them.
|
|
68
140
|
*/
|
|
69
|
-
export declare function
|
|
141
|
+
export declare function recordProducerEmission(sessionID: string, producer: InjectionProducer, emittedTokens: number, truncatedTokens: number, surface: InjectionSurface): void;
|
|
70
142
|
/**
|
|
71
|
-
*
|
|
72
|
-
* If the requester's need exceeds the remaining budget, it gets the remainder
|
|
73
|
-
* and the other source is implicitly blocked (remaining drops to 0).
|
|
143
|
+
* Snapshot of the session's current turn ledger (null when absent).
|
|
74
144
|
*/
|
|
75
|
-
export declare function requestUnifiedBudget(sessionID: string, requestedTokens: number): number;
|
|
76
145
|
/**
|
|
77
|
-
*
|
|
146
|
+
* Deduct tokens from a producer's recorded emission (#2107 §3): downstream
|
|
147
|
+
* system-chain mutators (the role filter) REMOVE strings after the producer
|
|
148
|
+
* recorded them, and the final accounting must not count bytes the model
|
|
149
|
+
* never sees. Floors at zero; no-op without a ledger or producer entry.
|
|
78
150
|
*/
|
|
79
|
-
export declare function
|
|
151
|
+
export declare function deductProducerEmission(sessionID: string, producer: InjectionProducer, removedTokens: number): void;
|
|
152
|
+
export declare function getTurnLedgerSummary(sessionID: string): TurnLedgerSummary | null;
|
|
80
153
|
/**
|
|
81
|
-
*
|
|
154
|
+
* Emitted tokens recorded for one producer this turn (0 when no ledger or the
|
|
155
|
+
* producer has not run). Replaces the old `getSystemEnhancerDemand` relay: the
|
|
156
|
+
* knowledge-injector reads the system-enhancer's actual emission from here.
|
|
82
157
|
*/
|
|
83
|
-
export declare function
|
|
158
|
+
export declare function getProducerEmission(sessionID: string, producer: InjectionProducer): number;
|
|
84
159
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
160
|
+
* Advance the turn generation for a session: the current ledger is discarded so
|
|
161
|
+
* the next request composition starts from a fresh generation. Called when
|
|
162
|
+
* compaction changes the message surface (`experimental.session.compacting`)
|
|
163
|
+
* and at session teardown.
|
|
87
164
|
*/
|
|
88
|
-
export declare function
|
|
165
|
+
export declare function advanceTurnGeneration(sessionID: string): void;
|
|
89
166
|
/**
|
|
90
|
-
*
|
|
91
|
-
* knowledge-injector can read it and compute its proportional share.
|
|
167
|
+
* Test/maintenance hook: clear one session's ledger.
|
|
92
168
|
*/
|
|
93
|
-
export declare function
|
|
169
|
+
export declare function clearTurnLedger(sessionID: string): void;
|
|
94
170
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
171
|
+
* Clear every session's ledger. Called from `resetSwarmState` so the
|
|
172
|
+
* plugin-wide reset also resets per-turn producer accounting (zaxbysauce
|
|
173
|
+
* review on PR #2415: the reset pattern must cover ALL module-scoped maps).
|
|
97
174
|
*/
|
|
98
|
-
export declare function
|
|
175
|
+
export declare function clearAllTurnLedgers(): void;
|
package/dist/state.d.ts
CHANGED
|
@@ -723,6 +723,34 @@ export declare const swarmState: {
|
|
|
723
723
|
pct: number;
|
|
724
724
|
tokens: number;
|
|
725
725
|
}>;
|
|
726
|
+
/**
|
|
727
|
+
* Final model-visible prompt pressure per session (#2107 §3) — the ONE
|
|
728
|
+
* truthful measurement taken after every injector has run and the system
|
|
729
|
+
* messages have been consolidated. Unlike `lastBudgetBySession` (the swarm
|
|
730
|
+
* INJECTION FOOTPRINT pct measured from an intermediate file surface),
|
|
731
|
+
* this is estimated total prompt tokens vs the same model limit physical
|
|
732
|
+
* pruning uses. Written by the final-context-accounting step; read by the
|
|
733
|
+
* compaction tiers, the CONTEXT PRESSURE advisory, and `/swarm status`.
|
|
734
|
+
* Bounded via {@link setFinalPromptPressure} (AGENTS.md invariant 8).
|
|
735
|
+
*/
|
|
736
|
+
finalPromptPressureBySession: Map<string, {
|
|
737
|
+
pct: number;
|
|
738
|
+
usedTokens: number;
|
|
739
|
+
limitTokens: number;
|
|
740
|
+
estimatorSource: string;
|
|
741
|
+
providerReported: boolean;
|
|
742
|
+
}>;
|
|
743
|
+
/**
|
|
744
|
+
* Per-session final-accounting warning-band latch (#2107 §3): one bounded
|
|
745
|
+
* advisory per session per band (warn / critical). Kept here — not in the
|
|
746
|
+
* hook module — so `resetSwarmState` covers it like every other
|
|
747
|
+
* session-keyed map (AGENTS.md invariant 8). Bounded via
|
|
748
|
+
* {@link setFinalAccountingWarningBand}.
|
|
749
|
+
*/
|
|
750
|
+
finalAccountingWarningBandsBySession: Map<string, {
|
|
751
|
+
warn: boolean;
|
|
752
|
+
critical: boolean;
|
|
753
|
+
}>;
|
|
726
754
|
/**
|
|
727
755
|
* Live `model.limit.context` per session — keyed by sessionID and bound to
|
|
728
756
|
* the reporting model/provider identity. Recorded by the
|
|
@@ -1382,6 +1410,34 @@ export declare function getLiveContextModelIdentity(sessionID: string | undefine
|
|
|
1382
1410
|
* written together so `/swarm status` can never pair a pct from one report
|
|
1383
1411
|
* with a denominator from another. */
|
|
1384
1412
|
export declare function setSessionBudget(sessionID: string, pct: number, tokens: number): void;
|
|
1413
|
+
/**
|
|
1414
|
+
* Record this session's final prompt pressure (#2107 §3), FIFO-evicting the
|
|
1415
|
+
* oldest entry past {@link MAX_TRACKED_BUDGET_SESSIONS}. Written once per request
|
|
1416
|
+
* composition by the final-context-accounting step.
|
|
1417
|
+
*/
|
|
1418
|
+
export declare function setFinalPromptPressure(sessionID: string, snapshot: {
|
|
1419
|
+
pct: number;
|
|
1420
|
+
usedTokens: number;
|
|
1421
|
+
limitTokens: number;
|
|
1422
|
+
estimatorSource: string;
|
|
1423
|
+
providerReported: boolean;
|
|
1424
|
+
}): void;
|
|
1425
|
+
/** The session's final prompt pressure snapshot, or undefined when the final
|
|
1426
|
+
* accounting step has not run for it (e.g. native-agent sessions). */
|
|
1427
|
+
export declare function getFinalPromptPressure(sessionID: string | undefined): {
|
|
1428
|
+
pct: number;
|
|
1429
|
+
usedTokens: number;
|
|
1430
|
+
limitTokens: number;
|
|
1431
|
+
estimatorSource: string;
|
|
1432
|
+
providerReported: boolean;
|
|
1433
|
+
} | undefined;
|
|
1434
|
+
/** Record that this session's #2107 §3 advisory already fired for a band
|
|
1435
|
+
* (one advisory per session per band), FIFO-evicting past the cap. */
|
|
1436
|
+
export declare function setFinalAccountingWarningBand(sessionID: string, band: 'warn' | 'critical'): void;
|
|
1437
|
+
/** Whether this session already received the band's advisory. */
|
|
1438
|
+
export declare function getFinalAccountingWarningBand(sessionID: string | undefined, band: 'warn' | 'critical'): boolean;
|
|
1439
|
+
/** Clear all band latches (used by resetSwarmState and tests). */
|
|
1440
|
+
export declare function clearFinalAccountingWarningBands(): void;
|
|
1385
1441
|
/** This session's last budget percentage, or 0 if it has not been measured.
|
|
1386
1442
|
* Consumers that ACT on a session (compaction, the context-pressure advisory)
|
|
1387
1443
|
* MUST use this rather than any cross-session aggregate. */
|
|
@@ -1397,6 +1453,19 @@ export declare function getDisplayBudget(): {
|
|
|
1397
1453
|
pct: number;
|
|
1398
1454
|
tokens: number;
|
|
1399
1455
|
} | null;
|
|
1456
|
+
/**
|
|
1457
|
+
* The most-pressured session's FINAL prompt pressure snapshot, for
|
|
1458
|
+
* process-wide DISPLAY only (`/swarm status` has no single session in scope).
|
|
1459
|
+
* The snapshot is returned whole so the pct, used tokens, limit, and estimator
|
|
1460
|
+
* source shown together always come from one measurement (#2107 §3).
|
|
1461
|
+
*/
|
|
1462
|
+
export declare function getDisplayFinalPromptPressure(): {
|
|
1463
|
+
pct: number;
|
|
1464
|
+
usedTokens: number;
|
|
1465
|
+
limitTokens: number;
|
|
1466
|
+
estimatorSource: string;
|
|
1467
|
+
providerReported: boolean;
|
|
1468
|
+
} | null;
|
|
1400
1469
|
/** Set the critical shown ids for a session, FIFO-evicting the oldest entry
|
|
1401
1470
|
* if the cap is exceeded. Re-setting an existing key keeps insertion order
|
|
1402
1471
|
* fresh for that key (delete-then-set). */
|
|
@@ -44,11 +44,40 @@ declare function summarizeJsonArray(parsed: unknown[]): string;
|
|
|
44
44
|
*/
|
|
45
45
|
declare function extractCodeSignatures(code: string): string[];
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* Codepoint-safe truncation to a UTF-8 byte budget (#2107 §5).
|
|
48
|
+
*
|
|
49
|
+
* Iterates code points (never UTF-16 units) so a multibyte CJK/emoji run can
|
|
50
|
+
* never be split mid-codepoint, and the result is deterministic across Bun and
|
|
51
|
+
* Node (which disagree on `Buffer.byteLength` for unpaired surrogates — per
|
|
52
|
+
* code point, both agree). Returns the kept text and the exact number of bytes
|
|
53
|
+
* omitted.
|
|
54
|
+
*/
|
|
55
|
+
export declare function truncateToBytes(text: string, maxBytes: number): {
|
|
56
|
+
text: string;
|
|
57
|
+
omittedBytes: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Deterministic bounded head/tail preview (#2107 §5).
|
|
61
|
+
*
|
|
62
|
+
* Head: the leading non-blank identity lines (ceil half of the line budget).
|
|
63
|
+
* Tail: the trailing RAW outcome lines (floor half) — compiler, test, lint,
|
|
64
|
+
* and security verdicts live at the END of tool output, so the old head-only
|
|
65
|
+
* preview discarded exactly the decision-relevant evidence. Lines are never
|
|
66
|
+
* reordered within either segment, no outcome is invented, and every dropped
|
|
67
|
+
* region is disclosed with an accurate omitted-line count. When everything
|
|
68
|
+
* fits, the original text is returned unchanged (modulo per-line caps).
|
|
69
|
+
*/
|
|
70
|
+
declare function headTailPreview(output: string, maxLines: number): string;
|
|
71
|
+
/**
|
|
72
|
+
* Build a preview for code output that includes declaration signatures plus
|
|
73
|
+
* the bounded head/tail policy (failure output at the end of a code blob is
|
|
74
|
+
* preserved).
|
|
48
75
|
*/
|
|
49
76
|
declare function summarizeCode(output: string): string;
|
|
50
77
|
/**
|
|
51
|
-
* Build a preview for plain text output
|
|
78
|
+
* Build a preview for plain text output using the bounded head/tail policy
|
|
79
|
+
* (see headTailPreview). Previously head-only: the first `maxLines` non-blank
|
|
80
|
+
* lines, which silently discarded trailing failure/exit evidence.
|
|
52
81
|
*/
|
|
53
82
|
declare function summarizeText(output: string, maxLines: number): string;
|
|
54
83
|
/**
|
|
@@ -56,7 +85,7 @@ declare function summarizeText(output: string, maxLines: number): string;
|
|
|
56
85
|
* @param output - The full tool output string
|
|
57
86
|
* @param toolName - The name of the tool that produced the output
|
|
58
87
|
* @param summaryId - Unique identifier for this summary
|
|
59
|
-
* @param maxSummaryChars - Maximum
|
|
88
|
+
* @param maxSummaryChars - Maximum bytes allowed for the preview
|
|
60
89
|
* @returns Formatted summary string
|
|
61
90
|
*/
|
|
62
91
|
export declare function createSummary(output: string, toolName: string, summaryId: string, maxSummaryChars: number): string;
|
|
@@ -64,6 +93,8 @@ export declare function createSummary(output: string, toolName: string, summaryI
|
|
|
64
93
|
* Internal helpers exposed for testability.
|
|
65
94
|
*/
|
|
66
95
|
export declare const _internals: {
|
|
96
|
+
truncateToBytes: typeof truncateToBytes;
|
|
97
|
+
headTailPreview: typeof headTailPreview;
|
|
67
98
|
jsonTypeSignature: typeof jsonTypeSignature;
|
|
68
99
|
summarizeJsonObject: typeof summarizeJsonObject;
|
|
69
100
|
summarizeJsonArray: typeof summarizeJsonArray;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derived SQLite index for the repo dependency graph (issue #1534).
|
|
3
|
+
*
|
|
4
|
+
* `.swarm/repo-graph.json` stays the single authoritative document in BOTH
|
|
5
|
+
* storage modes. When `repo_graph.storage === 'indexed'`, `saveGraph` also
|
|
6
|
+
* maintains `.swarm/repo-memory.sqlite`, a *derived accelerator* whose only job
|
|
7
|
+
* is to answer "give me the neighbourhood of these files" without parsing the
|
|
8
|
+
* whole JSON document. It returns an ordinary `RepoGraph` value that is fed to
|
|
9
|
+
* the existing, unmodified `getGraphNode` / `getLocalizationContext` /
|
|
10
|
+
* `getBlastRadius`, so no query logic is duplicated here.
|
|
11
|
+
*
|
|
12
|
+
* Every read verifies, before returning anything:
|
|
13
|
+
* (a) the persisted `graph_meta.workspace_root` realpath-matches the ACTIVE
|
|
14
|
+
* workspace (same trust boundary as `bindGraphToWorkspace`,
|
|
15
|
+
* `storage.ts:100-127`), and
|
|
16
|
+
* (b) `graph_meta.source_size` / `source_mtime_ms` equal a live stat of
|
|
17
|
+
* `repo-graph.json`.
|
|
18
|
+
* Any mismatch, absence, or error returns null and the caller uses its
|
|
19
|
+
* existing JSON path. The index is never a second source of truth.
|
|
20
|
+
*
|
|
21
|
+
* Runtime portability (AGENTS.md invariant 2): the SQLite driver is resolved
|
|
22
|
+
* ONLY through `src/db/sqlite-loader.ts`. The `import type` below is erased at
|
|
23
|
+
* build time, so this module contributes no `bun:` runtime resolution.
|
|
24
|
+
* `node:sqlite` is stricter than `bun:sqlite` about bound parameters, so every
|
|
25
|
+
* statement's placeholder count equals its argument count exactly and
|
|
26
|
+
* no-placeholder statements are issued as `db.run(sql)` with no array.
|
|
27
|
+
*/
|
|
28
|
+
import type { GraphNode, RepoGraph } from './types';
|
|
29
|
+
/** Filename of the derived index inside `.swarm/`. */
|
|
30
|
+
export declare const REPO_MEMORY_FILENAME = "repo-memory.sqlite";
|
|
31
|
+
/**
|
|
32
|
+
* Validated absolute path to `.swarm/repo-memory.sqlite`.
|
|
33
|
+
* Mirrors `getGraphPath`: validateWorkspace → validateSwarmPath →
|
|
34
|
+
* validateSymlinkBoundary.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getRepoMemoryPath(workspace: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Close the cached connection for a workspace. Called by the `/swarm close`
|
|
39
|
+
* clean stage before unlinking the store (Windows holds a WAL-mode file open,
|
|
40
|
+
* so `unlink` would fail with EBUSY — same guard as
|
|
41
|
+
* `closeProjectDb`, `project-db.ts:232-234`) and from test teardown.
|
|
42
|
+
*/
|
|
43
|
+
export declare function closeRepoMemory(workspace: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Close every cached connection. Test-teardown only: `/swarm close` uses the
|
|
46
|
+
* singular `closeRepoMemory` (src/commands/close.ts); this export has no
|
|
47
|
+
* other production caller.
|
|
48
|
+
*/
|
|
49
|
+
export declare function closeAllRepoMemory(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Delete the derived store and its WAL sidecars.
|
|
52
|
+
*
|
|
53
|
+
* The cached handle is closed FIRST on every delete path — a live WAL-mode
|
|
54
|
+
* connection keeps the file open and Windows `unlink` fails with EBUSY
|
|
55
|
+
* otherwise.
|
|
56
|
+
*/
|
|
57
|
+
export declare function deleteRepoMemory(workspace: string): void;
|
|
58
|
+
/** Whether a SQLite driver is resolvable in this runtime. */
|
|
59
|
+
export declare function isIndexedStorageAvailable(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Effective storage mode for a workspace.
|
|
62
|
+
*
|
|
63
|
+
* Config is the kill switch: flipping `repo_graph.storage` back to `'json'`
|
|
64
|
+
* stops every reader from consulting the index immediately, even while a valid
|
|
65
|
+
* store with a matching stamp is still on disk. Falls back to `'json'` on any
|
|
66
|
+
* config error and whenever no SQLite driver is available.
|
|
67
|
+
*/
|
|
68
|
+
export declare function resolveGraphStorageMode(workspace: string): 'json' | 'indexed';
|
|
69
|
+
/**
|
|
70
|
+
* Test seam (invariant 7: DI over mock.module) so the driver-unavailable
|
|
71
|
+
* fallback of {@link resolveGraphStorageMode} is exercisable without patching
|
|
72
|
+
* the module graph. Tests swap and restore the property; production reads it
|
|
73
|
+
* unchanged.
|
|
74
|
+
*/
|
|
75
|
+
export declare const _internals: {
|
|
76
|
+
isIndexedStorageAvailable: typeof isIndexedStorageAvailable;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Replace the whole index from `graph` in one transaction.
|
|
80
|
+
*
|
|
81
|
+
* `stamp` MUST be a stat of the TEMP FILE, taken inside the save lock
|
|
82
|
+
* immediately BEFORE this writer's rename publishes it — not a stat of
|
|
83
|
+
* `repo-graph.json` at any point. `rename(2)` leaves the inode's mtime and size
|
|
84
|
+
* untouched, so the temp-file stat identifies THIS writer's own bytes. Any stat
|
|
85
|
+
* of the published path instead describes whatever is at that path by then: a
|
|
86
|
+
* concurrent writer that failed the lock renames unlocked (the JSON write is
|
|
87
|
+
* never lock-gated), so a post-rename stat would let ITS bytes validate an index
|
|
88
|
+
* holding THIS writer's superseded content. See `saveGraph`.
|
|
89
|
+
*
|
|
90
|
+
* Returns false — never throws — on every failure; the JSON write is the
|
|
91
|
+
* durability point and has already succeeded.
|
|
92
|
+
*/
|
|
93
|
+
export declare function syncIndexFromGraph(workspace: string, graph: RepoGraph, stamp: {
|
|
94
|
+
size: number;
|
|
95
|
+
mtimeMs: number;
|
|
96
|
+
ino: string;
|
|
97
|
+
}): Promise<boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* Resolve a single file to its `GraphNode` using the index.
|
|
100
|
+
*
|
|
101
|
+
* Implements closure rule steps 1-2 in full, so an anchor whose `moduleName`
|
|
102
|
+
* diverges from `path.relative(root, filePath)` resolves exactly as it would
|
|
103
|
+
* through `getGraphNode` on the full graph. Returns null whenever the index is
|
|
104
|
+
* absent, stale, foreign, or unusable — the caller keeps its existing path.
|
|
105
|
+
*/
|
|
106
|
+
export declare function queryNodeByFile(workspace: string, file: string): GraphNode | null;
|
|
107
|
+
/**
|
|
108
|
+
* Build a bounded subgraph covering `files` and their neighbourhood, suitable
|
|
109
|
+
* for feeding the unmodified `getLocalizationContext` / `getBlastRadius`.
|
|
110
|
+
*
|
|
111
|
+
* Closure rule (normative, from the approved plan):
|
|
112
|
+
* 1-2. resolve every requested file the way `getGraphNode` would;
|
|
113
|
+
* 3. `T` = the union of resolved targets across ALL requested files in this
|
|
114
|
+
* ONE call (`getBlastRadius` seeds `visited` with every target at once,
|
|
115
|
+
* query.ts:623-625, so per-file subgraphs merged afterwards would produce
|
|
116
|
+
* a different `totalDependents` and therefore a different `riskLevel`);
|
|
117
|
+
* `N = T ∪ R_1..R_D ∪ F_1`, where `R` is the reverse closure to depth `D`
|
|
118
|
+
* and `F_1` is the 1-hop forward set from the targets only
|
|
119
|
+
* (`getDependencies`, query.ts:398-406);
|
|
120
|
+
* 4. `E = { edge : source ∈ N AND target ∈ N }` — AND, not incidence. An OR
|
|
121
|
+
* rule would admit frontier edges whose counterpart node is absent, and
|
|
122
|
+
* `moduleNameForEdgePath` (query.ts:83-88) silently degrades to a
|
|
123
|
+
* different string for those, changing `importers` / `dependencies` /
|
|
124
|
+
* `directDependents`. No asset/kind filtering happens in SQL:
|
|
125
|
+
* `buildReverseIndex` and `collectExternallyUsedSymbols` re-apply
|
|
126
|
+
* `isAssetEdge` downstream, so over-inclusion is harmless while
|
|
127
|
+
* under-inclusion is fatal;
|
|
128
|
+
* 5. the returned `workspaceRoot` is the realpath-bound ACTIVE workspace,
|
|
129
|
+
* never the persisted `graph_meta.workspace_root`.
|
|
130
|
+
*
|
|
131
|
+
* `depth` is clamped to at least 1: `getLocalizationContext` calls
|
|
132
|
+
* `getImporters` unconditionally, which needs `R_1` even when it passes
|
|
133
|
+
* `maxDepth = 0` to `getBlastRadius`. Over-inclusion of nodes is safe (a
|
|
134
|
+
* `maxDepth = 0` blast radius early-returns, query.ts:613-621).
|
|
135
|
+
*/
|
|
136
|
+
export declare function loadSubgraphForFiles(workspace: string, files: string[], depth: number): RepoGraph | null;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { FreshnessProbe } from './freshness';
|
|
2
2
|
import type { BlastRadiusResult, CallerReference, ContextPackResult, ContextPackSourceMode, DeadExportsResult, FileOntology, FileReference, GraphHealthResult, GraphNode, LocalizationBlock, PackageBoundarySummary, RepoGraph, SymbolReference } from './types';
|
|
3
3
|
export declare function getGraphNode(graph: RepoGraph, input: string): GraphNode | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Drop every cached query index. Required after any in-place mutation of a
|
|
6
|
+
* graph's `nodes` or `edges` (see the {@link queryIndexCache} contract note),
|
|
7
|
+
* and retained as the test seam for index-staleness assertions. Reassigns a
|
|
8
|
+
* fresh `WeakMap` rather than deleting keys, so it invalidates graphs this
|
|
9
|
+
* module can no longer enumerate.
|
|
10
|
+
*/
|
|
4
11
|
export declare function resetQueryCache(): void;
|
|
5
12
|
/**
|
|
6
13
|
* @deprecated Graph age is not a content-freshness signal. Internal consumers
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.155.0",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
"check:trajectory-store": "bun run scripts/check-trajectory-store-usage.ts",
|
|
115
115
|
"check:mock-cleanup": "bun run scripts/check-mock-cleanup.ts",
|
|
116
116
|
"check:invariants": "bun run scripts/check-invariants.ts",
|
|
117
|
+
"check:token-formula": "bun run scripts/check-token-formula.ts",
|
|
117
118
|
"check:cross-contamination": "bun run scripts/check-cross-contamination.ts",
|
|
118
119
|
"check:test-clock": "bun run scripts/check-test-clock.ts",
|
|
119
120
|
"check:test-file-cap": "bun run scripts/check-test-file-cap.ts",
|
|
@@ -123,6 +124,7 @@
|
|
|
123
124
|
"check:gate-portability": "bun run scripts/check-gate-portability.ts",
|
|
124
125
|
"check:bare-spawn": "bun run scripts/check-bare-executable-spawn.ts",
|
|
125
126
|
"check:error-channel-discard": "bun run scripts/check-error-channel-discard.ts",
|
|
127
|
+
"check:registry-citations": "bun run scripts/check-registry-citations.ts",
|
|
126
128
|
"check:memory-recall": "bun run scripts/memory-recall-regression.ts"
|
|
127
129
|
},
|
|
128
130
|
"dependencies": {
|