agent-runtime-kit 0.3.0__tar.gz → 0.4.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 (63) hide show
  1. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/CHANGELOG.md +26 -0
  2. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/PKG-INFO +36 -1
  3. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/README.md +35 -0
  4. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/api-stability.md +8 -0
  5. agent_runtime_kit-0.4.0/docs/quickstart.md +122 -0
  6. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/pyproject.toml +1 -1
  7. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/__init__.py +7 -0
  8. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/_errors.py +12 -0
  9. agent_runtime_kit-0.4.0/src/agent_runtime_kit/_kit.py +426 -0
  10. agent_runtime_kit-0.4.0/src/agent_runtime_kit/_schema.py +272 -0
  11. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/_types.py +56 -2
  12. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_core.py +27 -0
  13. agent_runtime_kit-0.4.0/tests/test_kit.py +340 -0
  14. agent_runtime_kit-0.4.0/tests/test_schema.py +200 -0
  15. agent_runtime_kit-0.3.0/docs/quickstart.md +0 -47
  16. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/.gitignore +0 -0
  17. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/LICENSE +0 -0
  18. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/capability-matrix.md +0 -0
  19. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/live-smoke.md +0 -0
  20. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/mestre-migration.md +0 -0
  21. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/providers.md +0 -0
  22. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/sdk-evolution-agent-design.md +0 -0
  23. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/docs/sdk-evolution-agent.md +0 -0
  24. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/__init__.py +0 -0
  25. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/run_same_task.py +0 -0
  26. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/__init__.py +0 -0
  27. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/__main__.py +0 -0
  28. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/auth.py +0 -0
  29. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/behavior.py +0 -0
  30. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/cli.py +0 -0
  31. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/collectors.py +0 -0
  32. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/current_state.py +0 -0
  33. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/events.py +0 -0
  34. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/models.py +0 -0
  35. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/pr.py +0 -0
  36. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/release_notes.py +0 -0
  37. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/report.py +0 -0
  38. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/schemas.py +0 -0
  39. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/snapshots.py +0 -0
  40. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/examples/sdk_evolution_agent/stages.py +0 -0
  41. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/_runtime.py +0 -0
  42. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/adapters/__init__.py +0 -0
  43. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/adapters/_common.py +0 -0
  44. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/adapters/antigravity.py +0 -0
  45. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/adapters/claude.py +0 -0
  46. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/adapters/codex.py +0 -0
  47. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/adapters/diagnostics.py +0 -0
  48. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/events.py +0 -0
  49. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/py.typed +0 -0
  50. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/registry.py +0 -0
  51. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/testing/__init__.py +0 -0
  52. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/src/agent_runtime_kit/testing/fakes.py +0 -0
  53. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_adapter_protocol.py +0 -0
  54. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_antigravity_adapter.py +0 -0
  55. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_claude_adapter.py +0 -0
  56. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_codex_adapter.py +0 -0
  57. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_events.py +0 -0
  58. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_live_smoke.py +0 -0
  59. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_mestre_compatibility.py +0 -0
  60. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_optional_dependencies.py +0 -0
  61. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_provider_diagnostics.py +0 -0
  62. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_sdk_contract.py +0 -0
  63. {agent_runtime_kit-0.3.0 → agent_runtime_kit-0.4.0}/tests/test_sdk_evolution_agent.py +0 -0
