agentshim 0.15.4__tar.gz → 0.15.6__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.
- {agentshim-0.15.4 → agentshim-0.15.6}/CHANGELOG.md +25 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/PKG-INFO +1 -1
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/__init__.py +1 -1
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/session_policy.py +15 -4
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/transport.py +12 -8
- {agentshim-0.15.4 → agentshim-0.15.6}/pyproject.toml +1 -1
- {agentshim-0.15.4 → agentshim-0.15.6}/.gitignore +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/LICENSE +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/README.md +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/agent.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/_files.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/checkpoints.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/clock.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/conversation.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/env.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/errors.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/events.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/home.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/ids.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/mcp.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/permissions.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/pricing.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/profile.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/provider.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/schema.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/skills.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/status.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/stream.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/turn.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/core/usage.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/confinement.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/docker.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/executor.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/host.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/process.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/execution/transform.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/oneshot.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/events.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/failures.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/hooks/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/hooks/confine_reads.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/parser.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/provider.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/rate_limits.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/sandbox.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/scripted.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/stream_argv.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/stream_transport.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/claude/user_hooks.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/_toml.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/_wire.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/approvals.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/channel.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/errors.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/items.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/mcp.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/permissions.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/profile.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/protocol.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/rate_limits.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/app_server/usage.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/events.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/failures.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/mcp_scope.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/parser.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/provider.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/rules.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/sandbox.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/scripted.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/codex/skills.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/copilot/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/copilot/events.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/copilot/parser.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/copilot/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/copilot/provider.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/copilot/scripted.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/gemini/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/gemini/events.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/gemini/parser.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/gemini/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/gemini/provider.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/gemini/scripted.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/opencode/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/opencode/events.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/opencode/parser.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/opencode/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/opencode/provider.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/providers/opencode/scripted.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/py.typed +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/runtime.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/session.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/__init__.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/claude_stream.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/clock.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/codex_app_server.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/confinement.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/contracts.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/conversation.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/probe.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/agentshim/testing/process.py +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/tests/fixtures/claude_stream/README.md +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/tests/fixtures/codex/README.md +0 -0
- {agentshim-0.15.4 → agentshim-0.15.6}/tests/fixtures/codex_app_server/README.md +0 -0
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.6 (2026-10-09)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- A Codex app-server that ignores the interrupt of a timed-out turn is stopped, and the
|
|
8
|
+
next turn replaces it by resuming the thread, as the Claude stream transport already
|
|
9
|
+
does. Before, the conversation was written off: the next turn failed with "the previous
|
|
10
|
+
turn did not stop" and the session then forgot the thread, so one hung turn cost two
|
|
11
|
+
failed turns and the conversation's history.
|
|
12
|
+
|
|
13
|
+
## 0.15.5 (2026-10-09)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- A conversation whose provider thread was lost under it is no longer wedged. When a
|
|
18
|
+
turn that did not itself resume (its conversation was opened during the turn)
|
|
19
|
+
failed with `SessionResumeError` (the Codex app-server died mid-turn and its thread
|
|
20
|
+
could not be resumed in the new process), the session kept the dead conversation
|
|
21
|
+
open and every later turn raised the same error. The session now closes and forgets
|
|
22
|
+
it, still without replaying the turn that may have run.
|
|
23
|
+
- A Codex app-server that never acknowledges a turn (silent or wedged) is stopped when
|
|
24
|
+
the turn times out, so the next turn replaces it by resuming the thread instead of
|
|
25
|
+
timing out against the same process forever. (The Claude stream transport already
|
|
26
|
+
killed a process that ignored its interrupt.)
|
|
27
|
+
|
|
3
28
|
## 0.15.4 (2026-10-09)
|
|
4
29
|
|
|
5
30
|
### Added
|
|
@@ -12,7 +12,9 @@ What the policy decides, per turn:
|
|
|
12
12
|
* A ``TRANSIENT`` failure is retried in place after each delay of the
|
|
13
13
|
``RetryPolicy``; the waits end early when the shell reports a stop.
|
|
14
14
|
* A refused resume replaces the conversation once, unless the turn must not
|
|
15
|
-
lose its conversation (``strict`` or ``pinned``).
|
|
15
|
+
lose its conversation (``strict`` or ``pinned``). A refusal during a turn that
|
|
16
|
+
did not itself resume (the conversation was lost under it) forgets the
|
|
17
|
+
conversation without replaying the turn.
|
|
16
18
|
* An unclassified failure of a resumed turn forgets the conversation.
|
|
17
19
|
* After a successful turn that exhausts the provider's ``RenewalBudget`` the
|
|
18
20
|
conversation is retired.
|
|
@@ -531,13 +533,22 @@ class SessionPolicy:
|
|
|
531
533
|
if event.outcome is Outcome.TRANSIENT:
|
|
532
534
|
return self._retry_transient(state, turn, event)
|
|
533
535
|
if event.outcome is Outcome.RESUME_REFUSED:
|
|
534
|
-
|
|
535
|
-
return _replace_conversation(state, turn)
|
|
536
|
-
return _give_up(state, event.now)
|
|
536
|
+
return self._on_resume_refused(state, turn, event)
|
|
537
537
|
if event.outcome is Outcome.OTHER and turn.resumed and not turn.keeps_conversation:
|
|
538
538
|
return _forget_conversation(state, event.now)
|
|
539
539
|
return _give_up(state, event.now)
|
|
540
540
|
|
|
541
|
+
def _on_resume_refused(self, state: SessionState, turn: TurnState, event: Failed) -> Step:
|
|
542
|
+
if turn.keeps_conversation:
|
|
543
|
+
return _give_up(state, event.now)
|
|
544
|
+
if turn.resumed:
|
|
545
|
+
return _replace_conversation(state, turn)
|
|
546
|
+
# The turn began in a conversation it opened itself and the provider
|
|
547
|
+
# then lost it (a process died mid-turn and its thread could not be
|
|
548
|
+
# resumed). The turn may have run, so it is not replayed, but the
|
|
549
|
+
# conversation is gone: holding it would refuse every later turn.
|
|
550
|
+
return _forget_conversation(state, event.now)
|
|
551
|
+
|
|
541
552
|
def _retry_transient(self, state: SessionState, turn: TurnState, event: Failed) -> Step:
|
|
542
553
|
delays = self.config.retry.delays
|
|
543
554
|
if turn.retries >= len(delays):
|
|
@@ -153,7 +153,7 @@ class CodexAppServerTransport:
|
|
|
153
153
|
The timeouts are in seconds on *clock*: ``startup_timeout`` bounds the
|
|
154
154
|
handshake, ``close_timeout`` each step of shutting the process down, and
|
|
155
155
|
``interrupt_grace`` how long an interrupted or timed-out turn may take to
|
|
156
|
-
wind down before
|
|
156
|
+
wind down before its process is stopped.
|
|
157
157
|
"""
|
|
158
158
|
|
|
159
159
|
# Each argument is an independent documented option of the public constructor.
|
|
@@ -369,7 +369,6 @@ class _Conversation:
|
|
|
369
369
|
self._skills: SkillTracker | None = None
|
|
370
370
|
self._failed_servers: dict[str, str] = {}
|
|
371
371
|
self._deferred_failure: TurnFailedError | None = None
|
|
372
|
-
self._stuck = False
|
|
373
372
|
|
|
374
373
|
# -- Conversation protocol
|
|
375
374
|
|
|
@@ -559,9 +558,6 @@ class _Conversation:
|
|
|
559
558
|
if self._running:
|
|
560
559
|
msg = "a turn is already running in this conversation"
|
|
561
560
|
raise SessionStateError(msg)
|
|
562
|
-
if self._stuck:
|
|
563
|
-
msg = "the previous turn did not stop, so this conversation cannot take another"
|
|
564
|
-
raise TurnFailedError(msg, kind=FailureKind.OTHER, detail=msg)
|
|
565
561
|
self._running = True
|
|
566
562
|
self._turn_id = None
|
|
567
563
|
self._interrupt_asked = False
|
|
@@ -596,6 +592,12 @@ class _Conversation:
|
|
|
596
592
|
self._handle(self._channel.read(deadline), turn)
|
|
597
593
|
except Expired:
|
|
598
594
|
self._wind_down(turn)
|
|
595
|
+
if turn.turn_id is None:
|
|
596
|
+
# The server never acknowledged the turn, so it is silent or
|
|
597
|
+
# wedged and no interrupt can reach it. Stop it: the next turn
|
|
598
|
+
# replaces the process by resuming the thread, where holding
|
|
599
|
+
# it would time out every later turn too.
|
|
600
|
+
_stop(self._channel.process, self._timeouts.close)
|
|
599
601
|
raise TurnTimeoutError(request.timeout or 0.0) from None
|
|
600
602
|
except Gone as gone:
|
|
601
603
|
raise self._gone_error(gone) from None
|
|
@@ -853,8 +855,10 @@ class _Conversation:
|
|
|
853
855
|
def _wind_down(self, turn: _Turn) -> None:
|
|
854
856
|
"""Stop a turn that is being abandoned and wait, within bounds, for the server to agree.
|
|
855
857
|
|
|
856
|
-
If the server never reports the turn over, the
|
|
857
|
-
|
|
858
|
+
If the server never reports the turn over, the process is stopped:
|
|
859
|
+
another ``turn/start`` on it could collide with the one still running.
|
|
860
|
+
The next turn replaces it by resuming the thread, as the Claude stream
|
|
861
|
+
transport does for a process that ignores its interrupt.
|
|
858
862
|
"""
|
|
859
863
|
if turn.turn_id is None or turn.completed is not None:
|
|
860
864
|
return
|
|
@@ -865,7 +869,7 @@ class _Conversation:
|
|
|
865
869
|
while turn.completed is None:
|
|
866
870
|
self._handle(self._channel.read(deadline), turn)
|
|
867
871
|
except (Expired, Gone, AgentShimError):
|
|
868
|
-
self.
|
|
872
|
+
_stop(self._channel.process, self._timeouts.close)
|
|
869
873
|
|
|
870
874
|
# -- finishing
|
|
871
875
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|