axio 0.11.2__tar.gz → 0.11.3__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.
- {axio-0.11.2 → axio-0.11.3}/PKG-INFO +24 -10
- {axio-0.11.2 → axio-0.11.3}/README.md +23 -9
- {axio-0.11.2 → axio-0.11.3}/pyproject.toml +1 -1
- {axio-0.11.2 → axio-0.11.3}/.gitignore +0 -0
- {axio-0.11.2 → axio-0.11.3}/LICENSE +0 -0
- {axio-0.11.2 → axio-0.11.3}/Makefile +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/__init__.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/agent.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/agent_loader.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/blocks.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/compaction.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/context.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/events.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/exceptions.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/field.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/messages.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/models.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/permission.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/py.typed +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/realtime.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/retry.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/schema.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/selector.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/stream.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/testing.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/tool.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/tool_args.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/transport.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/src/axio/types.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/conftest.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_branch.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_capabilities.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_loader.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_permission.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_run.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_stream.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_agent_tools.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_blocks.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_compaction.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_context.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_events.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_exceptions.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_field.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_init.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_models.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_permission.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_realtime.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_retry.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_schema.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_selector.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_stream.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_testing.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_tool.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_tool_args.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_transport.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/tests/test_types.py +0 -0
- {axio-0.11.2 → axio-0.11.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: axio
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.3
|
|
4
4
|
Summary: Minimal, streaming-first, protocol-driven foundation for LLM-powered agents
|
|
5
5
|
Project-URL: Documentation, https://docs.axio-agent.com
|
|
6
6
|
Project-URL: Homepage, https://github.com/mosquito/axio-agent
|
|
@@ -49,9 +49,13 @@ import sys, types
|
|
|
49
49
|
from axio.testing import StubTransport, make_text_response
|
|
50
50
|
|
|
51
51
|
_m = types.ModuleType("axio_transport_openai")
|
|
52
|
+
|
|
53
|
+
|
|
52
54
|
class OpenAITransport(StubTransport):
|
|
53
55
|
def __init__(self, api_key: str = "", model: str = "") -> None:
|
|
54
56
|
super().__init__([make_text_response("Hello, Alice!")])
|
|
57
|
+
|
|
58
|
+
|
|
55
59
|
_m.OpenAITransport = OpenAITransport # type: ignore[attr-defined]
|
|
56
60
|
sys.modules["axio_transport_openai"] = _m
|
|
57
61
|
```
|
|
@@ -63,11 +67,13 @@ from axio.agent import Agent
|
|
|
63
67
|
from axio.context import MemoryContextStore
|
|
64
68
|
from axio.tool import Tool
|
|
65
69
|
|
|
70
|
+
|
|
66
71
|
# 1. Define a tool
|
|
67
72
|
async def greet(name: str) -> str:
|
|
68
73
|
"""Return a greeting for the given name."""
|
|
69
74
|
return f"Hello, {name}!"
|
|
70
75
|
|
|
76
|
+
|
|
71
77
|
greet_tool = Tool(name="greet", description="Greet someone by name", handler=greet)
|
|
72
78
|
|
|
73
79
|
# 2. Wire up the agent (transport comes from an axio-transport-* package)
|
|
@@ -76,12 +82,14 @@ from axio_transport_openai import OpenAITransport
|
|
|
76
82
|
transport = OpenAITransport(api_key="sk-...", model="gpt-4o-mini")
|
|
77
83
|
agent = Agent(system="You are helpful.", transport=transport, tools=[greet_tool])
|
|
78
84
|
|
|
85
|
+
|
|
79
86
|
# 3. Run
|
|
80
87
|
async def main() -> None:
|
|
81
88
|
ctx = MemoryContextStore()
|
|
82
89
|
async for event in agent.run_stream("Please greet Alice", ctx):
|
|
83
90
|
print(event)
|
|
84
91
|
|
|
92
|
+
|
|
85
93
|
asyncio.run(main())
|
|
86
94
|
```
|
|
87
95
|
|
|
@@ -121,11 +129,10 @@ from axio.events import StreamEvent
|
|
|
121
129
|
from axio.messages import Message
|
|
122
130
|
from axio.tool import Tool
|
|
123
131
|
|
|
132
|
+
|
|
124
133
|
@runtime_checkable
|
|
125
134
|
class CompletionTransport(Protocol):
|
|
126
|
-
def stream(
|
|
127
|
-
self, messages: list[Message], tools: list[Tool], system: str
|
|
128
|
-
) -> AsyncIterator[StreamEvent]: ...
|
|
135
|
+
def stream(self, messages: list[Message], tools: list[Tool], system: str) -> AsyncIterator[StreamEvent]: ...
|
|
129
136
|
```
|
|
130
137
|
|
|
131
138
|
### ContextStore
|
|
@@ -135,6 +142,7 @@ class CompletionTransport(Protocol):
|
|
|
135
142
|
from axio.context import ContextStore
|
|
136
143
|
from axio.messages import Message
|
|
137
144
|
|
|
145
|
+
|
|
138
146
|
class MyContextStore(ContextStore):
|
|
139
147
|
def __init__(self) -> None:
|
|
140
148
|
self._messages: list[Message] = []
|
|
@@ -161,6 +169,7 @@ from typing import Any
|
|
|
161
169
|
from axio.permission import PermissionGuard
|
|
162
170
|
from axio.tool import Tool
|
|
163
171
|
|
|
172
|
+
|
|
164
173
|
class MyGuard(PermissionGuard):
|
|
165
174
|
async def check(self, tool: Tool[Any], **kwargs: Any) -> dict[str, Any]:
|
|
166
175
|
# return kwargs to allow, raise GuardError to deny
|
|
@@ -185,16 +194,18 @@ class MyGuard(PermissionGuard):
|
|
|
185
194
|
```python
|
|
186
195
|
from axio.tool import Tool
|
|
187
196
|
|
|
197
|
+
|
|
188
198
|
async def summarise(text: str, max_words: int = 20) -> str:
|
|
189
199
|
"""Summarise the given text in one sentence."""
|
|
190
200
|
# your implementation
|
|
191
201
|
return "..."
|
|
192
202
|
|
|
203
|
+
|
|
193
204
|
tool = Tool(
|
|
194
205
|
name="summarise",
|
|
195
|
-
description="Summarise text",
|
|
206
|
+
description="Summarise text", # overrides docstring if set
|
|
196
207
|
handler=summarise,
|
|
197
|
-
concurrency=4,
|
|
208
|
+
concurrency=4, # max parallel executions
|
|
198
209
|
)
|
|
199
210
|
```
|
|
200
211
|
|
|
@@ -211,11 +222,14 @@ from axio.testing import (
|
|
|
211
222
|
make_echo_tool,
|
|
212
223
|
)
|
|
213
224
|
|
|
225
|
+
|
|
214
226
|
async def test_agent_calls_tool():
|
|
215
|
-
transport = StubTransport(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
227
|
+
transport = StubTransport(
|
|
228
|
+
[
|
|
229
|
+
make_tool_use_response("echo", tool_input={"msg": "hi"}),
|
|
230
|
+
make_text_response("Done"),
|
|
231
|
+
]
|
|
232
|
+
)
|
|
219
233
|
agent = Agent(system="", tools=[make_echo_tool()], transport=transport)
|
|
220
234
|
result = await agent.run("say hi", make_ephemeral_context())
|
|
221
235
|
assert result == "Done"
|
|
@@ -32,9 +32,13 @@ import sys, types
|
|
|
32
32
|
from axio.testing import StubTransport, make_text_response
|
|
33
33
|
|
|
34
34
|
_m = types.ModuleType("axio_transport_openai")
|
|
35
|
+
|
|
36
|
+
|
|
35
37
|
class OpenAITransport(StubTransport):
|
|
36
38
|
def __init__(self, api_key: str = "", model: str = "") -> None:
|
|
37
39
|
super().__init__([make_text_response("Hello, Alice!")])
|
|
40
|
+
|
|
41
|
+
|
|
38
42
|
_m.OpenAITransport = OpenAITransport # type: ignore[attr-defined]
|
|
39
43
|
sys.modules["axio_transport_openai"] = _m
|
|
40
44
|
```
|
|
@@ -46,11 +50,13 @@ from axio.agent import Agent
|
|
|
46
50
|
from axio.context import MemoryContextStore
|
|
47
51
|
from axio.tool import Tool
|
|
48
52
|
|
|
53
|
+
|
|
49
54
|
# 1. Define a tool
|
|
50
55
|
async def greet(name: str) -> str:
|
|
51
56
|
"""Return a greeting for the given name."""
|
|
52
57
|
return f"Hello, {name}!"
|
|
53
58
|
|
|
59
|
+
|
|
54
60
|
greet_tool = Tool(name="greet", description="Greet someone by name", handler=greet)
|
|
55
61
|
|
|
56
62
|
# 2. Wire up the agent (transport comes from an axio-transport-* package)
|
|
@@ -59,12 +65,14 @@ from axio_transport_openai import OpenAITransport
|
|
|
59
65
|
transport = OpenAITransport(api_key="sk-...", model="gpt-4o-mini")
|
|
60
66
|
agent = Agent(system="You are helpful.", transport=transport, tools=[greet_tool])
|
|
61
67
|
|
|
68
|
+
|
|
62
69
|
# 3. Run
|
|
63
70
|
async def main() -> None:
|
|
64
71
|
ctx = MemoryContextStore()
|
|
65
72
|
async for event in agent.run_stream("Please greet Alice", ctx):
|
|
66
73
|
print(event)
|
|
67
74
|
|
|
75
|
+
|
|
68
76
|
asyncio.run(main())
|
|
69
77
|
```
|
|
70
78
|
|
|
@@ -104,11 +112,10 @@ from axio.events import StreamEvent
|
|
|
104
112
|
from axio.messages import Message
|
|
105
113
|
from axio.tool import Tool
|
|
106
114
|
|
|
115
|
+
|
|
107
116
|
@runtime_checkable
|
|
108
117
|
class CompletionTransport(Protocol):
|
|
109
|
-
def stream(
|
|
110
|
-
self, messages: list[Message], tools: list[Tool], system: str
|
|
111
|
-
) -> AsyncIterator[StreamEvent]: ...
|
|
118
|
+
def stream(self, messages: list[Message], tools: list[Tool], system: str) -> AsyncIterator[StreamEvent]: ...
|
|
112
119
|
```
|
|
113
120
|
|
|
114
121
|
### ContextStore
|
|
@@ -118,6 +125,7 @@ class CompletionTransport(Protocol):
|
|
|
118
125
|
from axio.context import ContextStore
|
|
119
126
|
from axio.messages import Message
|
|
120
127
|
|
|
128
|
+
|
|
121
129
|
class MyContextStore(ContextStore):
|
|
122
130
|
def __init__(self) -> None:
|
|
123
131
|
self._messages: list[Message] = []
|
|
@@ -144,6 +152,7 @@ from typing import Any
|
|
|
144
152
|
from axio.permission import PermissionGuard
|
|
145
153
|
from axio.tool import Tool
|
|
146
154
|
|
|
155
|
+
|
|
147
156
|
class MyGuard(PermissionGuard):
|
|
148
157
|
async def check(self, tool: Tool[Any], **kwargs: Any) -> dict[str, Any]:
|
|
149
158
|
# return kwargs to allow, raise GuardError to deny
|
|
@@ -168,16 +177,18 @@ class MyGuard(PermissionGuard):
|
|
|
168
177
|
```python
|
|
169
178
|
from axio.tool import Tool
|
|
170
179
|
|
|
180
|
+
|
|
171
181
|
async def summarise(text: str, max_words: int = 20) -> str:
|
|
172
182
|
"""Summarise the given text in one sentence."""
|
|
173
183
|
# your implementation
|
|
174
184
|
return "..."
|
|
175
185
|
|
|
186
|
+
|
|
176
187
|
tool = Tool(
|
|
177
188
|
name="summarise",
|
|
178
|
-
description="Summarise text",
|
|
189
|
+
description="Summarise text", # overrides docstring if set
|
|
179
190
|
handler=summarise,
|
|
180
|
-
concurrency=4,
|
|
191
|
+
concurrency=4, # max parallel executions
|
|
181
192
|
)
|
|
182
193
|
```
|
|
183
194
|
|
|
@@ -194,11 +205,14 @@ from axio.testing import (
|
|
|
194
205
|
make_echo_tool,
|
|
195
206
|
)
|
|
196
207
|
|
|
208
|
+
|
|
197
209
|
async def test_agent_calls_tool():
|
|
198
|
-
transport = StubTransport(
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
210
|
+
transport = StubTransport(
|
|
211
|
+
[
|
|
212
|
+
make_tool_use_response("echo", tool_input={"msg": "hi"}),
|
|
213
|
+
make_text_response("Done"),
|
|
214
|
+
]
|
|
215
|
+
)
|
|
202
216
|
agent = Agent(system="", tools=[make_echo_tool()], transport=transport)
|
|
203
217
|
result = await agent.run("say hi", make_ephemeral_context())
|
|
204
218
|
assert result == "Done"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "axio"
|
|
3
|
-
version = "0.11.
|
|
3
|
+
version = "0.11.3" # bumped to the git tag by CI on publish
|
|
4
4
|
description = "Minimal, streaming-first, protocol-driven foundation for LLM-powered agents"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
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
|