agentshim 0.14.0__tar.gz → 0.15.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.
- {agentshim-0.14.0 → agentshim-0.15.0}/CHANGELOG.md +72 -0
- agentshim-0.15.0/LICENSE +21 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/PKG-INFO +7 -1
- {agentshim-0.14.0 → agentshim-0.15.0}/README.md +4 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/__init__.py +88 -1
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/agent.py +14 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/__init__.py +45 -0
- agentshim-0.15.0/agentshim/core/checkpoints.py +67 -0
- agentshim-0.15.0/agentshim/core/clock.py +60 -0
- agentshim-0.15.0/agentshim/core/conversation.py +103 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/errors.py +77 -7
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/events.py +23 -0
- agentshim-0.15.0/agentshim/core/ids.py +22 -0
- agentshim-0.15.0/agentshim/core/permissions.py +112 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/profile.py +26 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/schema.py +70 -26
- agentshim-0.15.0/agentshim/core/session_policy.py +604 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/turn.py +3 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/execution/__init__.py +21 -1
- agentshim-0.15.0/agentshim/execution/confinement.py +115 -0
- agentshim-0.15.0/agentshim/execution/docker.py +134 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/execution/executor.py +6 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/execution/host.py +142 -0
- agentshim-0.15.0/agentshim/execution/process.py +96 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/execution/transform.py +16 -0
- agentshim-0.15.0/agentshim/oneshot.py +194 -0
- agentshim-0.15.0/agentshim/providers/codex/app_server/__init__.py +49 -0
- agentshim-0.15.0/agentshim/providers/codex/app_server/_wire.py +351 -0
- agentshim-0.15.0/agentshim/providers/codex/app_server/protocol.py +5638 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/provider.py +7 -0
- agentshim-0.15.0/agentshim/runtime.py +187 -0
- agentshim-0.15.0/agentshim/session.py +505 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/testing/__init__.py +60 -1
- agentshim-0.15.0/agentshim/testing/clock.py +52 -0
- agentshim-0.15.0/agentshim/testing/confinement.py +52 -0
- agentshim-0.15.0/agentshim/testing/contracts.py +428 -0
- agentshim-0.15.0/agentshim/testing/conversation.py +250 -0
- agentshim-0.15.0/agentshim/testing/process.py +198 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/pyproject.toml +15 -1
- agentshim-0.15.0/tests/fixtures/codex_app_server/README.md +18 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/.gitignore +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/_files.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/env.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/home.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/mcp.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/pricing.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/provider.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/skills.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/stream.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/core/usage.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/events.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/failures.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/hooks/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/hooks/confine_reads.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/parser.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/provider.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/sandbox.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/scripted.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/claude/user_hooks.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/_toml.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/events.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/failures.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/mcp_scope.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/parser.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/rules.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/sandbox.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/scripted.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/codex/skills.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/copilot/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/copilot/events.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/copilot/parser.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/copilot/provider.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/copilot/scripted.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/gemini/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/gemini/events.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/gemini/parser.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/gemini/provider.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/gemini/scripted.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/opencode/__init__.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/opencode/events.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/opencode/parser.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/opencode/provider.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/providers/opencode/scripted.py +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/agentshim/py.typed +0 -0
- {agentshim-0.14.0 → agentshim-0.15.0}/tests/fixtures/codex/README.md +0 -0
|
@@ -1,5 +1,77 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.0 (2026-10-09)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Session tier. `Agent(provider, *, permissions, approvals, ...)` hands out
|
|
8
|
+
`Session`s: `prepare_turn(request, *, expect_conversation=None, pin=False) ->
|
|
9
|
+
TurnTicket` (the turn id exists before dispatch), `run(ticket, *, on_event=None)
|
|
10
|
+
-> Turn(result, continuity, turn_id, conversation_id)`, `interrupt()`,
|
|
11
|
+
`release()`, `adopt()`, `close()`. `Continuity` is `CONTINUED`, `RESET` or
|
|
12
|
+
`REPLACED`. Recovery is a pure `SessionPolicy` state machine: transient
|
|
13
|
+
retries on `RetryPolicy(delays)`, one fresh retry of a refused resume, a
|
|
14
|
+
backstop that forgets a resumed conversation after an unclassified failure,
|
|
15
|
+
renewal by `ProviderProfile.renewal` (`RenewalBudget`; Codex: 2 turns,
|
|
16
|
+
10M input tokens or 600 s), idle release, and checkpoints through
|
|
17
|
+
`CheckpointStore` / `InMemoryCheckpointStore` / `Checkpoint`.
|
|
18
|
+
- Transport tier. `Transport.open(ConversationSpec) -> Conversation` with
|
|
19
|
+
`turn`, `interrupt`, `close`; `OneShotTransport` wraps the one-shot path
|
|
20
|
+
(bypass permissions only) and behaves exactly like `AgentSession`.
|
|
21
|
+
`CliAgent.derive(model=, event_handler=)` copies a checked agent.
|
|
22
|
+
- Errors: `TurnFailedError(kind, detail)` (now the base of `CliExitError`),
|
|
23
|
+
`TurnTimeoutError` (now the base of `CliTimeoutError`), `ContinuityError`,
|
|
24
|
+
`SessionStateError`, `TurnCancelledError`. Session code catches the base
|
|
25
|
+
types only.
|
|
26
|
+
- Events `TurnInterrupted` and `ApprovalDenied(kind, detail)`;
|
|
27
|
+
`TurnResult.interrupted` (default `False`).
|
|
28
|
+
- Test doubles `FakeTransport`, `FakeConversation`, `FakeTurn`,
|
|
29
|
+
`FakeCheckpointStore`, `fake_profile`, `turn_failed`, `resume_refused`,
|
|
30
|
+
`turn_timeout`, and contract suites `TransportContract`,
|
|
31
|
+
`ConversationContract`, `CheckpointStoreContract`.
|
|
32
|
+
- Docs: [sessions](https://vic-lsh.github.io/agentshim/sessions/).
|
|
33
|
+
|
|
34
|
+
### Added (process layer)
|
|
35
|
+
|
|
36
|
+
- MIT license (`LICENSE`), declared in the package metadata.
|
|
37
|
+
- Long-lived processes: `CommandExecutor.spawn(SpawnRequest) -> Process` with a
|
|
38
|
+
pull-based output model (`StdoutLine`, `StderrLine`, `ProcessExited`),
|
|
39
|
+
implemented by `HostCommandExecutor` and `TransformingExecutor`.
|
|
40
|
+
`ProcessClosedError` reports a write to a closed or exited process.
|
|
41
|
+
- `Confinement` protocol, `confine(executor, confinement)` and
|
|
42
|
+
`DockerExecConfinement` (`docker exec` into a running container, with path
|
|
43
|
+
mapping and `reap()` of marked processes).
|
|
44
|
+
- `Clock`/`SystemClock`/`StopSignal` and `IdAllocator`/`RandomIds`.
|
|
45
|
+
- `NativeMode`, `NativePermissions`, `ApprovalPolicy` and
|
|
46
|
+
`ProviderProfile.native_permission_modes` (default `BYPASS` only).
|
|
47
|
+
- Test doubles `FakeProcess`, `FakePeer`, `EchoPeer`, `SilentPeer`,
|
|
48
|
+
`ReplayGates`, `GateMarker`, `FakeConfinement`, `FakeClock`, `SequentialIds`,
|
|
49
|
+
`FakeExecutor(peers=...)`, and contract suites `ProcessContract`,
|
|
50
|
+
`ConfinementContract`, `ClockContract` in `agentshim.testing.contracts`.
|
|
51
|
+
- Generated, typed Codex `app-server` protocol (`agentshim.providers.codex.app_server`):
|
|
52
|
+
frozen dataclasses for the requests, notifications, server requests and item
|
|
53
|
+
types a transport needs, tolerant `from_wire` for server messages, strict
|
|
54
|
+
`to_wire` for client messages, and `parse_server_message`. Regenerated from
|
|
55
|
+
the CLI's own JSON Schema by `scripts/generate_codex_protocol.py` (codex-cli
|
|
56
|
+
0.160.0); not exported from the top-level package yet.
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
60
|
+
- `DockerExecConfinement.reap()` raises the new `ReapError` unless the
|
|
61
|
+
container is gone or stopped, and the reap script fails when the container
|
|
62
|
+
lacks `tr`/`grep`, instead of reporting a clean sweep. `env` may not use the
|
|
63
|
+
reserved `AGENTSHIM_CONFINED` name.
|
|
64
|
+
- `Process.next_output(0)` on the host polls and returns already-queued output.
|
|
65
|
+
|
|
66
|
+
## 0.14.1 (2026-10-04)
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- Schema normalization preserves descriptions, titles and examples, including
|
|
71
|
+
annotations alongside `$ref`, so structured-output field guidance reaches
|
|
72
|
+
the model. Only metadata rejected by the selected dialect is removed.
|
|
73
|
+
- The open schema dialect accepts `oneOf` variants, as Claude does.
|
|
74
|
+
|
|
3
75
|
## 0.14.0 (2026-10-04)
|
|
4
76
|
|
|
5
77
|
Codex resumed turns report invocation usage. Additive.
|
agentshim-0.15.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vic Shihang Li
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentshim
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Provider-agnostic coding-agent CLI shims
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
5
7
|
Requires-Python: >=3.10
|
|
6
8
|
Requires-Dist: tomli>=2; python_full_version < '3.11'
|
|
7
9
|
Provides-Extra: test
|
|
@@ -248,3 +250,7 @@ uv publish # release
|
|
|
248
250
|
|
|
249
251
|
uv run --group docs mkdocs build --strict
|
|
250
252
|
```
|
|
253
|
+
|
|
254
|
+
## License
|
|
255
|
+
|
|
256
|
+
MIT. See [LICENSE](LICENSE).
|
|
@@ -11,21 +11,32 @@ from .core import (
|
|
|
11
11
|
AgentEvent,
|
|
12
12
|
AgentEventHandler,
|
|
13
13
|
AgentShimError,
|
|
14
|
+
ApprovalDenied,
|
|
15
|
+
ApprovalPolicy,
|
|
14
16
|
ArgvContext,
|
|
15
17
|
AssistantText,
|
|
18
|
+
Checkpoint,
|
|
19
|
+
CheckpointStore,
|
|
16
20
|
CliCheckError,
|
|
17
21
|
CliExitError,
|
|
18
22
|
CliNotFoundError,
|
|
19
23
|
CliTimeoutError,
|
|
24
|
+
Clock,
|
|
20
25
|
CompositeEventHandler,
|
|
21
26
|
ConfigFileInstallation,
|
|
22
27
|
ConfigScope,
|
|
23
28
|
ConsoleEventHandler,
|
|
24
29
|
ContextualStreamParser,
|
|
30
|
+
Continuity,
|
|
31
|
+
ContinuityError,
|
|
32
|
+
Conversation,
|
|
33
|
+
ConversationSpec,
|
|
25
34
|
EventHandlerBase,
|
|
26
35
|
FailureKind,
|
|
27
36
|
FlagsInstallation,
|
|
28
37
|
HttpMcpServer,
|
|
38
|
+
IdAllocator,
|
|
39
|
+
InMemoryCheckpointStore,
|
|
29
40
|
Lifecycle,
|
|
30
41
|
McpConfigError,
|
|
31
42
|
McpInstallation,
|
|
@@ -34,26 +45,37 @@ from .core import (
|
|
|
34
45
|
McpServer,
|
|
35
46
|
McpTransport,
|
|
36
47
|
ModelPricing,
|
|
48
|
+
NativeMode,
|
|
49
|
+
NativePermissions,
|
|
37
50
|
NoopInstallation,
|
|
38
51
|
NullEventHandler,
|
|
39
52
|
OutputSchema,
|
|
40
53
|
OutputSchemaStyle,
|
|
41
54
|
ParsedTurn,
|
|
42
55
|
ParserContext,
|
|
56
|
+
PolicyConfig,
|
|
43
57
|
PricingTable,
|
|
58
|
+
ProcessClosedError,
|
|
44
59
|
Provider,
|
|
45
60
|
ProviderCapabilityError,
|
|
46
61
|
ProviderError,
|
|
47
62
|
ProviderProfile,
|
|
48
63
|
ProviderUsage,
|
|
64
|
+
RandomIds,
|
|
49
65
|
RawOutput,
|
|
66
|
+
ReapError,
|
|
50
67
|
Reasoning,
|
|
68
|
+
RenewalBudget,
|
|
69
|
+
RetryPolicy,
|
|
51
70
|
RunFinished,
|
|
52
71
|
RunStarted,
|
|
53
72
|
SchemaDialect,
|
|
54
73
|
SchemaDialectError,
|
|
74
|
+
SessionPolicy,
|
|
55
75
|
SessionResumeError,
|
|
56
76
|
SessionStarted,
|
|
77
|
+
SessionState,
|
|
78
|
+
SessionStateError,
|
|
57
79
|
SkillInvoked,
|
|
58
80
|
SkillScope,
|
|
59
81
|
SkillsDiscovered,
|
|
@@ -62,14 +84,21 @@ from .core import (
|
|
|
62
84
|
SkillTracker,
|
|
63
85
|
Stderr,
|
|
64
86
|
StdioMcpServer,
|
|
87
|
+
StopSignal,
|
|
65
88
|
StreamParser,
|
|
89
|
+
SystemClock,
|
|
66
90
|
TokenUsage,
|
|
67
91
|
TokenWeights,
|
|
68
92
|
ToolCall,
|
|
69
93
|
ToolResult,
|
|
70
94
|
ToolTracker,
|
|
95
|
+
Transport,
|
|
96
|
+
TurnCancelledError,
|
|
97
|
+
TurnFailedError,
|
|
98
|
+
TurnInterrupted,
|
|
71
99
|
TurnRequest,
|
|
72
100
|
TurnResult,
|
|
101
|
+
TurnTimeoutError,
|
|
73
102
|
UsageReport,
|
|
74
103
|
compact_json,
|
|
75
104
|
compose_event_handlers,
|
|
@@ -92,27 +121,45 @@ from .execution import (
|
|
|
92
121
|
CommandRequest,
|
|
93
122
|
CommandResult,
|
|
94
123
|
CommandStreamSink,
|
|
124
|
+
Confinement,
|
|
125
|
+
DockerExecConfinement,
|
|
95
126
|
HostCommandExecutor,
|
|
127
|
+
HostProcess,
|
|
96
128
|
NullSink,
|
|
129
|
+
Process,
|
|
130
|
+
ProcessExited,
|
|
131
|
+
ProcessOutput,
|
|
132
|
+
SpawnRequest,
|
|
133
|
+
StderrLine,
|
|
134
|
+
StdoutLine,
|
|
97
135
|
TransformingExecutor,
|
|
136
|
+
confine,
|
|
98
137
|
)
|
|
138
|
+
from .oneshot import OneShotTransport
|
|
99
139
|
from .providers import get_provider, provider_names
|
|
100
140
|
from .providers.claude import ClaudeHook, ClaudeProvider, SandboxConfig
|
|
101
141
|
from .providers.codex import CodexProvider, CodexSandboxConfig
|
|
102
142
|
from .providers.copilot import CopilotProvider
|
|
103
143
|
from .providers.gemini import GeminiProvider
|
|
104
144
|
from .providers.opencode import OpencodeProvider
|
|
145
|
+
from .runtime import Agent
|
|
146
|
+
from .session import Session, Turn, TurnTicket, map_mcp_servers
|
|
105
147
|
|
|
106
|
-
__version__ = "0.
|
|
148
|
+
__version__ = "0.15.0"
|
|
107
149
|
|
|
108
150
|
__all__ = [
|
|
151
|
+
"Agent",
|
|
109
152
|
"AgentEvent",
|
|
110
153
|
"AgentEventHandler",
|
|
111
154
|
"AgentSession",
|
|
112
155
|
"AgentShimError",
|
|
156
|
+
"ApprovalDenied",
|
|
157
|
+
"ApprovalPolicy",
|
|
113
158
|
"ArgvContext",
|
|
114
159
|
"AssistantText",
|
|
115
160
|
"CallbackCommandStreamSink",
|
|
161
|
+
"Checkpoint",
|
|
162
|
+
"CheckpointStore",
|
|
116
163
|
"ClaudeHook",
|
|
117
164
|
"ClaudeProvider",
|
|
118
165
|
"CliAgent",
|
|
@@ -120,6 +167,7 @@ __all__ = [
|
|
|
120
167
|
"CliExitError",
|
|
121
168
|
"CliNotFoundError",
|
|
122
169
|
"CliTimeoutError",
|
|
170
|
+
"Clock",
|
|
123
171
|
"CodexProvider",
|
|
124
172
|
"CodexSandboxConfig",
|
|
125
173
|
"CommandExecutor",
|
|
@@ -130,15 +178,24 @@ __all__ = [
|
|
|
130
178
|
"CompositeEventHandler",
|
|
131
179
|
"ConfigFileInstallation",
|
|
132
180
|
"ConfigScope",
|
|
181
|
+
"Confinement",
|
|
133
182
|
"ConsoleEventHandler",
|
|
134
183
|
"ContextualStreamParser",
|
|
184
|
+
"Continuity",
|
|
185
|
+
"ContinuityError",
|
|
186
|
+
"Conversation",
|
|
187
|
+
"ConversationSpec",
|
|
135
188
|
"CopilotProvider",
|
|
189
|
+
"DockerExecConfinement",
|
|
136
190
|
"EventHandlerBase",
|
|
137
191
|
"FailureKind",
|
|
138
192
|
"FlagsInstallation",
|
|
139
193
|
"GeminiProvider",
|
|
140
194
|
"HostCommandExecutor",
|
|
195
|
+
"HostProcess",
|
|
141
196
|
"HttpMcpServer",
|
|
197
|
+
"IdAllocator",
|
|
198
|
+
"InMemoryCheckpointStore",
|
|
142
199
|
"Lifecycle",
|
|
143
200
|
"McpConfigError",
|
|
144
201
|
"McpInstallation",
|
|
@@ -147,56 +204,86 @@ __all__ = [
|
|
|
147
204
|
"McpServer",
|
|
148
205
|
"McpTransport",
|
|
149
206
|
"ModelPricing",
|
|
207
|
+
"NativeMode",
|
|
208
|
+
"NativePermissions",
|
|
150
209
|
"NoopInstallation",
|
|
151
210
|
"NullEventHandler",
|
|
152
211
|
"NullSink",
|
|
212
|
+
"OneShotTransport",
|
|
153
213
|
"OpencodeProvider",
|
|
154
214
|
"OutputSchema",
|
|
155
215
|
"OutputSchemaStyle",
|
|
156
216
|
"ParsedTurn",
|
|
157
217
|
"ParserContext",
|
|
218
|
+
"PolicyConfig",
|
|
158
219
|
"PricingTable",
|
|
220
|
+
"Process",
|
|
221
|
+
"ProcessClosedError",
|
|
222
|
+
"ProcessExited",
|
|
223
|
+
"ProcessOutput",
|
|
159
224
|
"Provider",
|
|
160
225
|
"ProviderCapabilityError",
|
|
161
226
|
"ProviderError",
|
|
162
227
|
"ProviderProfile",
|
|
163
228
|
"ProviderUsage",
|
|
229
|
+
"RandomIds",
|
|
164
230
|
"RawOutput",
|
|
231
|
+
"ReapError",
|
|
165
232
|
"Reasoning",
|
|
233
|
+
"RenewalBudget",
|
|
234
|
+
"RetryPolicy",
|
|
166
235
|
"RunFinished",
|
|
167
236
|
"RunStarted",
|
|
168
237
|
"SandboxConfig",
|
|
169
238
|
"SchemaDialect",
|
|
170
239
|
"SchemaDialectError",
|
|
240
|
+
"Session",
|
|
241
|
+
"SessionPolicy",
|
|
171
242
|
"SessionResumeError",
|
|
172
243
|
"SessionStarted",
|
|
244
|
+
"SessionState",
|
|
245
|
+
"SessionStateError",
|
|
173
246
|
"SkillInvoked",
|
|
174
247
|
"SkillScope",
|
|
175
248
|
"SkillSignal",
|
|
176
249
|
"SkillSummary",
|
|
177
250
|
"SkillTracker",
|
|
178
251
|
"SkillsDiscovered",
|
|
252
|
+
"SpawnRequest",
|
|
179
253
|
"Stderr",
|
|
254
|
+
"StderrLine",
|
|
180
255
|
"StdioMcpServer",
|
|
256
|
+
"StdoutLine",
|
|
257
|
+
"StopSignal",
|
|
181
258
|
"StreamParser",
|
|
259
|
+
"SystemClock",
|
|
182
260
|
"TokenUsage",
|
|
183
261
|
"TokenWeights",
|
|
184
262
|
"ToolCall",
|
|
185
263
|
"ToolResult",
|
|
186
264
|
"ToolTracker",
|
|
187
265
|
"TransformingExecutor",
|
|
266
|
+
"Transport",
|
|
267
|
+
"Turn",
|
|
268
|
+
"TurnCancelledError",
|
|
269
|
+
"TurnFailedError",
|
|
270
|
+
"TurnInterrupted",
|
|
188
271
|
"TurnRequest",
|
|
189
272
|
"TurnResult",
|
|
273
|
+
"TurnTicket",
|
|
274
|
+
"TurnTimeoutError",
|
|
190
275
|
"UsageReport",
|
|
191
276
|
"__version__",
|
|
192
277
|
"compact_json",
|
|
193
278
|
"compose_event_handlers",
|
|
279
|
+
"confine",
|
|
194
280
|
"cost_usd",
|
|
195
281
|
"default_pricing",
|
|
196
282
|
"dialect_problems",
|
|
197
283
|
"get_provider",
|
|
198
284
|
"install_config_file",
|
|
199
285
|
"interactive_env",
|
|
286
|
+
"map_mcp_servers",
|
|
200
287
|
"materialize",
|
|
201
288
|
"normalize",
|
|
202
289
|
"normalized_usage",
|
|
@@ -7,6 +7,7 @@ neither of them has to know that agents exist.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import copy
|
|
10
11
|
import posixpath
|
|
11
12
|
import threading
|
|
12
13
|
import time
|
|
@@ -116,6 +117,19 @@ class CliAgent:
|
|
|
116
117
|
self.executor.check_binary(self.binary_path, self.env, timeout=check_timeout)
|
|
117
118
|
self.log(f"{self.profile.display_name} ready at {self.binary_path}")
|
|
118
119
|
|
|
120
|
+
def derive(self, *, model: str | None, event_handler: AgentEventHandler) -> CliAgent:
|
|
121
|
+
"""Return a copy that uses *model* and reports events to *event_handler*.
|
|
122
|
+
|
|
123
|
+
The binary lookup and health check are not repeated: the copy shares
|
|
124
|
+
the executor, environment and resolved binary of this agent. That is
|
|
125
|
+
what lets one checked install serve many conversations, each with its
|
|
126
|
+
own event routing.
|
|
127
|
+
"""
|
|
128
|
+
clone = copy.copy(self)
|
|
129
|
+
clone.model = model
|
|
130
|
+
clone.event_handler = event_handler
|
|
131
|
+
return clone
|
|
132
|
+
|
|
119
133
|
def start_session( # noqa: PLR0913 - one keyword per independent session option
|
|
120
134
|
self,
|
|
121
135
|
*,
|
|
@@ -7,6 +7,9 @@ this package may not do.
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
from .checkpoints import Checkpoint, CheckpointStore, InMemoryCheckpointStore
|
|
11
|
+
from .clock import Clock, StopSignal, SystemClock
|
|
12
|
+
from .conversation import Conversation, ConversationSpec, Transport
|
|
10
13
|
from .env import interactive_env
|
|
11
14
|
from .errors import (
|
|
12
15
|
AgentShimError,
|
|
@@ -14,15 +17,23 @@ from .errors import (
|
|
|
14
17
|
CliExitError,
|
|
15
18
|
CliNotFoundError,
|
|
16
19
|
CliTimeoutError,
|
|
20
|
+
ContinuityError,
|
|
17
21
|
FailureKind,
|
|
18
22
|
McpConfigError,
|
|
23
|
+
ProcessClosedError,
|
|
19
24
|
ProviderCapabilityError,
|
|
25
|
+
ReapError,
|
|
20
26
|
SchemaDialectError,
|
|
21
27
|
SessionResumeError,
|
|
28
|
+
SessionStateError,
|
|
29
|
+
TurnCancelledError,
|
|
30
|
+
TurnFailedError,
|
|
31
|
+
TurnTimeoutError,
|
|
22
32
|
)
|
|
23
33
|
from .events import (
|
|
24
34
|
AgentEvent,
|
|
25
35
|
AgentEventHandler,
|
|
36
|
+
ApprovalDenied,
|
|
26
37
|
AssistantText,
|
|
27
38
|
CompositeEventHandler,
|
|
28
39
|
ConsoleEventHandler,
|
|
@@ -40,10 +51,12 @@ from .events import (
|
|
|
40
51
|
Stderr,
|
|
41
52
|
ToolCall,
|
|
42
53
|
ToolResult,
|
|
54
|
+
TurnInterrupted,
|
|
43
55
|
UsageReport,
|
|
44
56
|
compose_event_handlers,
|
|
45
57
|
)
|
|
46
58
|
from .home import prepare_config_home
|
|
59
|
+
from .ids import IdAllocator, RandomIds
|
|
47
60
|
from .mcp import (
|
|
48
61
|
ConfigFileInstallation,
|
|
49
62
|
FlagsInstallation,
|
|
@@ -54,6 +67,7 @@ from .mcp import (
|
|
|
54
67
|
StdioMcpServer,
|
|
55
68
|
install_config_file,
|
|
56
69
|
)
|
|
70
|
+
from .permissions import ApprovalPolicy, NativeMode, NativePermissions
|
|
57
71
|
from .pricing import ModelPricing, PricingTable, cost_usd, default_pricing, price_for
|
|
58
72
|
from .profile import (
|
|
59
73
|
ConfigScope,
|
|
@@ -61,6 +75,7 @@ from .profile import (
|
|
|
61
75
|
McpScope,
|
|
62
76
|
OutputSchemaStyle,
|
|
63
77
|
ProviderProfile,
|
|
78
|
+
RenewalBudget,
|
|
64
79
|
SchemaDialect,
|
|
65
80
|
SkillScope,
|
|
66
81
|
SkillSignal,
|
|
@@ -75,6 +90,7 @@ from .provider import (
|
|
|
75
90
|
StreamParser,
|
|
76
91
|
)
|
|
77
92
|
from .schema import compact_json, dialect_problems, materialize, normalize
|
|
93
|
+
from .session_policy import Continuity, PolicyConfig, RetryPolicy, SessionPolicy, SessionState
|
|
78
94
|
from .skills import SkillSummary, SkillTracker
|
|
79
95
|
from .stream import ToolTracker, parse_json_object
|
|
80
96
|
from .turn import OutputSchema, TurnRequest, TurnResult
|
|
@@ -84,21 +100,32 @@ __all__ = [
|
|
|
84
100
|
"AgentEvent",
|
|
85
101
|
"AgentEventHandler",
|
|
86
102
|
"AgentShimError",
|
|
103
|
+
"ApprovalDenied",
|
|
104
|
+
"ApprovalPolicy",
|
|
87
105
|
"ArgvContext",
|
|
88
106
|
"AssistantText",
|
|
107
|
+
"Checkpoint",
|
|
108
|
+
"CheckpointStore",
|
|
89
109
|
"CliCheckError",
|
|
90
110
|
"CliExitError",
|
|
91
111
|
"CliNotFoundError",
|
|
92
112
|
"CliTimeoutError",
|
|
113
|
+
"Clock",
|
|
93
114
|
"CompositeEventHandler",
|
|
94
115
|
"ConfigFileInstallation",
|
|
95
116
|
"ConfigScope",
|
|
96
117
|
"ConsoleEventHandler",
|
|
97
118
|
"ContextualStreamParser",
|
|
119
|
+
"Continuity",
|
|
120
|
+
"ContinuityError",
|
|
121
|
+
"Conversation",
|
|
122
|
+
"ConversationSpec",
|
|
98
123
|
"EventHandlerBase",
|
|
99
124
|
"FailureKind",
|
|
100
125
|
"FlagsInstallation",
|
|
101
126
|
"HttpMcpServer",
|
|
127
|
+
"IdAllocator",
|
|
128
|
+
"InMemoryCheckpointStore",
|
|
102
129
|
"Lifecycle",
|
|
103
130
|
"McpConfigError",
|
|
104
131
|
"McpInstallation",
|
|
@@ -107,26 +134,37 @@ __all__ = [
|
|
|
107
134
|
"McpServer",
|
|
108
135
|
"McpTransport",
|
|
109
136
|
"ModelPricing",
|
|
137
|
+
"NativeMode",
|
|
138
|
+
"NativePermissions",
|
|
110
139
|
"NoopInstallation",
|
|
111
140
|
"NullEventHandler",
|
|
112
141
|
"OutputSchema",
|
|
113
142
|
"OutputSchemaStyle",
|
|
114
143
|
"ParsedTurn",
|
|
115
144
|
"ParserContext",
|
|
145
|
+
"PolicyConfig",
|
|
116
146
|
"PricingTable",
|
|
147
|
+
"ProcessClosedError",
|
|
117
148
|
"Provider",
|
|
118
149
|
"ProviderCapabilityError",
|
|
119
150
|
"ProviderError",
|
|
120
151
|
"ProviderProfile",
|
|
121
152
|
"ProviderUsage",
|
|
153
|
+
"RandomIds",
|
|
122
154
|
"RawOutput",
|
|
155
|
+
"ReapError",
|
|
123
156
|
"Reasoning",
|
|
157
|
+
"RenewalBudget",
|
|
158
|
+
"RetryPolicy",
|
|
124
159
|
"RunFinished",
|
|
125
160
|
"RunStarted",
|
|
126
161
|
"SchemaDialect",
|
|
127
162
|
"SchemaDialectError",
|
|
163
|
+
"SessionPolicy",
|
|
128
164
|
"SessionResumeError",
|
|
129
165
|
"SessionStarted",
|
|
166
|
+
"SessionState",
|
|
167
|
+
"SessionStateError",
|
|
130
168
|
"SkillInvoked",
|
|
131
169
|
"SkillScope",
|
|
132
170
|
"SkillSignal",
|
|
@@ -135,14 +173,21 @@ __all__ = [
|
|
|
135
173
|
"SkillsDiscovered",
|
|
136
174
|
"Stderr",
|
|
137
175
|
"StdioMcpServer",
|
|
176
|
+
"StopSignal",
|
|
138
177
|
"StreamParser",
|
|
178
|
+
"SystemClock",
|
|
139
179
|
"TokenUsage",
|
|
140
180
|
"TokenWeights",
|
|
141
181
|
"ToolCall",
|
|
142
182
|
"ToolResult",
|
|
143
183
|
"ToolTracker",
|
|
184
|
+
"Transport",
|
|
185
|
+
"TurnCancelledError",
|
|
186
|
+
"TurnFailedError",
|
|
187
|
+
"TurnInterrupted",
|
|
144
188
|
"TurnRequest",
|
|
145
189
|
"TurnResult",
|
|
190
|
+
"TurnTimeoutError",
|
|
146
191
|
"UsageReport",
|
|
147
192
|
"compact_json",
|
|
148
193
|
"compose_event_handlers",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Durable record of which provider conversation a session was in.
|
|
2
|
+
|
|
3
|
+
A checkpoint is what a restarted process needs to continue a conversation: the
|
|
4
|
+
provider's id for it and the usage baseline of its last report. Where it is
|
|
5
|
+
stored is the caller's business, so the store is a protocol.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import threading
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from typing import TYPE_CHECKING, Protocol
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from .usage import ProviderUsage
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class Checkpoint:
|
|
20
|
+
"""A provider conversation a later process can resume.
|
|
21
|
+
|
|
22
|
+
``usage`` is the conversation's most recent report, kept so a provider
|
|
23
|
+
whose usage is cumulative can still tell the next turn's increment.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
conversation_id: str
|
|
27
|
+
usage: ProviderUsage | None = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CheckpointStore(Protocol):
|
|
31
|
+
"""Where a session keeps its checkpoint between processes."""
|
|
32
|
+
|
|
33
|
+
def load(self, key: str) -> Checkpoint | None:
|
|
34
|
+
"""Return the checkpoint saved under *key*, or ``None``."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def save(self, key: str, checkpoint: Checkpoint) -> None:
|
|
38
|
+
"""Replace whatever is saved under *key*."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def clear(self, key: str) -> None:
|
|
42
|
+
"""Forget *key*; clearing a key that holds nothing is not an error."""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class InMemoryCheckpointStore:
|
|
47
|
+
"""A ``CheckpointStore`` that lives and dies with the process."""
|
|
48
|
+
|
|
49
|
+
def __init__(self) -> None:
|
|
50
|
+
"""Start empty."""
|
|
51
|
+
self._lock = threading.Lock()
|
|
52
|
+
self._items: dict[str, Checkpoint] = {}
|
|
53
|
+
|
|
54
|
+
def load(self, key: str) -> Checkpoint | None:
|
|
55
|
+
"""Return the checkpoint saved under *key*, or ``None``."""
|
|
56
|
+
with self._lock:
|
|
57
|
+
return self._items.get(key)
|
|
58
|
+
|
|
59
|
+
def save(self, key: str, checkpoint: Checkpoint) -> None:
|
|
60
|
+
"""Replace whatever is saved under *key*."""
|
|
61
|
+
with self._lock:
|
|
62
|
+
self._items[key] = checkpoint
|
|
63
|
+
|
|
64
|
+
def clear(self, key: str) -> None:
|
|
65
|
+
"""Forget *key*."""
|
|
66
|
+
with self._lock:
|
|
67
|
+
self._items.pop(key, None)
|