@team-agent/installer 0.5.32 → 0.5.34
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/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
|
@@ -764,9 +764,31 @@ impl Coordinator {
|
|
|
764
764
|
// refreshed BEFORE classification (the classifier sees the updated value).
|
|
765
765
|
// A non-empty but UNCHANGED capture must not dirty the state every tick
|
|
766
766
|
// (P3 umbrella: steady second tick is a zero state write).
|
|
767
|
+
//
|
|
768
|
+
// 0.5.32 follow-up (`.team/artifacts/0532-r1-real-fail-triage.md` §6):
|
|
769
|
+
// fresh-cohort startup-output guard. After the restart clear helper wipes
|
|
770
|
+
// `activity`/`worker_state`/`last_output_at`/`last_output_hash`, the first
|
|
771
|
+
// non-empty pane capture (fake worker's READY line, provider startup
|
|
772
|
+
// banner) is trivially different from the missing digest. If we let it
|
|
773
|
+
// set `last_output_at=now`, classify_agent_activity falls through to
|
|
774
|
+
// `recent_provider_output => Working` even though no structural signal
|
|
775
|
+
// exists — that's the R1 real-machine false busy.
|
|
776
|
+
//
|
|
777
|
+
// Narrow gate: fresh cohort (no activity/worker_state/last_output_at
|
|
778
|
+
// /last_output_hash/current turn/task fields), no work obligation
|
|
779
|
+
// arming a real send, and no structural prompt/working signal in the
|
|
780
|
+
// capture → still update `last_output_hash` (dedup) but do NOT write
|
|
781
|
+
// `last_output_at`. The classifier then returns Uncertain=UNKNOWN,
|
|
782
|
+
// which is the honest post-clear observation. Preserves recent_provider_output
|
|
783
|
+
// for non-startup normal output (later capture has prior last_output_at
|
|
784
|
+
// or last_output_hash, so `fresh_cohort` false → gate skipped).
|
|
785
|
+
let fresh_cohort = agent_is_fresh_cohort(agent);
|
|
786
|
+
let has_structural_signal = latest_pane_signal_is_structural(&captured.text);
|
|
767
787
|
let output_advanced =
|
|
768
788
|
!captured.text.is_empty() && scrollback_digest_advanced(agent, &captured.text);
|
|
769
|
-
|
|
789
|
+
let suppress_last_output_at =
|
|
790
|
+
output_advanced && fresh_cohort && !has_work_obligation && !has_structural_signal;
|
|
791
|
+
if output_advanced && !suppress_last_output_at {
|
|
770
792
|
if let Some(agent_obj) = agent.as_object_mut() {
|
|
771
793
|
agent_obj.insert(
|
|
772
794
|
"last_output_at".to_string(),
|
|
@@ -1808,11 +1830,21 @@ fn parse_rfc3339_utc(raw: &str) -> Option<chrono::DateTime<chrono::Utc>> {
|
|
|
1808
1830
|
}
|
|
1809
1831
|
|
|
1810
1832
|
/// 0.5.32 (`.team/artifacts/restart-resumed-stale-activity-locate.md` §5):
|
|
1811
|
-
/// return true when the rollout file's modification time is
|
|
1812
|
-
/// the agent's current `spawned_at`. Used by `jsonl_activity_for_agent`
|
|
1813
|
-
/// refuse classifying a pre-spawn transcript tail into fresh-cohort
|
|
1814
|
-
/// Missing `spawned_at`, missing mtime, or unparseable timestamp
|
|
1815
|
-
/// (do not block classification; the caller keeps the pre-0.5.32
|
|
1833
|
+
/// return true when the rollout file's modification time is strictly older
|
|
1834
|
+
/// than the agent's current `spawned_at`. Used by `jsonl_activity_for_agent`
|
|
1835
|
+
/// to refuse classifying a pre-spawn transcript tail into fresh-cohort
|
|
1836
|
+
/// activity. Missing `spawned_at`, missing mtime, or unparseable timestamp
|
|
1837
|
+
/// → false (do not block classification; the caller keeps the pre-0.5.32
|
|
1838
|
+
/// behavior).
|
|
1839
|
+
///
|
|
1840
|
+
/// 0.5.33 boundary tightening (leader 派单 msg_42dbad7f2938 / earlier cr
|
|
1841
|
+
/// batch older-or-equal 预警): use strict `<` not `<=`. Fast machines can
|
|
1842
|
+
/// produce a fresh post-spawn rollout whose mtime shares the second-resolution
|
|
1843
|
+
/// `spawned_at`; treating "equal" as pre-spawn would wrongly reject the
|
|
1844
|
+
/// first post-spawn transcript record. Genuinely pre-spawn transcripts have
|
|
1845
|
+
/// mtime strictly before `spawned_at` and remain rejected. The equal case
|
|
1846
|
+
/// falls back to the classifier + pane fallback, which is the ambiguous-
|
|
1847
|
+
/// but-safe path.
|
|
1816
1848
|
fn jsonl_older_than_spawn_boundary(agent: &Value, metadata: &std::fs::Metadata) -> bool {
|
|
1817
1849
|
let Some(spawned_at) = agent
|
|
1818
1850
|
.get("spawned_at")
|
|
@@ -1829,7 +1861,7 @@ fn jsonl_older_than_spawn_boundary(agent: &Value, metadata: &std::fs::Metadata)
|
|
|
1829
1861
|
};
|
|
1830
1862
|
let mtime_utc =
|
|
1831
1863
|
chrono::DateTime::<chrono::Utc>::from(std::time::UNIX_EPOCH + mtime_since_epoch);
|
|
1832
|
-
mtime_utc
|
|
1864
|
+
mtime_utc < spawned_at
|
|
1833
1865
|
}
|
|
1834
1866
|
|
|
1835
1867
|
fn matching_capture_pane_info(
|
|
@@ -2246,6 +2278,48 @@ fn clear_awaiting_human_confirm(agent: &mut Value) {
|
|
|
2246
2278
|
}
|
|
2247
2279
|
}
|
|
2248
2280
|
|
|
2281
|
+
/// 0.5.32 follow-up (`.team/artifacts/0532-r1-real-fail-triage.md` §6/§7):
|
|
2282
|
+
/// "fresh cohort" = the state a restart / start-agent clear helper leaves
|
|
2283
|
+
/// behind, before any post-spawn tick has repopulated observations.
|
|
2284
|
+
/// Requires `spawned_at` present so the gate fires only for real
|
|
2285
|
+
/// restart/start cohorts; coordinator-only fixtures without a spawn
|
|
2286
|
+
/// boundary keep pre-0.5.32 pane fallback behavior (spine2 sync_health
|
|
2287
|
+
/// tests seed bare provider/window/pane_id and expect `last_output_at`
|
|
2288
|
+
/// to be recorded on the first delta).
|
|
2289
|
+
fn agent_is_fresh_cohort(agent: &Value) -> bool {
|
|
2290
|
+
let spawned_at_present = agent
|
|
2291
|
+
.get("spawned_at")
|
|
2292
|
+
.and_then(Value::as_str)
|
|
2293
|
+
.is_some_and(|s| !s.is_empty());
|
|
2294
|
+
if !spawned_at_present {
|
|
2295
|
+
return false;
|
|
2296
|
+
}
|
|
2297
|
+
const CLEARED_FIELDS: &[&str] = &[
|
|
2298
|
+
"activity",
|
|
2299
|
+
"worker_state",
|
|
2300
|
+
"last_output_at",
|
|
2301
|
+
"last_output_hash",
|
|
2302
|
+
"current_turn_message_id",
|
|
2303
|
+
"current_task_id",
|
|
2304
|
+
"task_id",
|
|
2305
|
+
];
|
|
2306
|
+
CLEARED_FIELDS.iter().all(|field| {
|
|
2307
|
+
agent
|
|
2308
|
+
.get(*field)
|
|
2309
|
+
.map(|value| value.is_null())
|
|
2310
|
+
.unwrap_or(true)
|
|
2311
|
+
})
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
/// 0.5.32 follow-up: is there a structural pane signal in `text`?
|
|
2315
|
+
/// True when `latest_prompt_signal` recognizes anything (idle prompt char,
|
|
2316
|
+
/// working spinner/keyword, or fake READY/WORKING marker). When true, the
|
|
2317
|
+
/// classifier will produce a definite non-`recent_provider_output` activity
|
|
2318
|
+
/// on its own, so the freshness gate must not suppress `last_output_at`.
|
|
2319
|
+
fn latest_pane_signal_is_structural(text: &str) -> bool {
|
|
2320
|
+
crate::messaging::helpers::latest_prompt_signal(text).is_some()
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2249
2323
|
/// Python approvals/status.py:68-72 — sha256 the scrollback, compare to the stored
|
|
2250
2324
|
/// `last_output_hash`; only a CHANGED digest counts as advanced output (and stores
|
|
2251
2325
|
/// the new digest).
|
|
@@ -163,11 +163,31 @@ pub(crate) fn latest_prompt_signal(scrollback: &str) -> Option<AgentActivity> {
|
|
|
163
163
|
}
|
|
164
164
|
let mut has_idle_prompt = false;
|
|
165
165
|
let mut has_live_working_indicator = false;
|
|
166
|
+
let mut has_fake_ready_structural = false;
|
|
166
167
|
for line in &active_region {
|
|
167
168
|
let lower = line.to_ascii_lowercase();
|
|
168
169
|
if line.contains('❯') || line.contains('›') {
|
|
169
170
|
has_idle_prompt = true;
|
|
170
171
|
}
|
|
172
|
+
// 0.5.34 (`0532-r1-real-fail-triage.md` §6/§7 + te msg_94957b9c55b0):
|
|
173
|
+
// fake provider owns explicit READY/WORKING markers (fake_worker.rs:47/59).
|
|
174
|
+
// - READY is a STRUCTURAL non-busy signal that suppresses the
|
|
175
|
+
// `recent_provider_output` false-busy on first post-restart capture,
|
|
176
|
+
// but must NOT resolve to Idle (unknown-never-idle discipline —
|
|
177
|
+
// post-restart READY is the fake worker's boot heartbeat, not proof
|
|
178
|
+
// of an idle prompt). Route it through Uncertain with a distinct
|
|
179
|
+
// rationale so callers can trace the source.
|
|
180
|
+
// - WORKING is a structural busy signal (parity with the codex
|
|
181
|
+
// `• Working (` composer indicator).
|
|
182
|
+
// Scope: literal `TEAM_AGENT_FAKE_*` tokens only — do NOT infer that
|
|
183
|
+
// arbitrary "ready" prose from real providers means either idle or
|
|
184
|
+
// non-busy.
|
|
185
|
+
if line.contains("TEAM_AGENT_FAKE_READY") {
|
|
186
|
+
has_fake_ready_structural = true;
|
|
187
|
+
}
|
|
188
|
+
if line.contains("TEAM_AGENT_FAKE_WORKING") {
|
|
189
|
+
has_live_working_indicator = true;
|
|
190
|
+
}
|
|
171
191
|
// codex live spinner shapes (provider/adapter.rs:875-876 markers):
|
|
172
192
|
// braille spinner, `• Working (`, `Thinking`; claude `✶`/`✢`/`✻`
|
|
173
193
|
// and Claude Code tool-progress verbs. We look for STRUCTURAL
|
|
@@ -195,6 +215,17 @@ pub(crate) fn latest_prompt_signal(scrollback: &str) -> Option<AgentActivity> {
|
|
|
195
215
|
if has_idle_prompt {
|
|
196
216
|
return Some(idle_activity());
|
|
197
217
|
}
|
|
218
|
+
// 0.5.34: fake READY is structural but not decisive. Return Uncertain
|
|
219
|
+
// so the classifier short-circuits (avoiding recent_provider_output
|
|
220
|
+
// false-busy) without asserting idle. `latest_pane_signal_is_structural`
|
|
221
|
+
// in coordinator/tick.rs treats `Some(_)` as structural.
|
|
222
|
+
if has_fake_ready_structural {
|
|
223
|
+
return Some(AgentActivity {
|
|
224
|
+
status: ActivityStatus::Uncertain,
|
|
225
|
+
confidence: 0.6,
|
|
226
|
+
rationale: "fake_ready_structural".to_string(),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
198
229
|
// No structural signal in the bottom region → caller (activity.rs:184)
|
|
199
230
|
// gets None and treats as no-decisive-signal → Uncertain (IRON LAW).
|
|
200
231
|
None
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-agent/installer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.34",
|
|
4
4
|
"description": "npx installer for Team Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codex",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"team-agent-installer": "npm/install.mjs"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@team-agent/cli-darwin-arm64": "0.5.
|
|
24
|
-
"@team-agent/cli-darwin-x64": "0.5.
|
|
25
|
-
"@team-agent/cli-linux-x64": "0.5.
|
|
23
|
+
"@team-agent/cli-darwin-arm64": "0.5.34",
|
|
24
|
+
"@team-agent/cli-darwin-x64": "0.5.34",
|
|
25
|
+
"@team-agent/cli-linux-x64": "0.5.34"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"postinstall": "node npm/bincheck.mjs",
|