slopper 0.1.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.
Files changed (54) hide show
  1. slopper-0.1.0/PKG-INFO +115 -0
  2. slopper-0.1.0/README.md +91 -0
  3. slopper-0.1.0/pyproject.toml +61 -0
  4. slopper-0.1.0/setup.cfg +4 -0
  5. slopper-0.1.0/slopper.egg-info/PKG-INFO +115 -0
  6. slopper-0.1.0/slopper.egg-info/SOURCES.txt +52 -0
  7. slopper-0.1.0/slopper.egg-info/dependency_links.txt +1 -0
  8. slopper-0.1.0/slopper.egg-info/entry_points.txt +4 -0
  9. slopper-0.1.0/slopper.egg-info/requires.txt +7 -0
  10. slopper-0.1.0/slopper.egg-info/top_level.txt +1 -0
  11. slopper-0.1.0/slopper_env/__init__.py +0 -0
  12. slopper-0.1.0/slopper_env/__main__.py +7 -0
  13. slopper-0.1.0/slopper_env/adapters/__init__.py +0 -0
  14. slopper-0.1.0/slopper_env/adapters/base.py +44 -0
  15. slopper-0.1.0/slopper_env/adapters/claude_code.py +184 -0
  16. slopper-0.1.0/slopper_env/adapters/codex.py +220 -0
  17. slopper-0.1.0/slopper_env/agent.py +159 -0
  18. slopper-0.1.0/slopper_env/backends/__init__.py +21 -0
  19. slopper-0.1.0/slopper_env/backends/base.py +75 -0
  20. slopper-0.1.0/slopper_env/backends/claude.py +208 -0
  21. slopper-0.1.0/slopper_env/backends/codex.py +451 -0
  22. slopper-0.1.0/slopper_env/cli.py +317 -0
  23. slopper-0.1.0/slopper_env/config.py +98 -0
  24. slopper-0.1.0/slopper_env/constants.py +18 -0
  25. slopper-0.1.0/slopper_env/devtools.py +208 -0
  26. slopper-0.1.0/slopper_env/doc.py +1446 -0
  27. slopper-0.1.0/slopper_env/folio_mcp.py +78 -0
  28. slopper-0.1.0/slopper_env/identity.py +82 -0
  29. slopper-0.1.0/slopper_env/ids.py +28 -0
  30. slopper-0.1.0/slopper_env/lock.py +61 -0
  31. slopper-0.1.0/slopper_env/loop.py +227 -0
  32. slopper-0.1.0/slopper_env/main.py +348 -0
  33. slopper-0.1.0/slopper_env/models.py +138 -0
  34. slopper-0.1.0/slopper_env/ordering.py +128 -0
  35. slopper-0.1.0/slopper_env/registration.py +135 -0
  36. slopper-0.1.0/slopper_env/runner.py +207 -0
  37. slopper-0.1.0/slopper_env/service.py +273 -0
  38. slopper-0.1.0/slopper_env/sync.py +231 -0
  39. slopper-0.1.0/slopper_env/workspace.py +307 -0
  40. slopper-0.1.0/tests/test_agent.py +239 -0
  41. slopper-0.1.0/tests/test_agent_config.py +107 -0
  42. slopper-0.1.0/tests/test_agent_resume.py +121 -0
  43. slopper-0.1.0/tests/test_claude_adapter.py +163 -0
  44. slopper-0.1.0/tests/test_codex.py +245 -0
  45. slopper-0.1.0/tests/test_doc.py +609 -0
  46. slopper-0.1.0/tests/test_folio_mcp.py +60 -0
  47. slopper-0.1.0/tests/test_identity.py +93 -0
  48. slopper-0.1.0/tests/test_loop.py +375 -0
  49. slopper-0.1.0/tests/test_ordering.py +112 -0
  50. slopper-0.1.0/tests/test_packaging.py +99 -0
  51. slopper-0.1.0/tests/test_runner.py +240 -0
  52. slopper-0.1.0/tests/test_sync.py +104 -0
  53. slopper-0.1.0/tests/test_tool_decision.py +243 -0
  54. slopper-0.1.0/tests/test_workspace.py +318 -0
