ai-foreman 1.7.8 → 1.7.10
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/README.md +1 -11
- package/dist/activity.js +2 -2
- package/dist/adapters/claude.d.ts +15 -29
- package/dist/adapters/claude.js +90 -334
- package/dist/adapters/codex.d.ts +15 -18
- package/dist/adapters/codex.js +112 -195
- package/dist/adapters/recovering.d.ts +6 -6
- package/dist/adapters/recovering.js +6 -9
- package/dist/adapters/types.d.ts +37 -66
- package/dist/branch/currentGuard.d.ts +6 -5
- package/dist/branch/currentGuard.js +5 -6
- package/dist/branch/runner.d.ts +2 -0
- package/dist/branch/runner.js +2 -1
- package/dist/cli/start.js +95 -165
- package/dist/continuity.d.ts +7 -8
- package/dist/continuity.js +27 -72
- package/dist/foreman.d.ts +7 -1
- package/dist/foreman.js +25 -1
- package/dist/handoffs.js +3 -223
- package/dist/qaReview.d.ts +2 -0
- package/dist/qaReview.js +1 -4
- package/dist/sessionLifecycle.d.ts +22 -108
- package/dist/sessionLifecycle.js +322 -1023
- package/dist/statusReporter.d.ts +6 -27
- package/dist/statusReporter.js +21 -76
- package/dist/workflowDb.d.ts +10 -47
- package/dist/workflowDb.js +41 -146
- package/package.json +4 -4
package/dist/adapters/types.d.ts
CHANGED
|
@@ -59,55 +59,7 @@ export interface TurnResult {
|
|
|
59
59
|
inputTokens?: number;
|
|
60
60
|
outputTokens?: number;
|
|
61
61
|
failure?: RuntimeFailure;
|
|
62
|
-
/** A provider turn stopped at a context-compaction boundary, not a failure. */
|
|
63
|
-
interrupted?: {
|
|
64
|
-
reason: "compaction-boundary";
|
|
65
|
-
providerEventId?: string;
|
|
66
|
-
};
|
|
67
62
|
}
|
|
68
|
-
export type ContextCompactionOrigin = "provider-auto" | "rafi-manual" | "recovery" | "boundary";
|
|
69
|
-
export type ContextCompactionPhase = "started" | "succeeded" | "failed";
|
|
70
|
-
/** Native context policy installed before a Builder/QA role may do real work. */
|
|
71
|
-
export interface ContextManagementPolicy {
|
|
72
|
-
role: "builder" | "qa";
|
|
73
|
-
configuredThresholdPercent: number;
|
|
74
|
-
compactMaximum: number;
|
|
75
|
-
settingsRevision: number;
|
|
76
|
-
model: string;
|
|
77
|
-
/** Continue a provider-monotonic sequence after process recovery. */
|
|
78
|
-
providerSequenceStart?: number;
|
|
79
|
-
/** A persisted, model-matched maximum may avoid a discovery turn. */
|
|
80
|
-
knownModelContextWindow?: number;
|
|
81
|
-
/** Native compaction stays enabled until the host vetoes a boundary. */
|
|
82
|
-
nativeCompactionEnabled?: boolean;
|
|
83
|
-
}
|
|
84
|
-
export interface PreparedContextManagement {
|
|
85
|
-
modelContextWindow: number;
|
|
86
|
-
configuredTokenLimit: number;
|
|
87
|
-
installedNativeTokenLimit: number;
|
|
88
|
-
installedNativePercent: number;
|
|
89
|
-
sample?: ContextUsage;
|
|
90
|
-
}
|
|
91
|
-
export interface ContextCompactionEvent {
|
|
92
|
-
kind: "context-compaction";
|
|
93
|
-
phase: ContextCompactionPhase;
|
|
94
|
-
origin: ContextCompactionOrigin;
|
|
95
|
-
providerEventId: string;
|
|
96
|
-
providerSequence: number;
|
|
97
|
-
provider: "claude" | "codex";
|
|
98
|
-
sessionId?: string;
|
|
99
|
-
sessionRef?: ProviderSessionRefV1;
|
|
100
|
-
observedAt: string;
|
|
101
|
-
postCompactSample?: ContextUsage;
|
|
102
|
-
reason?: string;
|
|
103
|
-
}
|
|
104
|
-
export interface InterruptResult {
|
|
105
|
-
ok: boolean;
|
|
106
|
-
error?: string;
|
|
107
|
-
providerEventId?: string;
|
|
108
|
-
}
|
|
109
|
-
/** Host-owned gate used by wrappers that need additional provider turns. */
|
|
110
|
-
export type ManagedTurnDispatcher = (text: string, invoke: () => Promise<TurnResult>) => Promise<TurnResult>;
|
|
111
63
|
/** Observability events emitted while a builder works. */
|
|
112
64
|
export type BuilderEvent = {
|
|
113
65
|
kind: "text";
|
|
@@ -145,10 +97,7 @@ export type BuilderEvent = {
|
|
|
145
97
|
percentage?: number;
|
|
146
98
|
observedAt?: string;
|
|
147
99
|
source?: "provider-event" | "provider-query" | "post-compact";
|
|
148
|
-
|
|
149
|
-
sessionId?: string;
|
|
150
|
-
model?: string;
|
|
151
|
-
} | ContextCompactionEvent | {
|
|
100
|
+
} | {
|
|
152
101
|
kind: "error";
|
|
153
102
|
message: string;
|
|
154
103
|
};
|
|
@@ -158,10 +107,17 @@ export interface ContextUsage {
|
|
|
158
107
|
percentage?: number;
|
|
159
108
|
observedAt?: string;
|
|
160
109
|
source?: "provider-event" | "provider-query" | "post-compact";
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The provider-native automatic-compaction policy that was actually installed.
|
|
113
|
+
* Providers may clamp a requested ceiling to a model- or runtime-specific
|
|
114
|
+
* minimum, so lifecycle enforcement must consume the effective value.
|
|
115
|
+
*/
|
|
116
|
+
export interface NativeAutoCompactionPolicy {
|
|
117
|
+
requestedThresholdPercent: number;
|
|
118
|
+
effectiveThresholdPercent: number;
|
|
119
|
+
modelContextWindow?: number;
|
|
120
|
+
triggerTokens?: number;
|
|
165
121
|
}
|
|
166
122
|
export interface ProviderSessionUsage {
|
|
167
123
|
inputTokens?: number;
|
|
@@ -177,6 +133,15 @@ export interface CompactResult {
|
|
|
177
133
|
/** Preserve exact-session loss so lifecycle policy never treats it as an ordinary retryable compaction failure. */
|
|
178
134
|
failure?: RuntimeFailure;
|
|
179
135
|
}
|
|
136
|
+
/** A provider-confirmed compaction that happened without Rafi issuing /compact. */
|
|
137
|
+
export interface NativeCompaction {
|
|
138
|
+
/** Stable for the lifetime of an adapter; used for durable idempotency. */
|
|
139
|
+
id: string;
|
|
140
|
+
occurredAt: string;
|
|
141
|
+
provider: "claude" | "codex";
|
|
142
|
+
/** Adapter-local usage generation captured with the provider confirmation. */
|
|
143
|
+
usageRevision?: number;
|
|
144
|
+
}
|
|
180
145
|
export interface ProviderSettingSwitch {
|
|
181
146
|
model?: string;
|
|
182
147
|
effort?: EffortLevel;
|
|
@@ -218,8 +183,8 @@ export interface BuilderAdapterOptions {
|
|
|
218
183
|
systemPromptAppend?: string;
|
|
219
184
|
/** Skill names to preload for this session (Claude: lazy-loaded; Codex: flattened). */
|
|
220
185
|
skills?: string[];
|
|
221
|
-
/**
|
|
222
|
-
|
|
186
|
+
/** Provider-native context ceiling, as a percentage of that provider's model window. */
|
|
187
|
+
autoCompactThresholdPercent?: number;
|
|
223
188
|
}
|
|
224
189
|
export interface BuilderAdapter {
|
|
225
190
|
readonly agent: "claude" | "codex";
|
|
@@ -235,14 +200,20 @@ export interface BuilderAdapter {
|
|
|
235
200
|
validateSession?(): Promise<SessionAvailabilityV1>;
|
|
236
201
|
/** Provider-native compaction on the exact live conversation. */
|
|
237
202
|
compact?(): Promise<CompactResult>;
|
|
238
|
-
/**
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Install and verify provider-native automatic compaction before role work is
|
|
205
|
+
* dispatched. This intentionally happens outside a work turn so a long,
|
|
206
|
+
* tool-heavy first turn is protected too.
|
|
207
|
+
*/
|
|
208
|
+
prepareAutoCompaction?(thresholdPercent?: number): Promise<NativeAutoCompactionPolicy | void>;
|
|
209
|
+
/** The last provider-native automatic-compaction policy verified on this transport. */
|
|
210
|
+
autoCompactionPolicy?(): NativeAutoCompactionPolicy | undefined;
|
|
211
|
+
/** Consume provider-native compactions observed since the prior drain. */
|
|
212
|
+
drainNativeCompactions?(): NativeCompaction[];
|
|
213
|
+
/** Return a drained batch to the adapter when durable receipt failed. */
|
|
214
|
+
restoreNativeCompactions?(compactions: NativeCompaction[]): void;
|
|
215
|
+
/** Return occupancy known to postdate a native-compaction event, if available. */
|
|
216
|
+
contextUsageAfterNativeCompaction?(compaction: NativeCompaction): Promise<ContextUsage | undefined>;
|
|
246
217
|
/** Truthful provider context occupancy, when exposed by the provider. */
|
|
247
218
|
contextUsage?(): Promise<ContextUsage | undefined>;
|
|
248
219
|
/** Provider/session cumulative totals; distinct from live context occupancy. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BuilderAdapter, BuilderEvent, CompactResult,
|
|
1
|
+
import type { BuilderAdapter, BuilderEvent, CompactResult, ContextUsage, NativeAutoCompactionPolicy, NativeCompaction, ProviderSessionUsage, ProviderSettingSwitch, TurnResult } from "../adapters/types.js";
|
|
2
2
|
import type { ProviderSessionRefV1, SessionAvailabilityV1 } from "rafi-spec";
|
|
3
3
|
export interface CurrentWorkflowIdentity {
|
|
4
4
|
worktree: string;
|
|
@@ -26,10 +26,11 @@ export declare class CurrentWorkflowGuardAdapter implements BuilderAdapter {
|
|
|
26
26
|
adoptSessionRef(ref: ProviderSessionRefV1): void;
|
|
27
27
|
validateSession(): Promise<SessionAvailabilityV1>;
|
|
28
28
|
compact(): Promise<CompactResult>;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
prepareAutoCompaction(thresholdPercent?: number): Promise<NativeAutoCompactionPolicy | void>;
|
|
30
|
+
autoCompactionPolicy(): NativeAutoCompactionPolicy | undefined;
|
|
31
|
+
drainNativeCompactions(): import("../adapters/types.js").NativeCompaction[];
|
|
32
|
+
restoreNativeCompactions(compactions: NativeCompaction[]): void;
|
|
33
|
+
contextUsageAfterNativeCompaction(compaction: NativeCompaction): Promise<ContextUsage | undefined>;
|
|
33
34
|
contextUsage(): Promise<ContextUsage | undefined>;
|
|
34
35
|
sessionUsage(): Promise<ProviderSessionUsage | undefined>;
|
|
35
36
|
switchSettings(settings: ProviderSettingSwitch): Promise<CompactResult>;
|
|
@@ -48,12 +48,11 @@ export class CurrentWorkflowGuardAdapter {
|
|
|
48
48
|
adoptSessionRef(ref) { this.adapter.adoptSessionRef?.(ref); }
|
|
49
49
|
validateSession() { assertCurrentWorkflowIdentity(this.cwd, this.expected); return this.adapter.validateSession?.() ?? Promise.resolve({ version: 1, status: "unknown", checkedAt: new Date().toISOString(), reason: "legacy-unscoped" }); }
|
|
50
50
|
async compact() { assertCurrentWorkflowIdentity(this.cwd, this.expected); const result = await (this.adapter.compact?.() ?? Promise.resolve({ ok: false, error: "native compaction unavailable" })); assertCurrentWorkflowIdentity(this.cwd, this.expected); return result; }
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
installManagedTurnDispatcher(dispatcher) { this.adapter.installManagedTurnDispatcher?.(dispatcher); }
|
|
51
|
+
prepareAutoCompaction(thresholdPercent) { return this.adapter.prepareAutoCompaction?.(thresholdPercent) ?? Promise.resolve(); }
|
|
52
|
+
autoCompactionPolicy() { return this.adapter.autoCompactionPolicy?.(); }
|
|
53
|
+
drainNativeCompactions() { return this.adapter.drainNativeCompactions?.() ?? []; }
|
|
54
|
+
restoreNativeCompactions(compactions) { this.adapter.restoreNativeCompactions?.(compactions); }
|
|
55
|
+
contextUsageAfterNativeCompaction(compaction) { return this.adapter.contextUsageAfterNativeCompaction?.(compaction) ?? Promise.resolve(undefined); }
|
|
57
56
|
contextUsage() { return this.adapter.contextUsage?.() ?? Promise.resolve(undefined); }
|
|
58
57
|
sessionUsage() { return this.adapter.sessionUsage?.() ?? Promise.resolve(undefined); }
|
|
59
58
|
switchSettings(settings) { return this.adapter.switchSettings?.(settings) ?? Promise.resolve({ ok: false, error: "settings switch unavailable" }); }
|
package/dist/branch/runner.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export interface BranchRunnerOptions {
|
|
|
56
56
|
builderSessionStrategy?: SessionStrategy;
|
|
57
57
|
qaSessionStrategy?: SessionStrategy;
|
|
58
58
|
observeBuilder?: (builder: BuilderAdapter) => Promise<void>;
|
|
59
|
+
observeBuilderNativeCompactions?: (builder: BuilderAdapter, cwd: string) => Promise<void>;
|
|
60
|
+
observeQaNativeCompactions?: (adapter: BuilderAdapter) => Promise<void>;
|
|
59
61
|
qaNonconvergence?: (context: QaNonconvergenceContext) => Promise<QaNonconvergenceDecision>;
|
|
60
62
|
beforeBuilderTurn?: (adapter: BuilderAdapter, frozenAction: string, cwd: string) => Promise<BuilderAdapter>;
|
|
61
63
|
builderSessionBoundary?: (adapter: BuilderAdapter, frozenAction: string, strategy: SessionStrategy, cwd: string) => Promise<BuilderAdapter>;
|
package/dist/branch/runner.js
CHANGED
|
@@ -173,7 +173,7 @@ export async function runBranchPlan(opts) {
|
|
|
173
173
|
}
|
|
174
174
|
builderWorkSessions += 1;
|
|
175
175
|
viewer = opts.observeBuilder?.(builder);
|
|
176
|
-
const foreman = new Foreman(builder, opts.log, opts.notificationsEnabled, opts.qaEnabled, 3, undefined, undefined, undefined, opts.qaSessionStrategy ?? "compact", undefined, opts.builderSessionStrategy ?? "compact", undefined, opts.beforeBuilderTurn ? (adapter, action) => opts.beforeBuilderTurn(adapter, action, worktreePath) : undefined);
|
|
176
|
+
const foreman = new Foreman(builder, opts.log, opts.notificationsEnabled, opts.qaEnabled, 3, undefined, undefined, undefined, opts.qaSessionStrategy ?? "compact", undefined, opts.builderSessionStrategy ?? "compact", undefined, opts.beforeBuilderTurn ? (adapter, action) => opts.beforeBuilderTurn(adapter, action, worktreePath) : undefined, undefined, undefined, async (adapter) => opts.observeBuilderNativeCompactions?.(adapter, worktreePath));
|
|
177
177
|
const { result, status } = await foreman.runInstruction(ticketInstruction);
|
|
178
178
|
builder = foreman.builderAdapter();
|
|
179
179
|
workflowCheckpoint(opts.projectDir, opts.runId, "builder-after", node.ticket.id, { status: status.kind, sessionId: builder.sessionId(), worktree: worktreePath });
|
|
@@ -242,6 +242,7 @@ export async function runBranchPlan(opts) {
|
|
|
242
242
|
ticket: node.ticket, builderWorktree: worktreePath, builderSummary: status.summary ?? result.text,
|
|
243
243
|
qaStrategy: opts.qaSessionStrategy ?? "compact", state: qaStream, createQa: opts.createQa, maxCycles: 3,
|
|
244
244
|
sessionBoundary: opts.qaSessionBoundary,
|
|
245
|
+
observeNativeCompactions: opts.observeQaNativeCompactions,
|
|
245
246
|
evidence: (entry) => opts.log.write("qa-evidence", { ticket: node.ticket.id, ...entry }),
|
|
246
247
|
fix: async (issues) => {
|
|
247
248
|
if (!builder)
|