context_watch: masoara si contextul fiecarui subagent
Pe SubagentStop hook-ul primeste agent_transcript_path - transcriptul separat al subagentului care tocmai s-a oprit. -Subagent il citeste pe acela in loc de transcriptul sesiunii, cu praguri mai joase (150k/200k), si spune orchestratorului sa nu mai dea sarcini agentului respectiv. Acopera gaura cunoscuta: subagentii nu-si simt singuri pragul. -Json ambaleaza mesajul in hookSpecificOutput/additionalContext. Garda stop_hook_active taie a doua declansare a aceluiasi ciclu de stop, care producea reinjectarea in bucla. Probat pe input real de hook capturat: 40k citit din transcriptul unui subagent, tacere sub prag, tacere la stop_hook_active=true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZwtBDjGbAWvy7TmcNVxDC
This commit is contained in:
@@ -17,9 +17,17 @@ param(
|
||||
[switch]$Intotdeauna,
|
||||
[switch]$Stdout, # UserPromptSubmit: mesajul se scrie pe stdout si se iese cu 0
|
||||
[switch]$OSinguraData, # PostToolUse: o singura alerta per prag atins, nu la fiecare tool
|
||||
[string]$StareFile # optional: fisier de stare cu antet datat, actualizat la prag atins
|
||||
[string]$StareFile, # optional: fisier de stare cu antet datat, actualizat la prag atins
|
||||
[switch]$Subagent, # SubagentStop: masoara agent_transcript_path, nu transcriptul sesiunii
|
||||
[switch]$Json # emite {"hookSpecificOutput":{...,"additionalContext":...}} pe stdout
|
||||
)
|
||||
|
||||
# subagentii nu-si simt pragul singuri: se taie sarcina mai devreme decat la sesiunea principala
|
||||
if ($Subagent) {
|
||||
if (-not $PSBoundParameters.ContainsKey('Prag')) { $Prag = 150000 }
|
||||
if (-not $PSBoundParameters.ContainsKey('PragMax')) { $PragMax = 200000 }
|
||||
}
|
||||
|
||||
function Scrie-AntetStare([string]$cale, [int]$tokeni, [string]$nivel) {
|
||||
$antet = "<!-- context_watch: $(Get-Date -Format 'dd.MM.yyyy HH:mm') | tokeni: $tokeni | nivel: $nivel -->"
|
||||
if (Test-Path $cale) {
|
||||
@@ -35,12 +43,26 @@ function Scrie-AntetStare([string]$cale, [int]$tokeni, [string]$nivel) {
|
||||
Set-Content -Path $cale -Value $continut -Encoding UTF8
|
||||
}
|
||||
|
||||
$agentEtich = ''
|
||||
if (-not $TranscriptPath) {
|
||||
$stdin = [Console]::In.ReadToEnd()
|
||||
if ($stdin) {
|
||||
try { $TranscriptPath = (ConvertFrom-Json $stdin).transcript_path } catch { }
|
||||
try {
|
||||
$h = ConvertFrom-Json $stdin
|
||||
# a doua declansare a aceluiasi ciclu de stop: taci, altfel hook-ul se reinjecteaza in bucla
|
||||
if ($h.stop_hook_active -eq $true) { exit 0 }
|
||||
# pe SubagentStop hook-ul primeste si transcriptul separat al subagentului
|
||||
if ($Subagent -and $h.agent_transcript_path) {
|
||||
$TranscriptPath = $h.agent_transcript_path
|
||||
$agentEtich = $(if ($h.agent_type) { $h.agent_type } else { $h.agent_id })
|
||||
} else {
|
||||
$TranscriptPath = $h.transcript_path
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
}
|
||||
# fara transcript de subagent nu avem ce masura; nu cadem pe sesiunea principala
|
||||
if ($Subagent -and -not $TranscriptPath) { exit 0 }
|
||||
# la primul mesaj al unei sesiuni noi transcriptul inca nu e creat: fara fallback, ca sa nu raporteze alta sesiune
|
||||
if ($TranscriptPath -and -not (Test-Path $TranscriptPath)) { exit 0 }
|
||||
if (-not $TranscriptPath) {
|
||||
@@ -73,7 +95,19 @@ $k = [Math]::Round($total / 1000)
|
||||
|
||||
$mesaj = ''
|
||||
$nivel = ''
|
||||
if ($total -ge $PragMax) {
|
||||
if ($Subagent) {
|
||||
$cine = $(if ($agentEtich) { "Subagentul '$agentEtich'" } else { 'Subagentul care tocmai s-a oprit' })
|
||||
if ($total -ge $PragMax) {
|
||||
$nivel = 'max'
|
||||
$mesaj = "$cine a consumat ${k}k context - PESTE limita de $([Math]::Round($PragMax/1000))k. " +
|
||||
"NU-i mai da nicio sarcina. Cere-i handoff pe disc daca a ramas ceva neconsemnat, " +
|
||||
"apoi opreste-l si spawneaza unul proaspat pentru blocul urmator."
|
||||
} elseif ($total -ge $Prag) {
|
||||
$nivel = 'avertisment'
|
||||
$mesaj = "$cine a consumat ${k}k context. Sarcina urmatoare se taie sau se da unui agent proaspat - " +
|
||||
"subagentii nu-si simt singuri pragul. Verifica intai ca si-a scris livrabilul pe disc."
|
||||
}
|
||||
} elseif ($total -ge $PragMax) {
|
||||
$nivel = 'max'
|
||||
$mesaj = "CONTEXT ${k}k - PESTE LIMITA de $([Math]::Round($PragMax/1000))k. REGULA ZERO, predare OBLIGATORIE ACUM: " +
|
||||
"(1) opreste lucrul, nu incepe nimic nou, adu editarile in curs la o stare consistenta pe disc; " +
|
||||
@@ -97,6 +131,12 @@ if ($mesaj) {
|
||||
if (Test-Path $marcaj) { exit 0 }
|
||||
New-Item -ItemType File -Path $marcaj -Force | Out-Null
|
||||
}
|
||||
if ($Json) {
|
||||
$ev = $(if ($Subagent) { 'SubagentStop' } else { 'PostToolUse' })
|
||||
$o = @{ hookSpecificOutput = @{ hookEventName = $ev; additionalContext = $mesaj } }
|
||||
Write-Output ($o | ConvertTo-Json -Compress -Depth 4)
|
||||
exit 0
|
||||
}
|
||||
if ($Stdout) { Write-Output $mesaj; exit 0 }
|
||||
[Console]::Error.WriteLine($mesaj)
|
||||
exit 2
|
||||
|
||||
Reference in New Issue
Block a user