slopper-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: slopper
3
+ Version: 0.1.0
4
+ Summary: Run Claude Code and Codex agent sessions for Folio on your own machine.
5
+ Keywords: agents,claude-code,codex,folio
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Environment :: Console
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: MacOS
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: pycrdt>=0.12.0
18
+ Requires-Dist: claude-agent-sdk<0.3,>=0.2.152
19
+ Requires-Dist: openai-codex-cli-bin<0.157,>=0.156
20
+ Requires-Dist: httpx>=0.28.0
21
+ Requires-Dist: websockets>=13.0
22
+ Requires-Dist: pydantic-settings>=2.2.0
23
+ Requires-Dist: python-json-logger>=2.0.0
24
+
25
+ # slopper
26
+
27
+ Run Folio agent sessions — Claude Code or Codex — on your own machine.
28
+
29
+ `slopper` is the environment a Folio session runs in. It registers with your
30
+ Folio server, picks up the sessions assigned to it, checks out the project's
31
+ repositories into a workspace per session, and runs the agent there. Every
32
+ tool call that needs your approval shows up in the session in Folio; the
33
+ agent waits until you answer.
34
+
35
+ Runs on **macOS** and **Linux**, Python 3.11+. Both agent CLIs are installed
36
+ with the package.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ uv tool install slopper # or: pipx install slopper
42
+ ```
43
+
44
+ ## Set up
45
+
46
+ 1. **Sign the agents in**, once per machine, as the user the service will run as:
47
+
48
+ ```bash
49
+ claude login # Claude Code
50
+ codex login # Codex (optional)
51
+ ```
52
+
53
+ 2. **Point it at Folio** with an API key from Folio's settings:
54
+
55
+ ```bash
56
+ slopper configure --server https://api.folio.example.com --token <api-key>
57
+ ```
58
+
59
+ This writes `~/.slopper/config.toml`, readable only by you.
60
+
61
+ 3. **Check everything**:
62
+
63
+ ```bash
64
+ slopper doctor
65
+ ```
66
+
67
+ 4. **Run it as a service** — started now, at every login, and again if it crashes:
68
+
69
+ ```bash
70
+ slopper service install
71
+ ```
72
+
73
+ - **macOS:** a LaunchAgent (`~/Library/LaunchAgents/slopper.plist`) in your
74
+ login session, so it can use the Claude login in your Keychain.
75
+ Logs: `~/Library/Logs/slopper/slopper.log`.
76
+ - **Linux:** a systemd user unit (`~/.config/systemd/user/slopper.service`).
77
+ Logs: `journalctl --user -u slopper`. To keep it running while you are
78
+ logged out (a headless machine): `sudo loginctl enable-linger $USER`.
79
+
80
+ ## Commands
81
+
82
+ | Command | |
83
+ |---|---|
84
+ | `slopper configure` | Write `~/.slopper/config.toml` (`--server`, `--token`, `--env-id`, `--workspace`) |
85
+ | `slopper doctor` | Check the config, the server, the key, git, and both agents' logins |
86
+ | `slopper service install` · `uninstall` | Install or remove the service |
87
+ | `slopper service start` · `stop` · `restart` · `status` | Control it |
88
+ | `slopper service logs [-f]` | Show (or follow) its log |
89
+ | `slopper run` | Run in the foreground instead of as a service |
90
+
91
+ Only one environment runs per user account; a second `slopper run` refuses to
92
+ start while the service is running.
93
+
94
+ ## Upgrade
95
+
96
+ ```bash
97
+ uv tool upgrade slopper && slopper service restart
98
+ ```
99
+
100
+ The service runs the installed interpreter by path, so it picks up the new
101
+ version on restart — there is nothing to reinstall.
102
+
103
+ ## Configuration
104
+
105
+ `~/.slopper/config.toml` holds the settings; environment variables of the
106
+ same name override it.
107
+
108
+ | Setting | Default | |
109
+ |---|---|---|
110
+ | `SLOPPER_SERVER_URL` | `http://localhost:8000` | Folio API |
111
+ | `SLOPPER_TOKEN` | — | API key this environment registers with |
112
+ | `SLOPPER_ENV_ID` | generated once, kept in `~/.slopper/identity.toml` | This machine's name in Folio. Must stay stable: sessions are bound to it |
113
+ | `SLOPPER_WORKSPACE_ROOT` | `~/.slopper/workspaces` | One directory per session |
114
+ | `SLOPPER_CLONE_SINCE` | `1.month.ago` | How much git history a checkout carries; empty for all |
115
+ | `SLOPPER_CODEX_BIN` | the bundled one | A different `codex` binary |
@@ -0,0 +1,91 @@
1
+ # slopper
2
+
3
+ Run Folio agent sessions — Claude Code or Codex — on your own machine.
4
+
5
+ `slopper` is the environment a Folio session runs in. It registers with your
6
+ Folio server, picks up the sessions assigned to it, checks out the project's
7
+ repositories into a workspace per session, and runs the agent there. Every
8
+ tool call that needs your approval shows up in the session in Folio; the
9
+ agent waits until you answer.
10
+
11
+ Runs on **macOS** and **Linux**, Python 3.11+. Both agent CLIs are installed
12
+ with the package.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ uv tool install slopper # or: pipx install slopper
18
+ ```
19
+
20
+ ## Set up
21
+
22
+ 1. **Sign the agents in**, once per machine, as the user the service will run as:
23
+
24
+ ```bash
25
+ claude login # Claude Code
26
+ codex login # Codex (optional)
27
+ ```
28
+
29
+ 2. **Point it at Folio** with an API key from Folio's settings:
30
+
31
+ ```bash
32
+ slopper configure --server https://api.folio.example.com --token <api-key>
33
+ ```
34
+
35
+ This writes `~/.slopper/config.toml`, readable only by you.
36
+
37
+ 3. **Check everything**:
38
+
39
+ ```bash
40
+ slopper doctor
41
+ ```
42
+
43
+ 4. **Run it as a service** — started now, at every login, and again if it crashes:
44
+
45
+ ```bash
46
+ slopper service install
47
+ ```
48
+
49
+ - **macOS:** a LaunchAgent (`~/Library/LaunchAgents/slopper.plist`) in your
50
+ login session, so it can use the Claude login in your Keychain.
51
+ Logs: `~/Library/Logs/slopper/slopper.log`.
52
+ - **Linux:** a systemd user unit (`~/.config/systemd/user/slopper.service`).
53
+ Logs: `journalctl --user -u slopper`. To keep it running while you are
54
+ logged out (a headless machine): `sudo loginctl enable-linger $USER`.
55
+
56
+ ## Commands
57
+
58
+ | Command | |
59
+ |---|---|
60
+ | `slopper configure` | Write `~/.slopper/config.toml` (`--server`, `--token`, `--env-id`, `--workspace`) |
61
+ | `slopper doctor` | Check the config, the server, the key, git, and both agents' logins |
62
+ | `slopper service install` · `uninstall` | Install or remove the service |
63
+ | `slopper service start` · `stop` · `restart` · `status` | Control it |
64
+ | `slopper service logs [-f]` | Show (or follow) its log |
65
+ | `slopper run` | Run in the foreground instead of as a service |
66
+
67
+ Only one environment runs per user account; a second `slopper run` refuses to
68
+ start while the service is running.
69
+
70
+ ## Upgrade
71
+
72
+ ```bash
73
+ uv tool upgrade slopper && slopper service restart
74
+ ```
75
+
76
+ The service runs the installed interpreter by path, so it picks up the new
77
+ version on restart — there is nothing to reinstall.
78
+
79
+ ## Configuration
80
+
81
+ `~/.slopper/config.toml` holds the settings; environment variables of the
82
+ same name override it.
83
+
84
+ | Setting | Default | |
85
+ |---|---|---|
86
+ | `SLOPPER_SERVER_URL` | `http://localhost:8000` | Folio API |
87
+ | `SLOPPER_TOKEN` | — | API key this environment registers with |
88
+ | `SLOPPER_ENV_ID` | generated once, kept in `~/.slopper/identity.toml` | This machine's name in Folio. Must stay stable: sessions are bound to it |
89
+ | `SLOPPER_WORKSPACE_ROOT` | `~/.slopper/workspaces` | One directory per session |
90
+ | `SLOPPER_CLONE_SINCE` | `1.month.ago` | How much git history a checkout carries; empty for all |
91
+ | `SLOPPER_CODEX_BIN` | the bundled one | A different `codex` binary |
@@ -0,0 +1,61 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "slopper"
7
+ version = "0.1.0"
8
+ description = "Run Claude Code and Codex agent sessions for Folio on your own machine."
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ keywords = ["agents", "claude-code", "codex", "folio"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Environment :: Console",
15
+ "Intended Audience :: Developers",
16
+ "Operating System :: MacOS",
17
+ "Operating System :: POSIX :: Linux",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ ]
23
+ dependencies = [
24
+ "pycrdt>=0.12.0",
25
+ # Pinned to a range, not a floor. A floor alone let two machines install
26
+ # from the same wheel and get agents two minor versions apart -- one on
27
+ # CLI 2.1.30, the other on 2.1.259 -- which made behaviour on one
28
+ # impossible to reason about from the source of the other. 0.2.x is also
29
+ # the floor for PreToolUse "defer", which the approval flow depends on.
30
+ "claude-agent-sdk>=0.2.152,<0.3",
31
+ # Bundles the codex binary for Codex sessions. Pinned to one minor: the
32
+ # app-server protocol the Codex backend speaks is marked experimental,
33
+ # and a drift between machines would be as confusing as the CLI drift
34
+ # above.
35
+ "openai-codex-cli-bin>=0.156,<0.157",
36
+ "httpx>=0.28.0",
37
+ "websockets>=13.0",
38
+ # TomlConfigSettingsSource, for ~/.slopper/config.toml.
39
+ "pydantic-settings>=2.2.0",
40
+ "python-json-logger>=2.0.0",
41
+ ]
42
+
43
+ [dependency-groups]
44
+ dev = ["pytest>=8.0.0", "pytest-asyncio>=0.24.0"]
45
+
46
+ [project.scripts]
47
+ slopper = "slopper_env.cli:main"
48
+ # The old name, kept for existing scripts: same flags, straight into `run`.
49
+ slopper-env = "slopper_env.cli:run_alias"
50
+ slopper-dev = "slopper_env.devtools:cli"
51
+
52
+ # Named explicitly. Auto-discovery treated the old "src" directory as the
53
+ # src-layout convention and flattened its modules to the top level of the
54
+ # wheel -- installing "config", "main", "doc" and "sync" into site-packages,
55
+ # where they shadow anything else by those names, while the console scripts
56
+ # still pointed at a "src" package the wheel no longer contained.
57
+ [tool.setuptools]
58
+ packages = ["slopper_env", "slopper_env.adapters", "slopper_env.backends"]
59
+
60
+ [tool.pytest.ini_options]
61
+ asyncio_mode = "auto"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.4
2
+ Name: slopper
3
+ Version: 0.1.0
4
+ Summary: Run Claude Code and Codex agent sessions for Folio on your own machine.
5
+ Keywords: agents,claude-code,codex,folio
6
+ Classifier: Development Status :: 3 - Alpha
7
+ Classifier: Environment :: Console
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Operating System :: MacOS
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: pycrdt>=0.12.0
18
+ Requires-Dist: claude-agent-sdk<0.3,>=0.2.152
19
+ Requires-Dist: openai-codex-cli-bin<0.157,>=0.156
20
+ Requires-Dist: httpx>=0.28.0
21
+ Requires-Dist: websockets>=13.0
22
+ Requires-Dist: pydantic-settings>=2.2.0
23
+ Requires-Dist: python-json-logger>=2.0.0
24
+
25
+ # slopper
26
+
27
+ Run Folio agent sessions — Claude Code or Codex — on your own machine.
28
+
29
+ `slopper` is the environment a Folio session runs in. It registers with your
30
+ Folio server, picks up the sessions assigned to it, checks out the project's
31
+ repositories into a workspace per session, and runs the agent there. Every
32
+ tool call that needs your approval shows up in the session in Folio; the
33
+ agent waits until you answer.
34
+
35
+ Runs on **macOS** and **Linux**, Python 3.11+. Both agent CLIs are installed
36
+ with the package.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ uv tool install slopper # or: pipx install slopper
42
+ ```
43
+
44
+ ## Set up
45
+
46
+ 1. **Sign the agents in**, once per machine, as the user the service will run as:
47
+
48
+ ```bash
49
+ claude login # Claude Code
50
+ codex login # Codex (optional)
51
+ ```
52
+
53
+ 2. **Point it at Folio** with an API key from Folio's settings:
54
+
55
+ ```bash
56
+ slopper configure --server https://api.folio.example.com --token <api-key>
57
+ ```
58
+
59
+ This writes `~/.slopper/config.toml`, readable only by you.
60
+
61
+ 3. **Check everything**:
62
+
63
+ ```bash
64
+ slopper doctor
65
+ ```
66
+
67
+ 4. **Run it as a service** — started now, at every login, and again if it crashes:
68
+
69
+ ```bash
70
+ slopper service install
71
+ ```
72
+
73
+ - **macOS:** a LaunchAgent (`~/Library/LaunchAgents/slopper.plist`) in your
74
+ login session, so it can use the Claude login in your Keychain.
75
+ Logs: `~/Library/Logs/slopper/slopper.log`.
76
+ - **Linux:** a systemd user unit (`~/.config/systemd/user/slopper.service`).
77
+ Logs: `journalctl --user -u slopper`. To keep it running while you are
78
+ logged out (a headless machine): `sudo loginctl enable-linger $USER`.
79
+
80
+ ## Commands
81
+
82
+ | Command | |
83
+ |---|---|
84
+ | `slopper configure` | Write `~/.slopper/config.toml` (`--server`, `--token`, `--env-id`, `--workspace`) |
85
+ | `slopper doctor` | Check the config, the server, the key, git, and both agents' logins |
86
+ | `slopper service install` · `uninstall` | Install or remove the service |
87
+ | `slopper service start` · `stop` · `restart` · `status` | Control it |
88
+ | `slopper service logs [-f]` | Show (or follow) its log |
89
+ | `slopper run` | Run in the foreground instead of as a service |
90
+
91
+ Only one environment runs per user account; a second `slopper run` refuses to
92
+ start while the service is running.
93
+
94
+ ## Upgrade
95
+
96
+ ```bash
97
+ uv tool upgrade slopper && slopper service restart
98
+ ```
99
+
100
+ The service runs the installed interpreter by path, so it picks up the new
101
+ version on restart — there is nothing to reinstall.
102
+
103
+ ## Configuration
104
+
105
+ `~/.slopper/config.toml` holds the settings; environment variables of the
106
+ same name override it.
107
+
108
+ | Setting | Default | |
109
+ |---|---|---|
110
+ | `SLOPPER_SERVER_URL` | `http://localhost:8000` | Folio API |
111
+ | `SLOPPER_TOKEN` | — | API key this environment registers with |
112
+ | `SLOPPER_ENV_ID` | generated once, kept in `~/.slopper/identity.toml` | This machine's name in Folio. Must stay stable: sessions are bound to it |
113
+ | `SLOPPER_WORKSPACE_ROOT` | `~/.slopper/workspaces` | One directory per session |
114
+ | `SLOPPER_CLONE_SINCE` | `1.month.ago` | How much git history a checkout carries; empty for all |
115
+ | `SLOPPER_CODEX_BIN` | the bundled one | A different `codex` binary |
@@ -0,0 +1,52 @@
1
+ README.md
2
+ pyproject.toml
3
+ slopper.egg-info/PKG-INFO
4
+ slopper.egg-info/SOURCES.txt
5
+ slopper.egg-info/dependency_links.txt
6
+ slopper.egg-info/entry_points.txt
7
+ slopper.egg-info/requires.txt
8
+ slopper.egg-info/top_level.txt
9
+ slopper_env/__init__.py
10
+ slopper_env/__main__.py
11
+ slopper_env/agent.py
12
+ slopper_env/cli.py
13
+ slopper_env/config.py
14
+ slopper_env/constants.py
15
+ slopper_env/devtools.py
16
+ slopper_env/doc.py
17
+ slopper_env/folio_mcp.py
18
+ slopper_env/identity.py
19
+ slopper_env/ids.py
20
+ slopper_env/lock.py
21
+ slopper_env/loop.py
22
+ slopper_env/main.py
23
+ slopper_env/models.py
24
+ slopper_env/ordering.py
25
+ slopper_env/registration.py
26
+ slopper_env/runner.py
27
+ slopper_env/service.py
28
+ slopper_env/sync.py
29
+ slopper_env/workspace.py
30
+ slopper_env/adapters/__init__.py
31
+ slopper_env/adapters/base.py
32
+ slopper_env/adapters/claude_code.py
33
+ slopper_env/adapters/codex.py
34
+ slopper_env/backends/__init__.py
35
+ slopper_env/backends/base.py
36
+ slopper_env/backends/claude.py
37
+ slopper_env/backends/codex.py
38
+ tests/test_agent.py
39
+ tests/test_agent_config.py
40
+ tests/test_agent_resume.py
41
+ tests/test_claude_adapter.py
42
+ tests/test_codex.py
43
+ tests/test_doc.py
44
+ tests/test_folio_mcp.py
45
+ tests/test_identity.py
46
+ tests/test_loop.py
47
+ tests/test_ordering.py
48
+ tests/test_packaging.py
49
+ tests/test_runner.py
50
+ tests/test_sync.py
51
+ tests/test_tool_decision.py
52
+ tests/test_workspace.py
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ slopper = slopper_env.cli:main
3
+ slopper-dev = slopper_env.devtools:cli
4
+ slopper-env = slopper_env.cli:run_alias
@@ -0,0 +1,7 @@
1
+ pycrdt>=0.12.0
2
+ claude-agent-sdk<0.3,>=0.2.152
3
+ openai-codex-cli-bin<0.157,>=0.156
4
+ httpx>=0.28.0
5
+ websockets>=13.0
6
+ pydantic-settings>=2.2.0
7
+ python-json-logger>=2.0.0
@@ -0,0 +1 @@
1
+ slopper_env
File without changes
@@ -0,0 +1,7 @@
1
+ """``python -m slopper_env`` -- what the installed service runs."""
2
+
3
+ import sys
4
+
5
+ from slopper_env.cli import main
6
+
7
+ sys.exit(main())
File without changes
@@ -0,0 +1,44 @@
1
+ """The provider seam.
2
+
3
+ This interface is the only place in the environment where a provider is
4
+ named. ``TurnRunner``, ``ConversationLoop``, the document, and the UI all
5
+ operate on canonical items alone.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from abc import ABC, abstractmethod
11
+ from dataclasses import dataclass
12
+ from typing import Any, Sequence
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class TurnEnd:
17
+ """The provider's account of how a turn finished, in neutral terms."""
18
+
19
+ #: The provider's own session (Claude) or thread (Codex) id, recorded so
20
+ #: a later attach can resume it.
21
+ session_id: str | None
22
+ #: The turn ended on a tool call waiting for a human, to be resumed.
23
+ deferred: bool = False
24
+
25
+
26
+ class AgentAdapter(ABC):
27
+ kind: str
28
+
29
+ @abstractmethod
30
+ def from_provider(self, message: Any) -> list[dict]:
31
+ """Translate one provider message into canonical items.
32
+
33
+ Returns a list because a single provider message may carry several
34
+ canonical items, and because some provider messages (usage reports,
35
+ lifecycle chatter) carry none.
36
+ """
37
+
38
+ @abstractmethod
39
+ def turn_end(self, message: Any) -> TurnEnd | None:
40
+ """The turn's outcome if ``message`` is the one that ends it."""
41
+
42
+ @abstractmethod
43
+ def to_provider(self, items: Sequence[dict]) -> Any:
44
+ """Translate canonical history into a provider payload."""