pi-crew 0.2.14 → 0.2.16
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/package.json
CHANGED
|
@@ -67,7 +67,6 @@ function formatCrewArtifactIndex(entries: CrewArtifactIndexEntry[]): string {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export function registerCompactionGuard(pi: ExtensionAPI, options: RegisterCompactionGuardOptions): void {
|
|
70
|
-
let pendingCompactReason: string | null = null;
|
|
71
70
|
let compactionInProgress = false;
|
|
72
71
|
|
|
73
72
|
const startCompact = (ctx: ExtensionContext, reason: string): void => {
|
|
@@ -94,34 +93,22 @@ export function registerCompactionGuard(pi: ExtensionAPI, options: RegisterCompa
|
|
|
94
93
|
});
|
|
95
94
|
};
|
|
96
95
|
|
|
97
|
-
// Phase 1.2:
|
|
96
|
+
// Phase 1.2: Allow compaction during foreground runs.
|
|
97
|
+
// Previously this deferred compaction, but that conflicts with context-mode's PreCompact hook
|
|
98
|
+
// which needs compaction to run to build resume snapshots.
|
|
99
|
+
// Instead, we now prioritize crew state in the compaction summary (see startCompact).
|
|
98
100
|
pi.on("session_before_compact", async (_event, ctx) => {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
ctx.ui.notify("Compaction allowed despite foreground run: context is critically full", "warning");
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
pendingCompactReason = "deferred-during-foreground-run";
|
|
106
|
-
ctx.ui.notify("Compaction deferred: foreground team run in progress", "info");
|
|
107
|
-
return { cancel: true };
|
|
101
|
+
// Always allow compaction - context-mode needs it for resume snapshots
|
|
102
|
+
// pi-crew state is preserved via customInstructions and artifactIndex
|
|
103
|
+
return;
|
|
108
104
|
});
|
|
109
105
|
|
|
110
106
|
// Phase 2.1: Proactive compaction with dynamic threshold based on model context window.
|
|
111
107
|
pi.on("turn_end", (_event, ctx) => {
|
|
112
108
|
if (compactionInProgress) return;
|
|
113
|
-
const hasActiveForeground = options.foregroundControllers.size > 0 || options.foregroundTeamRunControllers.size > 0;
|
|
114
|
-
if (!hasActiveForeground && pendingCompactReason) {
|
|
115
|
-
pendingCompactReason = null;
|
|
116
|
-
startCompact(ctx, "deferred");
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
109
|
const ratio = usageRatio(ctx);
|
|
120
110
|
if (ratio === undefined || ratio < TRIGGER_RATIO) return;
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
startCompact(ctx, "threshold");
|
|
111
|
+
// Always allow compaction during foreground runs - context-mode needs it
|
|
112
|
+
startCompact(ctx, ratio >= HARD_RATIO ? "critical" : "threshold");
|
|
126
113
|
});
|
|
127
114
|
}
|
package/src/ui/crew-widget.ts
CHANGED
|
@@ -156,9 +156,15 @@ function agentStats(agent: CrewAgentRecord, liveHandle?: LiveAgentHandle): strin
|
|
|
156
156
|
const rawCompleted = act.completedAtMs || 0;
|
|
157
157
|
const nowMs = Date.now();
|
|
158
158
|
const nowSec = Math.floor(nowMs / 1000);
|
|
159
|
-
// Detect if value is in seconds
|
|
160
|
-
// If value
|
|
161
|
-
const isSeconds = (v: number) =>
|
|
159
|
+
// Detect if value is in seconds vs milliseconds by comparing distance to current time
|
|
160
|
+
// If value is closer to nowSec (within ±2 years) AND not close to nowMs, treat as seconds
|
|
161
|
+
const isSeconds = (v: number) => {
|
|
162
|
+
if (v <= 0) return false;
|
|
163
|
+
const distToSec = Math.abs(v - nowSec);
|
|
164
|
+
const distToMs = Math.abs(v - nowMs);
|
|
165
|
+
// If distance to seconds is much smaller AND value is in valid seconds range
|
|
166
|
+
return distToSec < distToMs && distToSec < 31536000 * 2 && v > 1000000000;
|
|
167
|
+
};
|
|
162
168
|
const startedMs = isSeconds(rawStarted) ? rawStarted * 1000 : rawStarted;
|
|
163
169
|
const completedMs = isSeconds(rawCompleted) ? rawCompleted * 1000 : rawCompleted;
|
|
164
170
|
// Validate: startedAtMs should be within reasonable bounds
|
|
@@ -67,8 +67,14 @@ export class LiveConversationOverlay {
|
|
|
67
67
|
const rawStarted = act.startedAtMs || 0;
|
|
68
68
|
const rawCompleted = act.completedAtMs || 0;
|
|
69
69
|
const nowMs = Date.now();
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
const nowSec = Math.floor(nowMs / 1000);
|
|
71
|
+
// Detect if value is in seconds vs milliseconds by comparing distance to current time
|
|
72
|
+
const isSeconds = (v: number) => {
|
|
73
|
+
if (v <= 0) return false;
|
|
74
|
+
const distToSec = Math.abs(v - nowSec);
|
|
75
|
+
const distToMs = Math.abs(v - nowMs);
|
|
76
|
+
return distToSec < distToMs && distToSec < 31536000 * 2 && v > 1000000000;
|
|
77
|
+
};
|
|
72
78
|
const startedMs = isSeconds(rawStarted) ? rawStarted * 1000 : rawStarted;
|
|
73
79
|
const completedMs = isSeconds(rawCompleted) ? rawCompleted * 1000 : rawCompleted;
|
|
74
80
|
const isValidStarted = startedMs > 0 && startedMs < nowMs + 60000 && startedMs > nowMs - 3155692600000;
|