@@ -5,6 +5,32 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 0.4.0 - 2026-07-02
9
+
10
+ ### Added
11
+
12
+ - `AgentKit`, a FastAPI-flavored hub over the registry: keyword-native
13
+ `await kit.run("claude", goal=..., permissions="strict", ...)` assembling
14
+ the frozen `AgentTask` internally (a prebuilt `task=` still passes through),
15
+ short aliases for the built-in kinds via the documented `KIND_ALIASES`
16
+ mapping, per-kind runtime caching closed by `aclose()`/`async with`,
17
+ `@kit.on(...)` sync/async event handlers that tee alongside a task's own
18
+ sink and can never break a run, and `@kit.runtime(...)` decorator
19
+ registration for third-party kinds.
20
+ - Typed structured output: `kit.run(..., output_type=SomeType)` derives the
21
+ wire schema from a dataclass/`TypedDict` (dependency-free, bounded subset,
22
+ fail-closed via the new `OutputTypeError`) or from a Pydantic-style model's
23
+ own `model_json_schema`, and validates `parsed_output` back into the type.
24
+ The result is `ParsedResult[T]` — a runtime-identical `AgentResult`
25
+ subclass with a typed `parsed` accessor; `AgentResult` itself stays
26
+ non-generic. Non-conforming payloads yield `finish_reason="failed"`, the
27
+ adapters' own structured-output convention.
28
+ - `PermissionProfile` accepts string literals for `mode`/`filesystem`
29
+ ("strict", "read-only", ...) and coerces them to real enum members at
30
+ construction; unknown values raise `ValueError` listing the vocabulary.
31
+ Previously a bare string silently matched none of the adapters' identity
32
+ checks and ran at the default posture.
33
+
8
34
  ## 0.3.0 - 2026-07-02
9
35
 
10
36
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-runtime-kit
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: One typed runtime API for Claude, Codex, and Antigravity agent SDKs.
5
5
  Project-URL: Homepage, https://github.com/ebarti/agent-runtime-kit
6
6
  Project-URL: Repository, https://github.com/ebarti/agent-runtime-kit
@@ -108,6 +108,41 @@ are added through optional extras.
108
108
 
109
109
  ## Real Providers
110
110
 
111
+ `AgentKit` is the keyword-native hub: it registers the built-in runtimes,
112
+ caches them per kind, and turns Python types into structured output.
113
+
114
+ ```python
115
+ import asyncio
116
+ from dataclasses import dataclass
117
+
118
+ from agent_runtime_kit import AgentKit
119
+
120
+
121
+ @dataclass
122
+ class RepoSummary:
123
+ name: str
124
+ languages: list[str]
125
+
126
+
127
+ async def main() -> None:
128
+ async with AgentKit() as kit:
129
+ diagnostic = kit.availability_for("claude")
130
+ if not diagnostic.available:
131
+ raise RuntimeError(diagnostic.message)
132
+ result = await kit.run(
133
+ "claude",
134
+ goal="Summarize this repository",
135
+ permissions="strict",
136
+ output_type=RepoSummary,
137
+ )
138
+ print(result.parsed.languages if result.parsed else result.error)
139
+
140
+
141
+ asyncio.run(main())
142
+ ```
143
+
144
+ Adapters also work standalone when you need vendor-specific configuration:
145
+
111
146
  ```python
112
147
  import asyncio
113
148
 
@@ -76,6 +76,41 @@ are added through optional extras.
76
76
 
77
77
  ## Real Providers
78
78
 
79
+ `AgentKit` is the keyword-native hub: it registers the built-in runtimes,
80
+ caches them per kind, and turns Python types into structured output.
81
+
82
+ ```python
83
+ import asyncio
84
+ from dataclasses import dataclass
85
+
86
+ from agent_runtime_kit import AgentKit
87
+
88
+
89
+ @dataclass
90
+ class RepoSummary:
91
+ name: str
92
+ languages: list[str]
93
+
94
+
95
+ async def main() -> None:
96
+ async with AgentKit() as kit:
97
+ diagnostic = kit.availability_for("claude")
98
+ if not diagnostic.available:
99
+ raise RuntimeError(diagnostic.message)
100
+ result = await kit.run(
101
+ "claude",
102
+ goal="Summarize this repository",
103
+ permissions="strict",
104
+ output_type=RepoSummary,
105
+ )
106
+ print(result.parsed.languages if result.parsed else result.error)
107
+
108
+
109
+ asyncio.run(main())
110
+ ```
111
+
112
+ Adapters also work standalone when you need vendor-specific configuration:
113
+
79
114
  ```python
80
115
  import asyncio
81
116
 
@@ -37,6 +37,14 @@ import the names from the top-level package instead.
37
37
  a task field raises `UnsupportedTaskInputError`; the one exception is
