agentic-runner 3.4.2__tar.gz → 3.5.0__tar.gz
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.
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/PKG-INFO +1 -1
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/__init__.py +1 -1
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/activities.py +92 -30
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/service.py +10 -1
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/testing/control_plane.py +2 -2
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/_runtime_support.py +23 -6
- agentic_runner-3.5.0/src/agentic_runner/workers/acp_runtime.py +938 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/agent_runtime.py +32 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/settings.py +7 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/.gitignore +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/LICENSE +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/README.md +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/pyproject.toml +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/attempts.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/auth_mode.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/build.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/callback.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/child_watcher.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/cli.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/cli_floor.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/config.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/credentials.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/device_login_activities.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/egress.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/harness_self_test.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/heartbeat_link.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/hooks.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/host_store.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/__init__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/git/__init__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/git/contracts.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/git/evidence.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/git/fake_workspace.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/git/workspace.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/github/__init__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/github/auth.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/github/fake_client.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/integrations/github/gh_client.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/lifecycle.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/llm_proxy.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/mcp.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/message_store.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/private_state.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/py.typed +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/recipient_key_secret.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/registration.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/runtime/__init__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/runtime/verifier_command.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/sealed_box.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/testing/__init__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/testing/__main__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/testing/plugin.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/testing/test_conformance.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/testing/workflow.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/tiny_http.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/triage_activities.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/user_sources.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/__init__.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/claude_runtime.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/codex_runtime.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/command_policy.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/contract_device_login.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/contract_isolation.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/fastapi_client.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/harness_outcome.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/harness_usage.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/mcp_config.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/skills.py +0 -0
- {agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workstation.py +0 -0
|
@@ -29,7 +29,7 @@ import shlex
|
|
|
29
29
|
import shutil
|
|
30
30
|
import tempfile
|
|
31
31
|
import time
|
|
32
|
-
from collections.abc import AsyncIterator, Awaitable, Callable, Mapping
|
|
32
|
+
from collections.abc import AsyncIterator, Awaitable, Callable, Mapping, Sequence
|
|
33
33
|
from dataclasses import asdict, dataclass, field, fields, replace
|
|
34
34
|
from datetime import UTC, datetime
|
|
35
35
|
from pathlib import Path
|
|
@@ -128,6 +128,8 @@ from agentic_runner.workers.agent_runtime import (
|
|
|
128
128
|
AuthMode,
|
|
129
129
|
DirectiveRequest,
|
|
130
130
|
DirectiveResult,
|
|
131
|
+
ModelUsage,
|
|
132
|
+
PermissionFallback,
|
|
131
133
|
ResumableAgentRuntime,
|
|
132
134
|
)
|
|
133
135
|
from agentic_runner.workers.contract_device_login import login_file_counts
|
|
@@ -588,6 +590,9 @@ class _RuntimeContextState:
|
|
|
588
590
|
# on the Profile's `command_policy` blob — the sandbox floor already lives there, and
|
|
589
591
|
# a ceiling is exactly a floor rule. None means the Runner's own default applies.
|
|
590
592
|
memory_limit_bytes: int | None = None
|
|
593
|
+
# PRD decision 12: what a runtime asked per command does when the command policy has
|
|
594
|
+
# no answer. Carried on the same `command_policy` blob as the ceiling above.
|
|
595
|
+
permission_fallback: PermissionFallback = PermissionFallback.DENY
|
|
591
596
|
# Pushed on change and applied on receipt (ADR-0011 §11, PRD issue 44): the evaluator
|
|
592
597
|
# is local, so a narrowing lands on the next verb this state is read for.
|
|
593
598
|
grant_snapshot: GrantSnapshot = UNENFORCED_SNAPSHOT
|
|
@@ -1296,6 +1301,56 @@ def _profile_memory_limit_bytes(command_policy: Mapping[str, object]) -> int | N
|
|
|
1296
1301
|
return None
|
|
1297
1302
|
|
|
1298
1303
|
|
|
1304
|
+
def _model_usage_reports(
|
|
1305
|
+
cli_kind: str, model_usage: Sequence[ModelUsage]
|
|
1306
|
+
) -> list[tuple[dict[str, Any], str | None]]:
|
|
1307
|
+
"""A harness's per-model usage in the shapes the harness usage route already prices.
|
|
1308
|
+
|
|
1309
|
+
Claude Code: one ``result`` message whose ``modelUsage`` names every model. Codex: one
|
|
1310
|
+
``turn.completed.usage`` per model, whose ``input_tokens`` includes the cached reads,
|
|
1311
|
+
with the model the harness itself named rather than the Agent's configured one.
|
|
1312
|
+
"""
|
|
1313
|
+
|
|
1314
|
+
if cli_kind == "claude_code":
|
|
1315
|
+
return [
|
|
1316
|
+
(
|
|
1317
|
+
{
|
|
1318
|
+
"type": "result",
|
|
1319
|
+
"modelUsage": {
|
|
1320
|
+
row.model: {
|
|
1321
|
+
"inputTokens": row.input_tokens,
|
|
1322
|
+
"outputTokens": row.output_tokens,
|
|
1323
|
+
"cacheReadInputTokens": row.cached_read_tokens,
|
|
1324
|
+
"cacheCreationInputTokens": row.cached_write_tokens,
|
|
1325
|
+
}
|
|
1326
|
+
for row in model_usage
|
|
1327
|
+
},
|
|
1328
|
+
},
|
|
1329
|
+
None,
|
|
1330
|
+
)
|
|
1331
|
+
]
|
|
1332
|
+
return [
|
|
1333
|
+
(
|
|
1334
|
+
{
|
|
1335
|
+
"input_tokens": row.input_tokens + row.cached_read_tokens,
|
|
1336
|
+
"cached_input_tokens": row.cached_read_tokens,
|
|
1337
|
+
"output_tokens": row.output_tokens,
|
|
1338
|
+
"reasoning_output_tokens": row.reasoning_output_tokens,
|
|
1339
|
+
},
|
|
1340
|
+
row.model,
|
|
1341
|
+
)
|
|
1342
|
+
for row in model_usage
|
|
1343
|
+
]
|
|
1344
|
+
|
|
1345
|
+
|
|
1346
|
+
def _profile_permission_fallback(command_policy: Mapping[str, object]) -> PermissionFallback:
|
|
1347
|
+
"""The Profile's `permission_fallback`; anything but exactly ``hold`` is ``deny``."""
|
|
1348
|
+
|
|
1349
|
+
if command_policy.get("permission_fallback") == PermissionFallback.HOLD.value:
|
|
1350
|
+
return PermissionFallback.HOLD
|
|
1351
|
+
return PermissionFallback.DENY
|
|
1352
|
+
|
|
1353
|
+
|
|
1299
1354
|
def _contract_workspace_path(
|
|
1300
1355
|
*,
|
|
1301
1356
|
workspace_root: Path,
|
|
@@ -1992,6 +2047,7 @@ class RunnerRalphActivities:
|
|
|
1992
2047
|
mcp_servers=attempt.mcp_servers,
|
|
1993
2048
|
egress_allow_list=attempt.egress_allow_list,
|
|
1994
2049
|
auth_mode=attempt.auth_mode,
|
|
2050
|
+
permission_fallback=runtime_state.permission_fallback,
|
|
1995
2051
|
prompt=attempt.skills_preamble
|
|
1996
2052
|
+ _directive_prompt(
|
|
1997
2053
|
completion_criteria=runtime_state.completion_criteria,
|
|
@@ -3363,6 +3419,7 @@ class RunnerRalphActivities:
|
|
|
3363
3419
|
cli_kind=runtime_context.cli_kind,
|
|
3364
3420
|
model=runtime_context.model,
|
|
3365
3421
|
memory_limit_bytes=_profile_memory_limit_bytes(runtime_context.command_policy),
|
|
3422
|
+
permission_fallback=_profile_permission_fallback(runtime_context.command_policy),
|
|
3366
3423
|
grant_snapshot=snapshot,
|
|
3367
3424
|
grant_snapshot_payload=snapshot_payload,
|
|
3368
3425
|
persona_slug=runtime_context.persona_slug,
|
|
@@ -4636,6 +4693,7 @@ class RunnerRalphActivities:
|
|
|
4636
4693
|
mcp_servers=attempt.mcp_servers,
|
|
4637
4694
|
egress_allow_list=attempt.egress_allow_list,
|
|
4638
4695
|
auth_mode=attempt.auth_mode,
|
|
4696
|
+
permission_fallback=state.permission_fallback,
|
|
4639
4697
|
prompt=attempt.skills_preamble
|
|
4640
4698
|
+ _learning_prompt(
|
|
4641
4699
|
request,
|
|
@@ -4896,6 +4954,7 @@ class RunnerRalphActivities:
|
|
|
4896
4954
|
mcp_servers=attempt.mcp_servers,
|
|
4897
4955
|
egress_allow_list=attempt.egress_allow_list,
|
|
4898
4956
|
auth_mode=attempt.auth_mode,
|
|
4957
|
+
permission_fallback=state.permission_fallback,
|
|
4899
4958
|
prompt=attempt.skills_preamble + await kind.prompt(state, prompt_notes),
|
|
4900
4959
|
base_branch=request.base_ref,
|
|
4901
4960
|
work_branch=state.work_branch,
|
|
@@ -5155,38 +5214,41 @@ class RunnerRalphActivities:
|
|
|
5155
5214
|
if auth_mode == AuthMode.API_KEY:
|
|
5156
5215
|
return
|
|
5157
5216
|
directive = directive_id(work_record_id=work_record_id, directive_number=directive_number)
|
|
5158
|
-
|
|
5217
|
+
reports: list[tuple[dict[str, Any], str | None]]
|
|
5218
|
+
if result.model_usage:
|
|
5219
|
+
reports = _model_usage_reports(runtime_state.cli_kind, result.model_usage)
|
|
5220
|
+
elif runtime_state.cli_kind == "claude_code":
|
|
5159
5221
|
usage_event = extract_claude_result(result.stdout)
|
|
5160
|
-
|
|
5222
|
+
reports = [(usage_event, None)] if usage_event else []
|
|
5161
5223
|
else:
|
|
5162
5224
|
usage_event = extract_codex_turn_usage(result.stdout)
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5225
|
+
reports = [(usage_event, runtime_state.model or None)] if usage_event else []
|
|
5226
|
+
for usage_event, model_name in reports:
|
|
5227
|
+
if runtime_state.cli_kind != "claude_code" and model_name is None:
|
|
5228
|
+
# The backend 422s a Codex harness report with no model
|
|
5229
|
+
# (`report_harness_usage` requires one to price it), and the `suppress`
|
|
5230
|
+
# below swallows that -- an Agent with no model configured would otherwise
|
|
5231
|
+
# lose this Usage Record with no trace.
|
|
5232
|
+
activity.logger.warning(
|
|
5233
|
+
"harness usage unreported: Agent %s has no model configured for a Codex "
|
|
5234
|
+
"harness Directive (work record %s)",
|
|
5235
|
+
runtime_state.agent_id,
|
|
5236
|
+
work_record_id,
|
|
5237
|
+
)
|
|
5238
|
+
with contextlib.suppress(Exception): # noqa: BLE001 - metering never fails a Directive
|
|
5239
|
+
await self._fastapi_client.report_harness_usage(
|
|
5240
|
+
{
|
|
5241
|
+
"work_record_id": work_record_id,
|
|
5242
|
+
"agent_id": runtime_state.agent_id,
|
|
5243
|
+
"contract_id": runtime_state.contract_id,
|
|
5244
|
+
"directive_id": directive,
|
|
5245
|
+
"runner_id": None,
|
|
5246
|
+
"runtime_kind": runtime_state.cli_kind,
|
|
5247
|
+
"provider_name": runtime_state.cli_kind,
|
|
5248
|
+
"model_name": model_name,
|
|
5249
|
+
"usage_event": usage_event,
|
|
5250
|
+
}
|
|
5251
|
+
)
|
|
5190
5252
|
|
|
5191
5253
|
async def _harness_hold(
|
|
5192
5254
|
self,
|
|
@@ -99,6 +99,7 @@ from agentic_runner.sealed_box import (
|
|
|
99
99
|
from agentic_runner.tiny_http import HttpRequest, read_request, write_json
|
|
100
100
|
from agentic_runner.triage_activities import RunnerTriageActivities
|
|
101
101
|
from agentic_runner.user_sources import ProxyTriage, UserSourcePoller
|
|
102
|
+
from agentic_runner.workers.acp_runtime import ACP_BRIDGES, AcpRuntime
|
|
102
103
|
from agentic_runner.workers.agent_runtime import AgentRuntime
|
|
103
104
|
from agentic_runner.workers.claude_runtime import ClaudeRuntime
|
|
104
105
|
from agentic_runner.workers.codex_runtime import CodexRuntime
|
|
@@ -388,10 +389,18 @@ def build_agent_runtimes(
|
|
|
388
389
|
picks from here by the Work Record's `cli_kind` (local-agents 01) -- there is no
|
|
389
390
|
process-wide choice. The same `clis` ride the heartbeat's attestation, so what this
|
|
390
391
|
Runner serves and what routing believes it serves are one list.
|
|
392
|
+
|
|
393
|
+
Which runtime serves a kind -- its pinned ACP bridge or the per-CLI one -- is this
|
|
394
|
+
Runner's setting (`ACP_CLI_KINDS`), never the payload's (local-agents 12 items 6, 7).
|
|
391
395
|
"""
|
|
392
396
|
|
|
397
|
+
acp_kinds = {kind.strip() for kind in settings.ACP_CLI_KINDS.split(",") if kind.strip()}
|
|
393
398
|
return {
|
|
394
|
-
cli.cli_kind:
|
|
399
|
+
cli.cli_kind: (
|
|
400
|
+
AcpRuntime(cli_kind=cli.cli_kind, settings=settings)
|
|
401
|
+
if cli.cli_kind in acp_kinds and cli.cli_kind in ACP_BRIDGES
|
|
402
|
+
else _RUNTIMES[cli.cli_kind](settings)
|
|
403
|
+
)
|
|
395
404
|
for cli in clis
|
|
396
405
|
if cli.meets_floor and cli.cli_kind in _RUNTIMES
|
|
397
406
|
}
|
|
@@ -37,7 +37,7 @@ from dataclasses import dataclass, field
|
|
|
37
37
|
from datetime import UTC, datetime, timedelta
|
|
38
38
|
from email.utils import formatdate
|
|
39
39
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
40
|
-
from typing import Any
|
|
40
|
+
from typing import Any
|
|
41
41
|
from uuid import UUID, uuid4
|
|
42
42
|
|
|
43
43
|
import httpx
|
|
@@ -166,7 +166,7 @@ class FakeControlPlane:
|
|
|
166
166
|
contracts_floor: str = contracts_version
|
|
167
167
|
contract_id: UUID = DEFAULT_CONTRACT_ID
|
|
168
168
|
agent_id: UUID = DEFAULT_AGENT_ID
|
|
169
|
-
cli_kind:
|
|
169
|
+
cli_kind: str = "codex_cli"
|
|
170
170
|
|
|
171
171
|
bootstraps: list[BootstrapRequest] = field(default_factory=list)
|
|
172
172
|
runner_ids: list[UUID] = field(default_factory=list)
|
{agentic_runner-3.4.2 → agentic_runner-3.5.0}/src/agentic_runner/workers/_runtime_support.py
RENAMED
|
@@ -42,7 +42,10 @@ from agentic_runner.workers.contract_isolation import DirectiveSandbox
|
|
|
42
42
|
# the funder anyway, or route it round the Profile's egress allow-list. The two Claude Code
|
|
43
43
|
# bearers are here for the last reason too: either would authenticate the harness on a
|
|
44
44
|
# credential the Runner never chose, around the proxy and the mode it decided
|
|
45
|
-
# (local-agents 04; research 01 §4 gap 6).
|
|
45
|
+
# (local-agents 04; research 01 §4 gap 6). The ACP bridges' control variables are here
|
|
46
|
+
# for the same reason (local-agents 12): each swaps the vendor binary, hands approvals
|
|
47
|
+
# back to the harness's own reviewer, authenticates the bridge, or re-enables the MCP
|
|
48
|
+
# filtering that drops a granted server.
|
|
46
49
|
RESERVED_DIRECTIVE_ENV: Final[frozenset[str]] = frozenset(
|
|
47
50
|
{
|
|
48
51
|
"HOME",
|
|
@@ -53,6 +56,20 @@ RESERVED_DIRECTIVE_ENV: Final[frozenset[str]] = frozenset(
|
|
|
53
56
|
"ANTHROPIC_API_KEY",
|
|
54
57
|
"ANTHROPIC_AUTH_TOKEN",
|
|
55
58
|
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
59
|
+
"CODEX_PATH",
|
|
60
|
+
"CODEX_CONFIG",
|
|
61
|
+
"CODEX_API_KEY",
|
|
62
|
+
"MODEL_PROVIDER",
|
|
63
|
+
"DEFAULT_AUTH_REQUEST",
|
|
64
|
+
"INITIAL_AGENT_MODE",
|
|
65
|
+
"NO_BROWSER",
|
|
66
|
+
"APP_SERVER_LOGS",
|
|
67
|
+
"DISABLE_MCP_CONFIG_FILTERING",
|
|
68
|
+
"CLAUDE_CODE_EXECUTABLE",
|
|
69
|
+
"CLAUDE_MODEL_CONFIG",
|
|
70
|
+
"CLAUDE_AGENT_LOGS",
|
|
71
|
+
"MAX_THINKING_TOKENS",
|
|
72
|
+
"ANTHROPIC_MODEL",
|
|
56
73
|
CALLBACK_SOCKET_ENV,
|
|
57
74
|
CALLBACK_TOKEN_ENV,
|
|
58
75
|
*PROXY_ENV_NAMES,
|
|
@@ -154,10 +171,10 @@ async def run_subprocess_exec(
|
|
|
154
171
|
timeout=timeout_seconds,
|
|
155
172
|
)
|
|
156
173
|
except (TimeoutError, asyncio.CancelledError):
|
|
157
|
-
await
|
|
174
|
+
await terminate_process_tree(process)
|
|
158
175
|
raise
|
|
159
176
|
except PriorAttemptAliveError:
|
|
160
|
-
await
|
|
177
|
+
await terminate_process_tree(process)
|
|
161
178
|
raise
|
|
162
179
|
|
|
163
180
|
return SubprocessResult(
|
|
@@ -240,7 +257,7 @@ async def _read_stream_limited(
|
|
|
240
257
|
return bytes(tail), total_bytes > limit_bytes
|
|
241
258
|
|
|
242
259
|
|
|
243
|
-
async def
|
|
260
|
+
async def terminate_process_tree(process: asyncio.subprocess.Process) -> None:
|
|
244
261
|
if process.returncode is not None:
|
|
245
262
|
return
|
|
246
263
|
with contextlib.suppress(ProcessLookupError, PermissionError):
|
|
@@ -379,7 +396,7 @@ async def run_subprocess_launch_and_detach(
|
|
|
379
396
|
raise RuntimeError(f"process failed to start: {error.__class__.__name__}") from None
|
|
380
397
|
|
|
381
398
|
if process.stdout is None:
|
|
382
|
-
await
|
|
399
|
+
await terminate_process_tree(process)
|
|
383
400
|
raise RuntimeError("process stdout stream was unavailable")
|
|
384
401
|
|
|
385
402
|
loop = asyncio.get_running_loop()
|
|
@@ -408,7 +425,7 @@ async def run_subprocess_launch_and_detach(
|
|
|
408
425
|
_detach(process)
|
|
409
426
|
return text
|
|
410
427
|
except BaseException:
|
|
411
|
-
await
|
|
428
|
+
await terminate_process_tree(process)
|
|
412
429
|
raise
|
|
413
430
|
|
|
414
431
|
|