Skip to content

Commit b4e2e1d

Browse files
committed
Add reasoning loop models, client, and tests (v1.6.0)
Reasoning loop (ORGA cycle), Cedar policy evaluation, journal system, circuit breaker, and knowledge bridge — Pydantic models with enums, ReasoningClient sub-client with 15 methods, and 53 tests.
1 parent 8d246ff commit b4e2e1d

File tree

7 files changed

+1201
-2
lines changed

7 files changed

+1201
-2
lines changed

README.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,62 @@ pytest
11241124
- pydantic
11251125
- python-dotenv
11261126

1127-
## What's New in v0.6.0
1127+
## Reasoning Loop (v1.6.0)
1128+
1129+
Run autonomous reasoning loops with policy gates, circuit breakers, and knowledge recall:
1130+
1131+
```python
1132+
from symbiont import Client, RunReasoningLoopRequest, LoopConfig
1133+
1134+
client = Client()
1135+
1136+
# Run a reasoning loop
1137+
request = RunReasoningLoopRequest(
1138+
config=LoopConfig(max_iterations=10, timeout_ms=60000),
1139+
initial_message="Analyze the latest sales data and create a report.",
1140+
)
1141+
response = client.reasoning.run_loop("agent-1", request)
1142+
1143+
print(f"Output: {response.result.output}")
1144+
print(f"Iterations: {response.result.iterations}")
1145+
print(f"Termination: {response.result.termination_reason.type}")
1146+
1147+
# Check loop status
1148+
status = client.reasoning.get_loop_status("agent-1", response.loop_id)
1149+
1150+
# Read journal entries
1151+
journal = client.reasoning.get_journal_entries("agent-1", limit=50)
1152+
1153+
# Cedar policy management
1154+
from symbiont import CedarPolicy
1155+
1156+
client.reasoning.add_cedar_policy("agent-1", CedarPolicy(
1157+
name="deny-file-write",
1158+
source='forbid(principal, action == "tool_call", resource) when { resource.name == "write_file" };',
1159+
active=True,
1160+
))
1161+
policies = client.reasoning.list_cedar_policies("agent-1")
1162+
1163+
# Circuit breaker status
1164+
breakers = client.reasoning.get_circuit_breaker_status("agent-1")
1165+
1166+
# Knowledge bridge
1167+
client.reasoning.store_knowledge("agent-1", "sales", "grew_by", "15%")
1168+
facts = client.reasoning.recall_knowledge("agent-1", "sales growth")
1169+
```
1170+
1171+
## What's New in v1.6.0
1172+
1173+
- **Reasoning Loop**`client.reasoning.run_loop()`, `get_loop_status()`, `cancel_loop()` for autonomous ORGA cycles
1174+
- **Journal System**`get_journal_entries()`, `compact_journal()` for loop event replay and auditing
1175+
- **Cedar Policies**`list_cedar_policies()`, `add_cedar_policy()`, `evaluate_cedar_policy()` for action-level governance
1176+
- **Circuit Breakers**`get_circuit_breaker_status()`, `reset_circuit_breaker()` for tool failure isolation
1177+
- **Knowledge Bridge**`recall_knowledge()`, `store_knowledge()` for persistent agent memory
1178+
- **Pydantic Models** — Full type coverage for all reasoning types in `symbiont.reasoning`
1179+
1180+
### Previous Releases
1181+
1182+
#### v0.6.0
11281183

11291184
### Webhook Verification
11301185

symbiont/__init__.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,43 @@
121121
SkillMetadata,
122122
SkillScanner,
123123
)
124+
from .reasoning import (
125+
CedarPolicy,
126+
CircuitBreakerConfig,
127+
CircuitBreakerStatus,
128+
CircuitState,
129+
FinishReason,
130+
InferenceOptions,
131+
InferenceResponse,
132+
JournalEntry,
133+
KnowledgeConfig,
134+
LoopConfig,
135+
LoopDecision,
136+
LoopDecisionType,
137+
LoopEvent,
138+
LoopEventType,
139+
LoopResult,
140+
LoopState,
141+
Observation,
142+
ProposedAction,
143+
ProposedActionType,
144+
RecoveryStrategy,
145+
RecoveryStrategyType,
146+
RunReasoningLoopRequest,
147+
RunReasoningLoopResponse,
148+
TerminationReason,
149+
TerminationReasonType,
150+
ToolCallRequest,
151+
ToolDefinition,
152+
Usage,
153+
)
154+
from .reasoning_client import ReasoningClient
124155
from .webhooks import HmacVerifier, JwtVerifier, SignatureVerifier, WebhookProvider
125156

126157
# Load environment variables from .env file
127158
load_dotenv()
128159

129-
__version__ = "0.6.0"
160+
__version__ = "1.6.0"
130161

131162
__all__ = [
132163
# Client
@@ -194,6 +225,20 @@
194225
'MetricsClient', 'MetricsCollector', 'MetricsSnapshot',
195226
'FileMetricsExporter', 'CompositeExporter',
196227

228+
# Reasoning Loop
229+
'ReasoningClient',
230+
'Usage', 'ToolDefinition', 'ToolCallRequest',
231+
'FinishReason', 'InferenceOptions', 'InferenceResponse',
232+
'Observation', 'ProposedAction', 'ProposedActionType',
233+
'LoopDecision', 'LoopDecisionType',
234+
'RecoveryStrategy', 'RecoveryStrategyType',
235+
'TerminationReason', 'TerminationReasonType',
236+
'LoopConfig', 'LoopState', 'LoopResult',
237+
'LoopEvent', 'LoopEventType', 'JournalEntry',
238+
'CedarPolicy', 'KnowledgeConfig',
239+
'CircuitState', 'CircuitBreakerConfig', 'CircuitBreakerStatus',
240+
'RunReasoningLoopRequest', 'RunReasoningLoopResponse',
241+
197242
# Exceptions
198243
'SymbiontError',
199244
'APIError',

symbiont/client.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ def __init__(self,
154154
self._channels: Optional[ChannelClient] = None
155155
self._agentpin: Optional[Any] = None
156156
self._metrics_client: Optional[Any] = None
157+
self._reasoning: Optional[Any] = None
157158

158159
@property
159160
def schedules(self) -> ScheduleClient:
@@ -177,6 +178,14 @@ def agentpin(self):
177178
self._agentpin = AgentPinClient(self)
178179
return self._agentpin
179180

181+
@property
182+
def reasoning(self):
183+
"""Lazy-loaded reasoning client for loop, journal, Cedar, circuit breaker, and knowledge operations."""
184+
if self._reasoning is None:
185+
from .reasoning_client import ReasoningClient
186+
self._reasoning = ReasoningClient(self)
187+
return self._reasoning
188+
180189
@property
181190
def metrics_client(self):
182191
"""Lazy-loaded metrics client for runtime metrics queries."""

0 commit comments

Comments
 (0)