38
38
  vendor-option drift, which is recorded in
39
39
  `AgentResult.metadata["dropped_options"]` instead.
40
+ - **`AgentKit` is sugar, not a second API.** The hub assembles the same frozen
41
+ `AgentTask` and returns the same `AgentResult` the runtimes produce
42
+ (`ParsedResult` is a runtime-identical subclass adding only the typed
43
+ `parsed` accessor). Kind aliases are limited to the documented
44
+ `KIND_ALIASES` mapping; exact kind strings always work. `output_type=`
45
+ supports a bounded, documented subset of the typing system and raises
46
+ `OutputTypeError` on anything outside it (Pydantic-style models are used
47
+ through their own `model_json_schema`/`model_validate` when present).
40
48
 
41
49
  ## Vendor SDK version policy
42
50
 
@@ -0,0 +1,122 @@
1
+ # Quickstart
2
+
3
+ Install all first-party runtime adapters:
4
+
5
+ ```bash
6
+ pip install "agent-runtime-kit[all]"
7
+ ```
8
+
9
+ Or install only the dependency-free core:
10
+
11
+ ```bash
12
+ pip install agent-runtime-kit
13
+ ```
14
+
15
+ Install one provider extra when you know you only need that runtime:
16
+
17
+ ```bash
18
+ pip install "agent-runtime-kit[claude]"
19
+ ```
20
+
21
+ The extras split is intentional. `agent-runtime-kit` exposes one API either way,
22
+ but Claude, Codex, and Antigravity ship as separate, fast-moving SDKs with their
23
+ own transitive dependencies and runtime packages. Optional extras keep a
24
+ Claude-only application from installing Codex or Antigravity packages, keep the
25
+ core usable when one vendor package is unavailable on a platform, and make
26
+ missing-provider errors actionable.
27
+
28
+ ## Run a task
29
+
30
+ `AgentKit` is the hub: it registers the built-in runtimes, resolves them
31
+ lazily, and gives `run()` a keyword-native surface.
32
+
33
+ ```python
34
+ import asyncio
35
+
36
+ from agent_runtime_kit import AgentKit
37
+
38
+
39
+ async def main() -> None:
40
+ async with AgentKit() as kit:
41
+ result = await kit.run(
42
+ "claude", # short alias; "claude-agent-sdk" works too
43
+ goal="Summarize this repository",
44
+ permissions="strict",
45
+ )
46
+ print(result.output)
47
+
48
+
49
+ asyncio.run(main())
50
+ ```
51
+
52
+ ## Typed structured output
53
+
54
+ Pass a type instead of hand-writing JSON schema. Dataclasses and `TypedDict`s
55
+ work out of the box (no dependency); Pydantic v2 models are used through their
56
+ own `model_json_schema`/`model_validate` when you have Pydantic installed.
57
+
58
+ ```python
59
+ from dataclasses import dataclass
60
+
61
+ from agent_runtime_kit import AgentKit
62
+
63
+
64
+ @dataclass
65
+ class RepoSummary:
66
+ name: str
67
+ languages: list[str]
68
+ risky_areas: list[str]
69
+
70
+
71
+ async def main() -> None:
72
+ async with AgentKit() as kit:
73
+ result = await kit.run(
74
+ "claude",
75
+ goal="Summarize this repository",
76
+ output_type=RepoSummary,
77
+ )
78
+ if result.parsed is not None:
79
+ print(result.parsed.languages) # typed: list[str]
80
+ else:
81
+ print(result.error)
82
+ ```
83
+
84
+ A payload that does not conform yields `finish_reason="failed"` with the
85
+ mismatch in `result.error` — the same convention the adapters use for
86
+ unsatisfied structured output. Unsupported annotations (sets, plain unions,
87
+ ...) raise `OutputTypeError` at call time rather than sending a half-true
88
+ schema.
89
+
90
+ ## Events and custom runtimes
91
+
92
+ ```python
93
+ kit = AgentKit()
94
+
95
+
96
+ @kit.on("agent.tool.completed")
97
+ def log_tool(event) -> None: # sync or async; exceptions never break a run
98
+ print(event["summary"])
99
+
100
+
101
+ @kit.runtime("x-myorg-agent")
102
+ def my_runtime(**kwargs): # must stay zero-arg constructible
103
+ return MyRuntime(**kwargs)
104
+ ```
105
+
106
+ ## Lower-level use
107
+
108
+ The hub is sugar over the same objects you can use directly — construct an
109
+ adapter yourself when you need vendor-specific configuration, and pass either
110
+ the instance or a prebuilt `AgentTask` to `kit.run` (or call `runtime.run(task)`
111
+ without the hub at all):
112
+
113
+ ```python
114
+ from agent_runtime_kit import AgentTask
115
+ from agent_runtime_kit.adapters import ClaudeAgentRuntime
116
+
117
+ runtime = ClaudeAgentRuntime(default_model="claude-sonnet-4-6", reuse_process=True)
118
+ result = await runtime.run(AgentTask(goal="Summarize this repository"))
119
+ ```
120
+
121
+ Use `kit.availability()` (or `runtime.availability()`) before dispatching work
122
+ in applications that need clear setup diagnostics.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "agent-runtime-kit"
7
- version = "0.3.0"
7
+ version = "0.4.0"
8
8
  description = "One typed runtime API for Claude, Codex, and Antigravity agent SDKs."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -3,9 +3,11 @@
