ai-foreman 1.7.8 → 1.7.9
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 +13 -29
- package/dist/adapters/claude.js +76 -334
- package/dist/adapters/codex.d.ts +13 -18
- package/dist/adapters/codex.js +103 -195
- package/dist/adapters/recovering.d.ts +5 -6
- package/dist/adapters/recovering.js +5 -9
- package/dist/adapters/types.d.ts +24 -66
- package/dist/branch/currentGuard.d.ts +5 -5
- package/dist/branch/currentGuard.js +4 -6
- package/dist/branch/runner.d.ts +2 -0
- package/dist/branch/runner.js +2 -1
- package/dist/cli/start.js +90 -165
- package/dist/continuity.d.ts +6 -8
- package/dist/continuity.js +26 -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 +19 -108
- package/dist/sessionLifecycle.js +310 -1024
- package/dist/statusReporter.d.ts +5 -27
- package/dist/statusReporter.js +20 -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,6 @@ export interface ContextUsage {
|
|
|
158
107
|
percentage?: number;
|
|
159
108
|
observedAt?: string;
|
|
160
109
|
source?: "provider-event" | "provider-query" | "post-compact";
|
|
161
|
-
/** Monotonic within one scoped provider session. */
|
|
162
|
-
sequence?: number;
|
|
163
|
-
sessionId?: string;
|
|
164
|
-
model?: string;
|
|
165
110
|
}
|
|
166
111
|
export interface ProviderSessionUsage {
|
|
167
112
|
inputTokens?: number;
|
|
@@ -177,6 +122,15 @@ export interface CompactResult {
|
|
|
177
122
|
/** Preserve exact-session loss so lifecycle policy never treats it as an ordinary retryable compaction failure. */
|
|
178
123
|
failure?: RuntimeFailure;
|
|
179
124
|
}
|
|
125
|
+
/** A provider-confirmed compaction that happened without Rafi issuing /compact. */
|
|
126
|
+
export interface NativeCompaction {
|
|
127
|
+
/** Stable for the lifetime of an adapter; used for durable idempotency. */
|
|
128
|
+
id: string;
|
|
129
|
+
occurredAt: string;
|
|
130
|
+
provider: "claude" | "codex";
|
|
131
|
+
/** Adapter-local usage generation captured with the provider confirmation. */
|
|
132
|
+
usageRevision?: number;
|
|
133
|
+
}
|
|
180
134
|
export interface ProviderSettingSwitch {
|
|
181
135
|
model?: string;
|
|
182
136
|
effort?: EffortLevel;
|
|
@@ -218,8 +172,8 @@ export interface BuilderAdapterOptions {
|
|
|
218
172
|
systemPromptAppend?: string;
|
|
219
173
|
/** Skill names to preload for this session (Claude: lazy-loaded; Codex: flattened). */
|
|
220
174
|
skills?: string[];
|
|
221
|
-
/**
|
|
222
|
-
|
|
175
|
+
/** Provider-native context ceiling, as a percentage of that provider's model window. */
|
|
176
|
+
autoCompactThresholdPercent?: number;
|
|
223
177
|
}
|
|
224
178
|
export interface BuilderAdapter {
|
|
225
179
|
readonly agent: "claude" | "codex";
|
|
@@ -235,14 +189,18 @@ export interface BuilderAdapter {
|
|
|
235
189
|
validateSession?(): Promise<SessionAvailabilityV1>;
|
|
236
190
|
/** Provider-native compaction on the exact live conversation. */
|
|
237
191
|
compact?(): Promise<CompactResult>;
|
|
238
|
-
/**
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Install and verify provider-native automatic compaction before role work is
|
|
194
|
+
* dispatched. This intentionally happens outside a work turn so a long,
|
|
195
|
+
* tool-heavy first turn is protected too.
|
|
196
|
+
*/
|
|
197
|
+
prepareAutoCompaction?(thresholdPercent?: number): Promise<void>;
|
|
198
|
+
/** Consume provider-native compactions observed since the prior drain. */
|
|
199
|
+
drainNativeCompactions?(): NativeCompaction[];
|
|
200
|
+
/** Return a drained batch to the adapter when durable receipt failed. */
|
|
201
|
+
restoreNativeCompactions?(compactions: NativeCompaction[]): void;
|
|
202
|
+
/** Return occupancy known to postdate a native-compaction event, if available. */
|
|
203
|
+
contextUsageAfterNativeCompaction?(compaction: NativeCompaction): Promise<ContextUsage | undefined>;
|
|
246
204
|
/** Truthful provider context occupancy, when exposed by the provider. */
|
|
247
205
|
contextUsage?(): Promise<ContextUsage | undefined>;
|
|
248
206
|
/** 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, 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,10 @@ 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<void>;
|
|
30
|
+
drainNativeCompactions(): import("../adapters/types.js").NativeCompaction[];
|
|
31
|
+
restoreNativeCompactions(compactions: NativeCompaction[]): void;
|
|
32
|
+
contextUsageAfterNativeCompaction(compaction: NativeCompaction): Promise<ContextUsage | undefined>;
|
|
33
33
|
contextUsage(): Promise<ContextUsage | undefined>;
|
|
34
34
|
sessionUsage(): Promise<ProviderSessionUsage | undefined>;
|
|
35
35
|
switchSettings(settings: ProviderSettingSwitch): Promise<CompactResult>;
|
|
@@ -48,12 +48,10 @@ 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
|
-
interruptTurnAtCompactionBoundary(providerEventId) { return this.adapter.interruptTurnAtCompactionBoundary?.(providerEventId) ?? Promise.resolve({ ok: false, error: "compaction-boundary interruption unavailable", providerEventId }); }
|
|
56
|
-
installManagedTurnDispatcher(dispatcher) { this.adapter.installManagedTurnDispatcher?.(dispatcher); }
|
|
51
|
+
prepareAutoCompaction(thresholdPercent) { return this.adapter.prepareAutoCompaction?.(thresholdPercent) ?? Promise.resolve(); }
|
|
52
|
+
drainNativeCompactions() { return this.adapter.drainNativeCompactions?.() ?? []; }
|
|
53
|
+
restoreNativeCompactions(compactions) { this.adapter.restoreNativeCompactions?.(compactions); }
|
|
54
|
+
contextUsageAfterNativeCompaction(compaction) { return this.adapter.contextUsageAfterNativeCompaction?.(compaction) ?? Promise.resolve(undefined); }
|
|
57
55
|
contextUsage() { return this.adapter.contextUsage?.() ?? Promise.resolve(undefined); }
|
|
58
56
|
sessionUsage() { return this.adapter.sessionUsage?.() ?? Promise.resolve(undefined); }
|
|
59
57
|
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)
|