sofias-sdk-lite 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.
- sofias_sdk_lite-0.1.0/PKG-INFO +151 -0
- sofias_sdk_lite-0.1.0/README.md +136 -0
- sofias_sdk_lite-0.1.0/pyproject.toml +51 -0
- sofias_sdk_lite-0.1.0/pyproject.toml.orig +51 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/__init__.py +262 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/__init__.py +67 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/agent.py +899 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/agent_builder.py +1221 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/agent_config.py +87 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/execution_context.py +222 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/middleware.py +118 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/response_workflow.py +232 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/agent/streaming.py +119 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/config/__init__.py +63 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/config/agent_settings.py +72 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/config/defaults.py +78 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/config/runtime_config.py +201 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/config/sdk_config.py +105 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/config/source.py +168 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/contracts/__init__.py +48 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/contracts/agent_contracts.py +174 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/contracts/base_contracts.py +115 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/contracts/node_contracts.py +177 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/contracts/strict_contract.py +34 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/errors/__init__.py +76 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/errors/circuit_breaker.py +150 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/errors/error_handler.py +413 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/errors/exceptions.py +408 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/llm/__init__.py +27 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/llm/protocol.py +92 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/llm/tokens.py +19 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/llm/tools.py +36 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/messaging/__init__.py +47 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/messaging/models.py +516 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/__init__.py +104 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/aggregator_config.py +78 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/aggregator_node.py +390 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/base_node.py +211 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/delegation_config.py +281 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/delegation_node.py +1120 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/delegation_transport.py +228 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/function_node.py +289 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/llm_node.py +1451 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/llm_node_config.py +266 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/plan_executor.py +434 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/planner_node.py +206 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/planning_models.py +137 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/nodes/prompt_assembler.py +266 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/observability/__init__.py +47 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/observability/_log.py +43 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/observability/events.py +438 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/observability/tracing.py +619 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/py.typed +0 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/__init__.py +33 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/client.py +105 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/config.py +33 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/consumer.py +149 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/delegation_transport.py +400 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/publisher.py +273 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/rpc_client.py +338 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/rabbitmq/types.py +68 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/routing/__init__.py +27 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/routing/router.py +301 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/routing/strategies.py +485 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/runner/__init__.py +8 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/runner/config.py +43 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/runner/runner.py +243 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/state/__init__.py +26 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/state/conversation_state.py +259 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/state/history.py +104 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/state/memory.py +123 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/tools.py +482 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/workflows/__init__.py +28 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/workflows/chat.py +113 -0
- sofias_sdk_lite-0.1.0/src/sofias_sdk_lite/workflows/null.py +35 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sofias-sdk-lite
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Build agents on the Sofias agent graph and run them over RabbitMQ.
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Dist: pydantic>=2.0
|
|
7
|
+
Requires-Dist: aio-pika>=9.0.0
|
|
8
|
+
Requires-Dist: rstream>=1.0.0
|
|
9
|
+
Requires-Dist: nh3>=0.3.6
|
|
10
|
+
Requires-Dist: mkdocs-material>=9.5 ; extra == 'docs'
|
|
11
|
+
Requires-Dist: mkdocstrings[python]>=0.25 ; extra == 'docs'
|
|
12
|
+
Requires-Python: >=3.11
|
|
13
|
+
Provides-Extra: docs
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# sofias-sdk-lite
|
|
17
|
+
|
|
18
|
+
Build multi-node agents on a declarative graph and run them against RabbitMQ.
|
|
19
|
+
|
|
20
|
+
`sofias-sdk-lite` gives you:
|
|
21
|
+
|
|
22
|
+
- **An agent graph** — LLM nodes, function nodes, delegation nodes (agent-to-agent),
|
|
23
|
+
aggregator nodes (fan-in), and planner nodes (dynamic DAGs), wired together with
|
|
24
|
+
explicit routing strategies.
|
|
25
|
+
- **A messaging layer** — pydantic wire models (`AgentTaskMessage`, `StreamFragment`,
|
|
26
|
+
delegation contracts) and a RabbitMQ transport (client, consumer, publisher, RPC,
|
|
27
|
+
delegation transport) built on `aio-pika` and RabbitMQ Streams.
|
|
28
|
+
- **A runner** — `AgentRunner` consumes tasks from a queue, resolves per-request
|
|
29
|
+
settings, executes your agent, and streams the response back — with graceful
|
|
30
|
+
shutdown, retries, and circuit breakers built in.
|
|
31
|
+
- **Bring your own LLM** — `LLMCallable` is a protocol. Wrap any HTTP client,
|
|
32
|
+
local model, or provider SDK in ~15 lines; no vendor lock-in.
|
|
33
|
+
|
|
34
|
+
Nothing here depends on a private backend, an internal config service, or a
|
|
35
|
+
specific LLM vendor. Everything infrastructure-specific is a constructor
|
|
36
|
+
argument or a protocol you implement yourself.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install sofias-sdk-lite
|
|
42
|
+
# or
|
|
43
|
+
uv add sofias-sdk-lite
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Requires Python 3.11+ and a running RabbitMQ broker (with the
|
|
47
|
+
[Streams plugin](https://www.rabbitmq.com/docs/streams) enabled) if you use
|
|
48
|
+
the runner or streaming responses.
|
|
49
|
+
|
|
50
|
+
## Quickstart
|
|
51
|
+
|
|
52
|
+
A minimal agent with a single function node:
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import asyncio
|
|
56
|
+
|
|
57
|
+
from sofias_sdk_lite import (
|
|
58
|
+
AgentBuilder,
|
|
59
|
+
AgentMessage,
|
|
60
|
+
BaseAgentSettings,
|
|
61
|
+
InputContract,
|
|
62
|
+
NodeContract,
|
|
63
|
+
OutputContract,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class GreetInput(InputContract):
|
|
68
|
+
name: str
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class GreetOutput(OutputContract):
|
|
72
|
+
greeting: str
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class HelloSettings(BaseAgentSettings):
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def greet(data: dict, context: dict | None = None) -> dict:
|
|
80
|
+
return {"greeting": f"Hello, {data['name']}!"}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
async def main() -> None:
|
|
84
|
+
contract = NodeContract(input_schema=GreetInput, output_schema=GreetOutput)
|
|
85
|
+
agent = (
|
|
86
|
+
AgentBuilder("hello_agent", version="0.1.0")
|
|
87
|
+
.with_settings_class(HelloSettings)
|
|
88
|
+
.with_contract(input_schema=GreetInput, output_schema=GreetOutput)
|
|
89
|
+
.add_function_node("greeter", contract, process_fn=greet)
|
|
90
|
+
.set_entry_node("greeter")
|
|
91
|
+
.set_terminal("greeter")
|
|
92
|
+
.build()
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
response = await agent.execute(AgentMessage(content=GreetInput(name="World")))
|
|
96
|
+
print(response.content) # {"greeting": "Hello, World!"}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
asyncio.run(main())
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See [`examples/`](examples/) for a runner against a local RabbitMQ
|
|
103
|
+
(`docker-compose.yml` included), tool loops, streaming, and agent-to-agent
|
|
104
|
+
delegation.
|
|
105
|
+
|
|
106
|
+
## Running an agent against RabbitMQ
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from sofias_sdk_lite import AgentRunner, RunnerConfig, RabbitMQConfig, AgentMessage
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class MyAgentRunner(AgentRunner):
|
|
113
|
+
settings_class = MySettings
|
|
114
|
+
|
|
115
|
+
def build_agent(self, settings, workflow):
|
|
116
|
+
return (
|
|
117
|
+
AgentBuilder("my_agent")
|
|
118
|
+
.with_settings_class(type(settings))
|
|
119
|
+
.with_response_workflow(workflow)
|
|
120
|
+
# ... nodes, routing ...
|
|
121
|
+
.build()
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def prepare_input(self, task, history, role):
|
|
125
|
+
return AgentMessage(
|
|
126
|
+
content=MyInput(message=task.content, role=role),
|
|
127
|
+
conversation_id=task.conversation_id,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
if __name__ == "__main__":
|
|
132
|
+
MyAgentRunner(
|
|
133
|
+
RunnerConfig(
|
|
134
|
+
queue="my-agent-tasks",
|
|
135
|
+
agent_name="my_agent",
|
|
136
|
+
rabbitmq=RabbitMQConfig(host="localhost"),
|
|
137
|
+
)
|
|
138
|
+
).run()
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Scope (v1)
|
|
142
|
+
|
|
143
|
+
Core agent graph, RabbitMQ messaging, and the runner ship today. Memory,
|
|
144
|
+
MCP tool discovery, and LLM adapter implementations are intentionally out
|
|
145
|
+
of scope for v1 — the SDK ships the relevant protocols
|
|
146
|
+
(`MemoryProvider`, `ToolProvider`, `LLMCallable`) so you can plug in your
|
|
147
|
+
own, and these become optional extras in a later release.
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
Apache-2.0. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# sofias-sdk-lite
|
|
2
|
+
|
|
3
|
+
Build multi-node agents on a declarative graph and run them against RabbitMQ.
|
|
4
|
+
|
|
5
|
+
`sofias-sdk-lite` gives you:
|
|
6
|
+
|
|
7
|
+
- **An agent graph** — LLM nodes, function nodes, delegation nodes (agent-to-agent),
|
|
8
|
+
aggregator nodes (fan-in), and planner nodes (dynamic DAGs), wired together with
|
|
9
|
+
explicit routing strategies.
|
|
10
|
+
- **A messaging layer** — pydantic wire models (`AgentTaskMessage`, `StreamFragment`,
|
|
11
|
+
delegation contracts) and a RabbitMQ transport (client, consumer, publisher, RPC,
|
|
12
|
+
delegation transport) built on `aio-pika` and RabbitMQ Streams.
|
|
13
|
+
- **A runner** — `AgentRunner` consumes tasks from a queue, resolves per-request
|
|
14
|
+
settings, executes your agent, and streams the response back — with graceful
|
|
15
|
+
shutdown, retries, and circuit breakers built in.
|
|
16
|
+
- **Bring your own LLM** — `LLMCallable` is a protocol. Wrap any HTTP client,
|
|
17
|
+
local model, or provider SDK in ~15 lines; no vendor lock-in.
|
|
18
|
+
|
|
19
|
+
Nothing here depends on a private backend, an internal config service, or a
|
|
20
|
+
specific LLM vendor. Everything infrastructure-specific is a constructor
|
|
21
|
+
argument or a protocol you implement yourself.
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install sofias-sdk-lite
|
|
27
|
+
# or
|
|
28
|
+
uv add sofias-sdk-lite
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Requires Python 3.11+ and a running RabbitMQ broker (with the
|
|
32
|
+
[Streams plugin](https://www.rabbitmq.com/docs/streams) enabled) if you use
|
|
33
|
+
the runner or streaming responses.
|
|
34
|
+
|
|
35
|
+
## Quickstart
|
|
36
|
+
|
|
37
|
+
A minimal agent with a single function node:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
|
|
42
|
+
from sofias_sdk_lite import (
|
|
43
|
+
AgentBuilder,
|
|
44
|
+
AgentMessage,
|
|
45
|
+
BaseAgentSettings,
|
|
46
|
+
InputContract,
|
|
47
|
+
NodeContract,
|
|
48
|
+
OutputContract,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class GreetInput(InputContract):
|
|
53
|
+
name: str
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class GreetOutput(OutputContract):
|
|
57
|
+
greeting: str
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class HelloSettings(BaseAgentSettings):
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def greet(data: dict, context: dict | None = None) -> dict:
|
|
65
|
+
return {"greeting": f"Hello, {data['name']}!"}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
async def main() -> None:
|
|
69
|
+
contract = NodeContract(input_schema=GreetInput, output_schema=GreetOutput)
|
|
70
|
+
agent = (
|
|
71
|
+
AgentBuilder("hello_agent", version="0.1.0")
|
|
72
|
+
.with_settings_class(HelloSettings)
|
|
73
|
+
.with_contract(input_schema=GreetInput, output_schema=GreetOutput)
|
|
74
|
+
.add_function_node("greeter", contract, process_fn=greet)
|
|
75
|
+
.set_entry_node("greeter")
|
|
76
|
+
.set_terminal("greeter")
|
|
77
|
+
.build()
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
response = await agent.execute(AgentMessage(content=GreetInput(name="World")))
|
|
81
|
+
print(response.content) # {"greeting": "Hello, World!"}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
asyncio.run(main())
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See [`examples/`](examples/) for a runner against a local RabbitMQ
|
|
88
|
+
(`docker-compose.yml` included), tool loops, streaming, and agent-to-agent
|
|
89
|
+
delegation.
|
|
90
|
+
|
|
91
|
+
## Running an agent against RabbitMQ
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from sofias_sdk_lite import AgentRunner, RunnerConfig, RabbitMQConfig, AgentMessage
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class MyAgentRunner(AgentRunner):
|
|
98
|
+
settings_class = MySettings
|
|
99
|
+
|
|
100
|
+
def build_agent(self, settings, workflow):
|
|
101
|
+
return (
|
|
102
|
+
AgentBuilder("my_agent")
|
|
103
|
+
.with_settings_class(type(settings))
|
|
104
|
+
.with_response_workflow(workflow)
|
|
105
|
+
# ... nodes, routing ...
|
|
106
|
+
.build()
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def prepare_input(self, task, history, role):
|
|
110
|
+
return AgentMessage(
|
|
111
|
+
content=MyInput(message=task.content, role=role),
|
|
112
|
+
conversation_id=task.conversation_id,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
if __name__ == "__main__":
|
|
117
|
+
MyAgentRunner(
|
|
118
|
+
RunnerConfig(
|
|
119
|
+
queue="my-agent-tasks",
|
|
120
|
+
agent_name="my_agent",
|
|
121
|
+
rabbitmq=RabbitMQConfig(host="localhost"),
|
|
122
|
+
)
|
|
123
|
+
).run()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Scope (v1)
|
|
127
|
+
|
|
128
|
+
Core agent graph, RabbitMQ messaging, and the runner ship today. Memory,
|
|
129
|
+
MCP tool discovery, and LLM adapter implementations are intentionally out
|
|
130
|
+
of scope for v1 — the SDK ships the relevant protocols
|
|
131
|
+
(`MemoryProvider`, `ToolProvider`, `LLMCallable`) so you can plug in your
|
|
132
|
+
own, and these become optional extras in a later release.
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
Apache-2.0. See [LICENSE](LICENSE).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sofias-sdk-lite"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Build agents on the Sofias agent graph and run them over RabbitMQ."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "Apache-2.0"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"pydantic>=2.0",
|
|
10
|
+
"aio-pika>=9.0.0",
|
|
11
|
+
"rstream>=1.0.0",
|
|
12
|
+
"nh3>=0.3.6",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
docs = [
|
|
17
|
+
"mkdocs-material>=9.5",
|
|
18
|
+
"mkdocstrings[python]>=0.25",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[[tool.uv.index]]
|
|
22
|
+
name = "pypi"
|
|
23
|
+
url = "https://pypi.org/simple"
|
|
24
|
+
default = true
|
|
25
|
+
|
|
26
|
+
[tool.pytest.ini_options]
|
|
27
|
+
pythonpath = ["src"]
|
|
28
|
+
addopts = "-ra"
|
|
29
|
+
asyncio_mode = "auto"
|
|
30
|
+
markers = ["integration: requires a running RabbitMQ broker"]
|
|
31
|
+
|
|
32
|
+
[tool.ruff]
|
|
33
|
+
line-length = 100
|
|
34
|
+
target-version = "py311"
|
|
35
|
+
|
|
36
|
+
[tool.pyright]
|
|
37
|
+
include = ["src"]
|
|
38
|
+
typeCheckingMode = "strict"
|
|
39
|
+
|
|
40
|
+
[build-system]
|
|
41
|
+
requires = ["uv_build>=0.10.0,<0.12.0"]
|
|
42
|
+
build-backend = "uv_build"
|
|
43
|
+
|
|
44
|
+
[dependency-groups]
|
|
45
|
+
dev = [
|
|
46
|
+
"pytest>=8.0",
|
|
47
|
+
"pytest-asyncio>=0.23.0",
|
|
48
|
+
"pytest-cov>=5.0",
|
|
49
|
+
"ruff>=0.4.0",
|
|
50
|
+
"pyright>=1.1.408",
|
|
51
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sofias-sdk-lite"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Build agents on the Sofias agent graph and run them over RabbitMQ."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
license = "Apache-2.0"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"pydantic>=2.0",
|
|
10
|
+
"aio-pika>=9.0.0",
|
|
11
|
+
"rstream>=1.0.0",
|
|
12
|
+
"nh3>=0.3.6",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
docs = [
|
|
17
|
+
"mkdocs-material>=9.5",
|
|
18
|
+
"mkdocstrings[python]>=0.25",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[[tool.uv.index]]
|
|
22
|
+
name = "pypi"
|
|
23
|
+
url = "https://pypi.org/simple"
|
|
24
|
+
default = true
|
|
25
|
+
|
|
26
|
+
[build-system]
|
|
27
|
+
requires = ["uv_build>=0.10.0,<0.12.0"]
|
|
28
|
+
build-backend = "uv_build"
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"pytest>=8.0",
|
|
33
|
+
"pytest-asyncio>=0.23.0",
|
|
34
|
+
"pytest-cov>=5.0",
|
|
35
|
+
"ruff>=0.4.0",
|
|
36
|
+
"pyright>=1.1.408",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
pythonpath = ["src"]
|
|
41
|
+
addopts = "-ra"
|
|
42
|
+
asyncio_mode = "auto"
|
|
43
|
+
markers = ["integration: requires a running RabbitMQ broker"]
|
|
44
|
+
|
|
45
|
+
[tool.ruff]
|
|
46
|
+
line-length = 100
|
|
47
|
+
target-version = "py311"
|
|
48
|
+
|
|
49
|
+
[tool.pyright]
|
|
50
|
+
include = ["src"]
|
|
51
|
+
typeCheckingMode = "strict"
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"""Sofias Agents SDK — build agents on the Sofias agent graph and run them over RabbitMQ.
|
|
2
|
+
|
|
3
|
+
Quickstart::
|
|
4
|
+
|
|
5
|
+
from sofias_sdk_lite import AgentBuilder, InputContract, NodeContract, OutputContract
|
|
6
|
+
|
|
7
|
+
class GreetInput(InputContract):
|
|
8
|
+
name: str
|
|
9
|
+
|
|
10
|
+
class GreetOutput(OutputContract):
|
|
11
|
+
greeting: str
|
|
12
|
+
|
|
13
|
+
agent = (
|
|
14
|
+
AgentBuilder("hello_agent", version="0.1.0")
|
|
15
|
+
.with_settings_class(MySettings)
|
|
16
|
+
.with_contract(input_schema=GreetInput, output_schema=GreetOutput)
|
|
17
|
+
.add_function_node(
|
|
18
|
+
"greeter",
|
|
19
|
+
NodeContract(input_schema=GreetInput, output_schema=GreetOutput),
|
|
20
|
+
process_fn=lambda data, ctx: {"greeting": f"Hello, {data['name']}!"},
|
|
21
|
+
)
|
|
22
|
+
.set_entry_node("greeter")
|
|
23
|
+
.set_terminal("greeter")
|
|
24
|
+
.build()
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
See the docs site for the full guide: agent graph concepts, running an agent
|
|
28
|
+
against RabbitMQ, streaming, delegation, and testing.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from __future__ import annotations
|
|
32
|
+
|
|
33
|
+
from sofias_sdk_lite.agent import (
|
|
34
|
+
Agent,
|
|
35
|
+
AgentBuildError,
|
|
36
|
+
AgentBuilder,
|
|
37
|
+
AgentConfig,
|
|
38
|
+
AgentLLMConfig,
|
|
39
|
+
AgentMiddleware,
|
|
40
|
+
BaseDelegationResponseWorkflow,
|
|
41
|
+
ExecutionContext,
|
|
42
|
+
LoggingMiddleware,
|
|
43
|
+
PublishFn,
|
|
44
|
+
ResponseWorkflow,
|
|
45
|
+
StreamingResponseWorkflow,
|
|
46
|
+
get_execution_context,
|
|
47
|
+
set_execution_context,
|
|
48
|
+
)
|
|
49
|
+
from sofias_sdk_lite.config import (
|
|
50
|
+
AgentSettings,
|
|
51
|
+
BaseAgentSettings,
|
|
52
|
+
ConfigSource,
|
|
53
|
+
EnvConfigSource,
|
|
54
|
+
RuntimeConfigError,
|
|
55
|
+
SDKConfig,
|
|
56
|
+
SettingsResolver,
|
|
57
|
+
StaticConfigSource,
|
|
58
|
+
)
|
|
59
|
+
from sofias_sdk_lite.contracts import (
|
|
60
|
+
AgentContract,
|
|
61
|
+
AgentMessage,
|
|
62
|
+
AgentResponse,
|
|
63
|
+
DelegationRequest,
|
|
64
|
+
DelegationResponse,
|
|
65
|
+
DelegationStatus,
|
|
66
|
+
InputContract,
|
|
67
|
+
NodeContract,
|
|
68
|
+
OutputContract,
|
|
69
|
+
ResponseStatus,
|
|
70
|
+
StrictContract,
|
|
71
|
+
)
|
|
72
|
+
from sofias_sdk_lite.errors import (
|
|
73
|
+
AgentSDKError,
|
|
74
|
+
CircuitBreakerConfig,
|
|
75
|
+
ConfigSourceError,
|
|
76
|
+
ContractValidationError,
|
|
77
|
+
ErrorHandler,
|
|
78
|
+
ErrorHandlerConfig,
|
|
79
|
+
GraphExecutionError,
|
|
80
|
+
InputValidationError,
|
|
81
|
+
NodeExecutionError,
|
|
82
|
+
OutputValidationError,
|
|
83
|
+
RetryPolicy,
|
|
84
|
+
RoutingError,
|
|
85
|
+
ToolExecutionError,
|
|
86
|
+
)
|
|
87
|
+
from sofias_sdk_lite.llm import (
|
|
88
|
+
LLMCallable,
|
|
89
|
+
LLMResponse,
|
|
90
|
+
StreamableLLMCallable,
|
|
91
|
+
TokenUsage,
|
|
92
|
+
ToolCall,
|
|
93
|
+
ToolSpec,
|
|
94
|
+
)
|
|
95
|
+
from sofias_sdk_lite.messaging import (
|
|
96
|
+
AgentTaskMessage,
|
|
97
|
+
ApiTaskMessage,
|
|
98
|
+
ChatRequest,
|
|
99
|
+
ChatResponse,
|
|
100
|
+
FileContent,
|
|
101
|
+
FileMessage,
|
|
102
|
+
StreamFragment,
|
|
103
|
+
)
|
|
104
|
+
from sofias_sdk_lite.nodes import (
|
|
105
|
+
AggregatorNode,
|
|
106
|
+
AggregatorNodeConfig,
|
|
107
|
+
BaseNode,
|
|
108
|
+
DelegationNode,
|
|
109
|
+
DelegationNodeConfig,
|
|
110
|
+
DelegationTransport,
|
|
111
|
+
FunctionNode,
|
|
112
|
+
LLMNode,
|
|
113
|
+
LLMNodeConfig,
|
|
114
|
+
NodeType,
|
|
115
|
+
NullDelegationTransport,
|
|
116
|
+
PlannerNode,
|
|
117
|
+
)
|
|
118
|
+
from sofias_sdk_lite.rabbitmq import (
|
|
119
|
+
AckPolicy,
|
|
120
|
+
RabbitMQClient,
|
|
121
|
+
RabbitMQConfig,
|
|
122
|
+
RabbitMQConsumer,
|
|
123
|
+
RabbitMQDelegationTransport,
|
|
124
|
+
RabbitMQPublisher,
|
|
125
|
+
RabbitMQRPCClient,
|
|
126
|
+
)
|
|
127
|
+
from sofias_sdk_lite.routing import (
|
|
128
|
+
CompositeStrategy,
|
|
129
|
+
ConditionalStrategy,
|
|
130
|
+
ConfidenceThresholdStrategy,
|
|
131
|
+
FanOutStrategy,
|
|
132
|
+
FieldPresenceStrategy,
|
|
133
|
+
FieldValueStrategy,
|
|
134
|
+
Router,
|
|
135
|
+
RoutingStrategy,
|
|
136
|
+
StaticRoute,
|
|
137
|
+
)
|
|
138
|
+
from sofias_sdk_lite.runner import AgentRunner, RunnerConfig
|
|
139
|
+
from sofias_sdk_lite.state import (
|
|
140
|
+
ConversationStateProvider,
|
|
141
|
+
HistoryProvider,
|
|
142
|
+
InMemoryHistory,
|
|
143
|
+
InMemoryStateProvider,
|
|
144
|
+
MemoryProvider,
|
|
145
|
+
Message,
|
|
146
|
+
)
|
|
147
|
+
from sofias_sdk_lite.workflows import ChatResponseWorkflow, NullWorkflow
|
|
148
|
+
|
|
149
|
+
__version__ = "0.1.0"
|
|
150
|
+
|
|
151
|
+
__all__ = [
|
|
152
|
+
"__version__",
|
|
153
|
+
# Agent
|
|
154
|
+
"Agent",
|
|
155
|
+
"AgentBuilder",
|
|
156
|
+
"AgentBuildError",
|
|
157
|
+
"AgentConfig",
|
|
158
|
+
"AgentLLMConfig",
|
|
159
|
+
"AgentMiddleware",
|
|
160
|
+
"LoggingMiddleware",
|
|
161
|
+
"ExecutionContext",
|
|
162
|
+
"get_execution_context",
|
|
163
|
+
"set_execution_context",
|
|
164
|
+
"ResponseWorkflow",
|
|
165
|
+
"StreamingResponseWorkflow",
|
|
166
|
+
"BaseDelegationResponseWorkflow",
|
|
167
|
+
"PublishFn",
|
|
168
|
+
# Config
|
|
169
|
+
"AgentSettings",
|
|
170
|
+
"BaseAgentSettings",
|
|
171
|
+
"SDKConfig",
|
|
172
|
+
"SettingsResolver",
|
|
173
|
+
"RuntimeConfigError",
|
|
174
|
+
"ConfigSource",
|
|
175
|
+
"StaticConfigSource",
|
|
176
|
+
"EnvConfigSource",
|
|
177
|
+
# Contracts
|
|
178
|
+
"StrictContract",
|
|
179
|
+
"InputContract",
|
|
180
|
+
"OutputContract",
|
|
181
|
+
"NodeContract",
|
|
182
|
+
"AgentContract",
|
|
183
|
+
"AgentMessage",
|
|
184
|
+
"AgentResponse",
|
|
185
|
+
"ResponseStatus",
|
|
186
|
+
"DelegationRequest",
|
|
187
|
+
"DelegationResponse",
|
|
188
|
+
"DelegationStatus",
|
|
189
|
+
# Errors
|
|
190
|
+
"AgentSDKError",
|
|
191
|
+
"ContractValidationError",
|
|
192
|
+
"InputValidationError",
|
|
193
|
+
"OutputValidationError",
|
|
194
|
+
"NodeExecutionError",
|
|
195
|
+
"RoutingError",
|
|
196
|
+
"ToolExecutionError",
|
|
197
|
+
"GraphExecutionError",
|
|
198
|
+
"ConfigSourceError",
|
|
199
|
+
"ErrorHandler",
|
|
200
|
+
"ErrorHandlerConfig",
|
|
201
|
+
"RetryPolicy",
|
|
202
|
+
"CircuitBreakerConfig",
|
|
203
|
+
# LLM protocol
|
|
204
|
+
"LLMCallable",
|
|
205
|
+
"StreamableLLMCallable",
|
|
206
|
+
"LLMResponse",
|
|
207
|
+
"TokenUsage",
|
|
208
|
+
"ToolCall",
|
|
209
|
+
"ToolSpec",
|
|
210
|
+
# Messaging
|
|
211
|
+
"AgentTaskMessage",
|
|
212
|
+
"ApiTaskMessage",
|
|
213
|
+
"ChatRequest",
|
|
214
|
+
"ChatResponse",
|
|
215
|
+
"StreamFragment",
|
|
216
|
+
"FileMessage",
|
|
217
|
+
"FileContent",
|
|
218
|
+
# Nodes
|
|
219
|
+
"BaseNode",
|
|
220
|
+
"NodeType",
|
|
221
|
+
"LLMNode",
|
|
222
|
+
"LLMNodeConfig",
|
|
223
|
+
"FunctionNode",
|
|
224
|
+
"AggregatorNode",
|
|
225
|
+
"AggregatorNodeConfig",
|
|
226
|
+
"DelegationNode",
|
|
227
|
+
"DelegationNodeConfig",
|
|
228
|
+
"DelegationTransport",
|
|
229
|
+
"NullDelegationTransport",
|
|
230
|
+
"PlannerNode",
|
|
231
|
+
# Routing
|
|
232
|
+
"Router",
|
|
233
|
+
"RoutingStrategy",
|
|
234
|
+
"StaticRoute",
|
|
235
|
+
"FieldValueStrategy",
|
|
236
|
+
"FieldPresenceStrategy",
|
|
237
|
+
"ConditionalStrategy",
|
|
238
|
+
"ConfidenceThresholdStrategy",
|
|
239
|
+
"CompositeStrategy",
|
|
240
|
+
"FanOutStrategy",
|
|
241
|
+
# RabbitMQ
|
|
242
|
+
"RabbitMQConfig",
|
|
243
|
+
"RabbitMQClient",
|
|
244
|
+
"RabbitMQConsumer",
|
|
245
|
+
"RabbitMQPublisher",
|
|
246
|
+
"RabbitMQRPCClient",
|
|
247
|
+
"RabbitMQDelegationTransport",
|
|
248
|
+
"AckPolicy",
|
|
249
|
+
# Runner
|
|
250
|
+
"AgentRunner",
|
|
251
|
+
"RunnerConfig",
|
|
252
|
+
# Workflows
|
|
253
|
+
"ChatResponseWorkflow",
|
|
254
|
+
"NullWorkflow",
|
|
255
|
+
# State
|
|
256
|
+
"ConversationStateProvider",
|
|
257
|
+
"InMemoryStateProvider",
|
|
258
|
+
"MemoryProvider",
|
|
259
|
+
"HistoryProvider",
|
|
260
|
+
"InMemoryHistory",
|
|
261
|
+
"Message",
|
|
262
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Agent module: the Agent executor, builder, and supporting runtime pieces."""
|
|
2
|
+
|
|
3
|
+
from sofias_sdk_lite.agent.agent import Agent
|
|
4
|
+
from sofias_sdk_lite.agent.agent_builder import AgentBuildError, AgentBuilder
|
|
5
|
+
from sofias_sdk_lite.agent.agent_config import AgentConfig, AgentLLMConfig
|
|
6
|
+
from sofias_sdk_lite.agent.execution_context import (
|
|
7
|
+
ExecutionContext,
|
|
8
|
+
TokenAccumulator,
|
|
9
|
+
get_execution_context,
|
|
10
|
+
set_execution_context,
|
|
11
|
+
)
|
|
12
|
+
from sofias_sdk_lite.agent.middleware import (
|
|
13
|
+
AgentMiddleware,
|
|
14
|
+
LoggingMiddleware,
|
|
15
|
+
TimingMiddleware,
|
|
16
|
+
)
|
|
17
|
+
from sofias_sdk_lite.agent.response_workflow import (
|
|
18
|
+
BaseDelegationResponseWorkflow,
|
|
19
|
+
PublishFn,
|
|
20
|
+
ResponseWorkflow,
|
|
21
|
+
StreamingResponseWorkflow,
|
|
22
|
+
)
|
|
23
|
+
from sofias_sdk_lite.agent.streaming import (
|
|
24
|
+
AgentCompleteEvent,
|
|
25
|
+
AgentErrorEvent,
|
|
26
|
+
AggregationResponseEvent,
|
|
27
|
+
NodeCompleteEvent,
|
|
28
|
+
NodeStartEvent,
|
|
29
|
+
StreamEvent,
|
|
30
|
+
TextChunkEvent,
|
|
31
|
+
ToolCallResultEvent,
|
|
32
|
+
ToolCallStartEvent,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
# Agent
|
|
37
|
+
"Agent",
|
|
38
|
+
"get_execution_context",
|
|
39
|
+
"set_execution_context",
|
|
40
|
+
"ExecutionContext",
|
|
41
|
+
"TokenAccumulator",
|
|
42
|
+
# Builder
|
|
43
|
+
"AgentBuilder",
|
|
44
|
+
"AgentBuildError",
|
|
45
|
+
# Config
|
|
46
|
+
"AgentConfig",
|
|
47
|
+
"AgentLLMConfig",
|
|
48
|
+
# Middleware
|
|
49
|
+
"AgentMiddleware",
|
|
50
|
+
"LoggingMiddleware",
|
|
51
|
+
"TimingMiddleware",
|
|
52
|
+
# Response workflow
|
|
53
|
+
"ResponseWorkflow",
|
|
54
|
+
"StreamingResponseWorkflow",
|
|
55
|
+
"BaseDelegationResponseWorkflow",
|
|
56
|
+
"PublishFn",
|
|
57
|
+
# Streaming events
|
|
58
|
+
"StreamEvent",
|
|
59
|
+
"TextChunkEvent",
|
|
60
|
+
"ToolCallStartEvent",
|
|
61
|
+
"ToolCallResultEvent",
|
|
62
|
+
"NodeStartEvent",
|
|
63
|
+
"NodeCompleteEvent",
|
|
64
|
+
"AgentCompleteEvent",
|
|
65
|
+
"AggregationResponseEvent",
|
|
66
|
+
"AgentErrorEvent",
|
|
67
|
+
]
|