3
3
  from agent_runtime_kit._errors import (
4
4
  AgentRuntimeError,
5
5
  AgentRuntimeUnavailableError,
6
+ OutputTypeError,
6
7
  RuntimeNotRegisteredError,
7
8
  UnsupportedTaskInputError,
8
9
  )
10
+ from agent_runtime_kit._kit import KIND_ALIASES, AgentKit
9
11
  from agent_runtime_kit._runtime import FakeAgentRuntime
10
12
  from agent_runtime_kit._types import (
11
13
  AgentCapabilities,
@@ -19,6 +21,7 @@ from agent_runtime_kit._types import (
19
21
  FilesystemAccess,
20
22
  FinishReason,
21
23
  McpServerConfig,
24
+ ParsedResult,
22
25
  PermissionMode,
23
26
  PermissionProfile,
24
27
  RuntimeAvailability,
@@ -41,6 +44,7 @@ from agent_runtime_kit.registry import RuntimeRegistry, create_default_registry
41
44
 
42
45
  __all__ = [
43
46
  "AgentCapabilities",
47
+ "AgentKit",
44
48
  "AgentResult",
45
49
  "AgentRuntime",
46
50
  "AgentRuntimeError",
@@ -53,7 +57,10 @@ __all__ = [
53
57
  "FakeAgentRuntime",
54
58
  "FilesystemAccess",
55
59
  "FinishReason",
60
+ "KIND_ALIASES",
56
61
  "McpServerConfig",
62
+ "OutputTypeError",
63
+ "ParsedResult",
57
64
  "PermissionMode",
58
65
  "PermissionProfile",
59
66
  "RuntimeAvailability",
@@ -26,6 +26,18 @@ class UnsupportedTaskInputError(AgentRuntimeError, ValueError):
26
26
  super().__init__(f"{runtime_kind_value(self.kind)} cannot honor {field}: {message}")
27
27
 
28
28
 
29
+ class OutputTypeError(AgentRuntimeError, TypeError):
30
+ """A structured ``output_type`` cannot be honored.
31
+
32
+ Raised when a Python type cannot be converted to a JSON schema (unsupported
33
+ annotation — the stdlib bridge deliberately supports a bounded subset and
34
+ fails closed on everything else), or when a returned payload does not
35
+ conform to the requested type. Schema-generation failures surface at call
36
+ time; payload mismatches are converted by ``AgentKit`` into a failed
37
+ ``AgentResult`` instead of raising.
38
+ """
39
+
40
+
29
41
  class RuntimeNotRegisteredError(AgentRuntimeError, LookupError):
30
42
  """No runtime factory is registered for the requested runtime kind."""
31
43