회기 연속성과 멀티 케이스 계약을 영속화

This commit is contained in:
Yun Chan 2026-09-01 11:45:16 +09:00
parent be08c0b573
commit 72353ecd82
26 changed files with 2170 additions and 127 deletions

View file

@ -698,28 +698,29 @@ async def _stream_agy(
raise ProviderError("Agy CLI를 찾을 수 없습니다.")
model, effort = await _resolve_selection(req, "agy_cli")
prompt = _cli_prompt(system_prompt, user_payload)
if os.name == "nt" and len(prompt) > 24_000:
raise ProviderError(
"Agy CLI 프롬프트가 Windows 명령줄 안전 한도(24,000자)를 초과했습니다."
)
args = [binary, "--model", model, "--sandbox"]
if effort:
args += ["--effort", effort]
args += [
"--print-timeout",
f"{int(CLI_TIMEOUT_SECONDS)}s",
# 긴 deep-loop 축어록을 Windows argv에 싣지 않는다. Agy의 공식 stream-json
# 입력 계약은 prompt를 stdin의 단일 user 이벤트로 받으므로 명령줄 길이 한계를
# 피하면서 전체 마스킹 근거를 그대로 보존한다.
"--input-format",
"stream-json",
"--output-format",
"stream-json",
"--print",
prompt,
]
proc = await asyncio.create_subprocess_exec(
*args,
cwd=str(_cli_runtime_cwd()),
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
env=_cli_subprocess_env(),
)
assert proc.stdin is not None
assert proc.stdout is not None
assert proc.stderr is not None
stderr_task = asyncio.create_task(proc.stderr.read())
@ -730,6 +731,30 @@ async def _stream_agy(
cached_input_tokens = 0
result_status = ""
try:
# 공식 protocol: 한 줄에 한 user event. 마지막 turn 뒤 stdin을 닫아도 CLI는
# terminal result를 내보낸 뒤 종료한다. stdin 거절은 child와 stderr를 정리한 뒤
# provider 오류로 승격해 프로세스를 남기지 않는다.
try:
proc.stdin.write(
(
json.dumps(
{"event": "user", "message": {"content": prompt}},
ensure_ascii=False,
)
+ "\n"
).encode("utf-8")
)
await proc.stdin.drain()
except (BrokenPipeError, ConnectionResetError) as exc:
raise ProviderError("Agy CLI가 stdin 평가 입력을 수락하지 않았습니다.") from exc
finally:
if not proc.stdin.is_closing():
proc.stdin.close()
try:
await proc.stdin.wait_closed()
except (BrokenPipeError, ConnectionResetError):
# 이미 종료된 CLI가 close 직후 EOF를 끊어도 finally가 child를 회수한다.
pass
async with asyncio.timeout(CLI_TIMEOUT_SECONDS):
while True:
raw = await proc.stdout.readline()