loopentx 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 (34) hide show
  1. loopentx-0.1.0/LICENSE +21 -0
  2. loopentx-0.1.0/PKG-INFO +555 -0
  3. loopentx-0.1.0/README.md +508 -0
  4. loopentx-0.1.0/loopentx/__init__.py +31 -0
  5. loopentx-0.1.0/loopentx/backends/__init__.py +11 -0
  6. loopentx-0.1.0/loopentx/backends/base.py +115 -0
  7. loopentx-0.1.0/loopentx/backends/memory.py +146 -0
  8. loopentx-0.1.0/loopentx/backends/redis_backend.py +196 -0
  9. loopentx-0.1.0/loopentx/cli/__init__.py +0 -0
  10. loopentx-0.1.0/loopentx/cli/main.py +398 -0
  11. loopentx-0.1.0/loopentx/core/__init__.py +28 -0
  12. loopentx-0.1.0/loopentx/core/config.py +67 -0
  13. loopentx-0.1.0/loopentx/core/context.py +362 -0
  14. loopentx-0.1.0/loopentx/core/events.py +35 -0
  15. loopentx-0.1.0/loopentx/core/exceptions.py +67 -0
  16. loopentx-0.1.0/loopentx/core/loop.py +240 -0
  17. loopentx-0.1.0/loopentx/core/memory.py +110 -0
  18. loopentx-0.1.0/loopentx/core/models.py +172 -0
  19. loopentx-0.1.0/loopentx/core/orchestrator.py +166 -0
  20. loopentx-0.1.0/loopentx/core/skill.py +159 -0
  21. loopentx-0.1.0/loopentx/llm/__init__.py +3 -0
  22. loopentx-0.1.0/loopentx/llm/caller.py +103 -0
  23. loopentx-0.1.0/loopentx/trust/__init__.py +4 -0
  24. loopentx-0.1.0/loopentx/trust/policy.py +185 -0
  25. loopentx-0.1.0/loopentx/trust/scorer.py +141 -0
  26. loopentx-0.1.0/loopentx.egg-info/PKG-INFO +555 -0
  27. loopentx-0.1.0/loopentx.egg-info/SOURCES.txt +32 -0
  28. loopentx-0.1.0/loopentx.egg-info/dependency_links.txt +1 -0
  29. loopentx-0.1.0/loopentx.egg-info/entry_points.txt +2 -0
  30. loopentx-0.1.0/loopentx.egg-info/requires.txt +29 -0
  31. loopentx-0.1.0/loopentx.egg-info/top_level.txt +1 -0
  32. loopentx-0.1.0/pyproject.toml +78 -0
  33. loopentx-0.1.0/setup.cfg +4 -0
  34. loopentx-0.1.0/tests/test_loopentx.py +548 -0
loopentx-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Loopentx Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,555 @@
1
+ Metadata-Version: 2.4
2
+ Name: loopentx
3
+ Version: 0.1.0
4
+ Summary: Write the loop once. Step back. Loopentx runs it forever.
5
+ Author-email: Deepak Acharya <acharyadt260499@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/D1EE7P2U9/Loopentx-
8
+ Project-URL: Repository, https://github.com/D1EE7P2U9/Loopentx-
9
+ Project-URL: Issues, https://github.com/D1EE7P2U9/Loopentx-/issues
10
+ Project-URL: Changelog, https://github.com/D1EE7P2U9/Loopentx-/releases
11
+ Keywords: ai,agents,llm,loops,orchestration,agentic,autonomous
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: pydantic>=2.0
23
+ Requires-Dist: anyio>=4.0
24
+ Requires-Dist: httpx>=0.25
25
+ Requires-Dist: croniter>=2.0
26
+ Requires-Dist: click>=8.0
27
+ Requires-Dist: rich>=13.0
28
+ Requires-Dist: structlog>=24.0
29
+ Requires-Dist: python-ulid>=2.0
30
+ Provides-Extra: redis
31
+ Requires-Dist: redis[hiredis]>=5.0; extra == "redis"
32
+ Provides-Extra: postgres
33
+ Requires-Dist: asyncpg>=0.29; extra == "postgres"
34
+ Requires-Dist: sqlalchemy[asyncio]>=2.0; extra == "postgres"
35
+ Provides-Extra: openai
36
+ Requires-Dist: openai>=1.0; extra == "openai"
37
+ Provides-Extra: anthropic
38
+ Requires-Dist: anthropic>=0.25; extra == "anthropic"
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest>=8.0; extra == "dev"
41
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
42
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
43
+ Requires-Dist: ruff>=0.4; extra == "dev"
44
+ Requires-Dist: mypy>=1.10; extra == "dev"
45
+ Requires-Dist: pre-commit>=3.7; extra == "dev"
46
+ Dynamic: license-file
47
+
48
+ # Loopentx
49
+
50
+ > *Write the loop once. Step back. Loopentx runs it forever.*
51
+
52
+ [![PyPI version](https://badge.fury.io/py/loopentx.svg)](https://badge.fury.io/py/loopentx)
53
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
54
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
55
+ [![Tests](https://github.com/D1EE7P2U9/Loopentx-/actions/workflows/ci.yml/badge.svg)](https://github.com/D1EE7P2U9/Loopentx-/actions)
56
+
57
+ ---
58
+
59
+ There's a shift happening in how developers work with AI.
60
+
61
+ - *"You shouldn't be prompting coding agents anymore. You should be designing loops that prompt your agents."* — [@steipete](https://x.com/steipete)
62
+ - *"I don't prompt Claude anymore. I write loops, the loops do the work."* — [@0xwhrrari](https://x.com/0xwhrrari)
63
+ - *"Remove yourself as the bottleneck. Arrange it once and hit go."* — [@karpathy](https://x.com/karpathy)
64
+
65
+ **Loopentx is the Python framework that makes this concrete.**
66
+
67
+ Not a prompt library. Not an agent wrapper. The infrastructure layer that lets you write a loop once — with durability, policy, trust, and memory built in — and trust it to run without you.
68
+
69
+ ---
70
+
71
+ ## The problem with existing frameworks
72
+
73
+ Every agent framework today still puts you in the loop by design.
74
+
75
+ LangGraph needs you to define the graph. CrewAI needs you to define agents and tasks. Inngest needs you to write the skills. These are excellent tools — but they all assume a human is nearby, watching, ready to intervene.
76
+
77
+ Loopentx is built around a different assumption: **you set it up once, then you're done.**
78
+
79
+ And it adds the layer every other framework is missing: **trust** — so when your loops run at 3am, you know they're doing the right thing, not just running.
80
+
81
+ ---
82
+
83
+ ## Architecture
84
+
85
+ ```
86
+ ┌─────────────────────────────────────────────────────────────┐
87
+ │ YOU (developer) │
88
+ │ Write the loop once. Step back. │
89
+ └──────────────────────────┬──────────────────────────────────┘
90
+
91
+ ┌──────────────────────────▼──────────────────────────────────┐
92
+ │ LOOPENTX FRAMEWORK │
93
+ │ │
94
+ │ ┌────────────────────────────────────────────────────────┐ │
95
+ │ │ LOOP LAYER │ │
96
+ │ │ @loop · cron/event · ctx.think() · memory · until= │ │
97
+ │ └───────────────────────────┬────────────────────────────┘ │
98
+ │ │ │
99
+ │ ┌───────────────────────────▼────────────────────────────┐ │
100
+ │ │ SKILL LAYER │ │
101
+ │ │ @skill · ctx.step() · retries · ctx.spawn() · hooks │ │
102
+ │ └───────────────────────────┬────────────────────────────┘ │
103
+ │ │ │
104
+ │ ┌───────────────────────────▼────────────────────────────┐ │
105
+ │ │ ORCHESTRATOR LAYER │ │
106
+ │ │ Scheduling · concurrency · history · hot-deploy │ │
107
+ │ └───────────────────────────┬────────────────────────────┘ │
108
+ │ │ │
109
+ │ ┌───────────────────────────▼────────────────────────────┐ │
110
+ │ │ TRUST + POLICY LAYER ✦ unique │ │
111
+ │ │ @policy · shadow mode · trust scoring · escalation │ │
112
+ │ └───────────────────────────┬────────────────────────────┘ │
113
+ └──────────────────────────────┼──────────────────────────────┘
114
+
115
+ ┌────────────────────┼────────────────────┐
116
+ ▼ ▼ ▼
117
+ LLM providers External tools Observability
118
+ OpenAI · Anthropic APIs · DBs · Slack Runs · traces
119
+ ```
120
+
121
+ Four layers. Most frameworks give you two. The trust layer is what makes the difference between a loop you watch and a loop you trust.
122
+
123
+ ---
124
+
125
+ ## Quickstart
126
+
127
+ ```bash
128
+ pip install loopentx
129
+ ```
130
+
131
+ ```python
132
+ from loopentx import loop, skill, configure
133
+ from loopentx.trust import policy
134
+ from loopentx.backends import RedisBackend
135
+
136
+ configure(backend=RedisBackend("redis://localhost:6379"))
137
+
138
+ # A skill — durable, checkpointed, policy-scoped
139
+ @policy(can_read=["metrics_api"], can_write=["slack"], shadow_cycles=3)
140
+ @skill(retries=3, timeout=120)
141
+ async def triage_incident(ctx, services: list[str]):
142
+ metrics = await ctx.step("fetch", fetch_metrics, services)
143
+ analysis = await ctx.step("analyze", ctx.think, "What's the root cause?", context=metrics)
144
+ await ctx.step("notify", post_slack, analysis)
145
+ return analysis
146
+
147
+ # A loop — runs forever, decides what to do, invokes skills
148
+ @loop(every="30m", memory=True)
149
+ async def health_check(ctx):
150
+ health = await ctx.step("assess", check_health)
151
+
152
+ decision = await ctx.think(
153
+ "Is this health status worth waking someone up for?",
154
+ context=health,
155
+ choose_from=["act", "monitor", "skip"]
156
+ )
157
+
158
+ if decision == "act":
159
+ await ctx.invoke(triage_incident, services=health.affected)
160
+ ```
161
+
162
+ ```bash
163
+ loopentx worker start --app myapp.loops
164
+ ```
165
+
166
+ That's it. You're done. The loop runs every 30 minutes. If something's wrong, it triages it. If the process dies mid-execution, it resumes from the last checkpoint. If the skill misbehaves, the trust layer catches it.
167
+
168
+ ---
169
+
170
+ ## Core primitives
171
+
172
+ ### `@loop` — the entry point
173
+
174
+ A loop is the unit of autonomous work. It runs on a schedule or event, uses an LLM to decide what to do next, and invokes skills to do it.
175
+
176
+ ```python
177
+ @loop(
178
+ every="1h", # interval: "30m", "2h", "1d"
179
+ cron="0 9 * * 1", # or cron expression
180
+ event="deploy.completed", # or event trigger
181
+ until=lambda ctx: ctx.memory.get("done"), # exit condition
182
+ max_iterations=100, # safety ceiling
183
+ memory=True, # persist state across runs
184
+ )
185
+ async def my_loop(ctx, **event_data):
186
+ ...
187
+ ```
188
+
189
+ ### `ctx.think()` — the LLM decision point
190
+
191
+ Every loop has a `think()` call. This is where the agent makes a decision. It's explicit and named — you always know where the LLM is in the loop.
192
+
193
+ ```python
194
+ decision = await ctx.think(
195
+ "Given what we know, what should we do next?",
196
+ context=ctx.memory.last(5),
197
+ choose_from=["continue", "escalate", "done"],
198
+ )
199
+ ```
200
+
201
+ ### `ctx.step()` — checkpointed execution
202
+
203
+ Every step is persisted. If the process restarts, completed steps are replayed from cache — not re-executed. LLM calls are never repeated. Tokens are never wasted.
204
+
205
+ ```python
206
+ result = await ctx.step("fetch-data", fetch_from_api, url)
207
+ summary = await ctx.step("summarize", call_llm, result)
208
+ ```
209
+
210
+ ### `ctx.memory` — loop-native persistence
211
+
212
+ Each loop has memory that persists across runs automatically.
213
+
214
+ ```python
215
+ ctx.memory.set("last_result", result)
216
+ ctx.memory.get("last_result")
217
+ ctx.memory.last(n=5) # last n run outputs
218
+ ctx.memory.append("log", item) # grow a list over time
219
+ ```
220
+
221
+ ### `ctx.spawn()` — child loops
222
+
223
+ A loop can spawn another loop as a subtask. Loops supervising loops, natively.
224
+
225
+ ```python
226
+ # Fire and forget — parent continues immediately
227
+ await ctx.spawn(summarise_loop, data=chunk, wait=False)
228
+
229
+ # Wait for result — parent blocks until child completes
230
+ result = await ctx.spawn(deep_research_loop, topic=topic, wait=True)
231
+
232
+ # Gather multiple children in parallel
233
+ results = await ctx.gather([
234
+ ctx.spawn(worker_loop, task=t, wait=True) for t in tasks
235
+ ])
236
+ ```
237
+
238
+ ### `ctx.escalate()` — optional human checkpoint
239
+
240
+ Humans aren't in the loop by default. But the loop can decide to pull one in.
241
+
242
+ ```python
243
+ if decision == "uncertain":
244
+ response = await ctx.escalate(
245
+ "Loop hit an edge case — error rate 25% for 3 cycles. What should I do?",
246
+ timeout="2h", # if no response in 2h, use fallback
247
+ fallback="pause", # pause | continue | abort
248
+ )
249
+ ```
250
+
251
+ ### `@policy` — the trust layer
252
+
253
+ Declare what a skill is allowed to do. Enforced at runtime, not just documented.
254
+
255
+ ```python
256
+ @policy(
257
+ can_read=["db", "metrics_api"], # read access
258
+ can_write=["slack", "email"], # write/action access
259
+ blast_radius="medium", # low | medium | high | critical
260
+ shadow_cycles=5, # dry runs before going live
261
+ require_approval=False, # auto-approve if blast_radius=low
262
+ )
263
+ @skill(retries=3)
264
+ async def my_skill(ctx, ...):
265
+ ...
266
+ ```
267
+
268
+ ---
269
+
270
+ ## The three loop patterns
271
+
272
+ Loopentx is designed around the three patterns that come up again and again in real agentic systems.
273
+
274
+ ### Pattern 1 — The heartbeat loop
275
+
276
+ *Boris's model: "I write loops, the loops do the work."*
277
+
278
+ Runs on a schedule. Checks state. Acts if needed. Never needs prompting.
279
+
280
+ ```python
281
+ @loop(every="1h", memory=True)
282
+ async def monitor_loop(ctx):
283
+ state = await ctx.step("check", fetch_state)
284
+ decision = await ctx.think("Is action needed?", context=state,
285
+ choose_from=["act", "skip"])
286
+ if decision == "act":
287
+ await ctx.invoke(handle_anomaly, state=state)
288
+ ctx.memory.append("actions_taken", state)
289
+ ```
290
+
291
+ ### Pattern 2 — The research loop
292
+
293
+ *Andrej's model: "Maximize token throughput. Remove yourself as the bottleneck."*
294
+
295
+ Runs until a goal is reached, not until a human says stop. Self-improving across iterations.
296
+
297
+ ```python
298
+ def confident_enough(ctx) -> bool:
299
+ return ctx.memory.get("confidence", 0) > 0.85
300
+
301
+ @loop(until=confident_enough, max_iterations=50, memory=True)
302
+ async def research_loop(ctx, topic: str):
303
+ prior = ctx.memory.get("findings", [])
304
+ findings = await ctx.step("search", search_and_read, topic, prior)
305
+ synthesis = await ctx.step("synthesize", ctx.think,
306
+ "How confident are we? What's missing?",
307
+ context=findings)
308
+ ctx.memory.set("confidence", synthesis.confidence)
309
+ ctx.memory.append("findings", synthesis.result)
310
+ ```
311
+
312
+ ### Pattern 3 — The supervisor loop
313
+
314
+ *Steipete's model: "Design loops that prompt your agents."*
315
+
316
+ A parent loop breaks work into subtasks, spawns child loops, and collects results.
317
+
318
+ ```python
319
+ @loop(cron="0 9 * * 1") # Every Monday 9am
320
+ async def supervisor_loop(ctx):
321
+ tasks = await ctx.step("plan", decompose_goal, weekly_goal)
322
+ results = await ctx.gather([
323
+ ctx.spawn(worker_loop, task=t, wait=True) for t in tasks
324
+ ])
325
+ report = await ctx.step("report", synthesize_results, results)
326
+ await ctx.step("send", email_report, report)
327
+ ```
328
+
329
+ ---
330
+
331
+ ## What makes Loopentx different
332
+
333
+ | | LangGraph | CrewAI | Inngest | Agentex | **Loopentx** |
334
+ |----------------------------------------|-----------|--------|---------|---------|--------------|
335
+ | Core primitive | Graph | Agent crew | Function | Skill | **Loop** |
336
+ | Philosophy | You define the graph | You define agents | You define functions | You define policy | **You define the loop, then leave** |
337
+ | Step checkpointing | Partial | ❌ | ✅ | ✅ | **✅** |
338
+ | Loop memory | ❌ | ❌ | ❌ | ❌ | **✅** |
339
+ | Exit conditions | Manual | Manual | Manual | Manual | **Native primitive** |
340
+ | Child loops | ❌ | ❌ | ✅ | ✅ | **✅** |
341
+ | `ctx.think()` — explicit LLM decision | ❌ | ❌ | ❌ | ❌ | **✅** |
342
+ | Trust scoring | ❌ | ❌ | ❌ | ✅ | **✅** |
343
+ | Shadow mode | ❌ | ❌ | ❌ | ✅ | **✅** |
344
+ | Capability scoping | ❌ | ❌ | ❌ | ✅ | **✅** |
345
+ | Human escalation (opt-in) | ❌ | ⚠️ | ❌ | ⚠️ | **✅** |
346
+ | Python-first | ✅ | ✅ | ❌ | ✅ | **✅** |
347
+
348
+ The key distinction: every other framework puts a human in the design loop. Loopentx puts you in the *setup* loop and takes you out of the *execution* loop.
349
+
350
+ ---
351
+
352
+ ## How agents run on their own
353
+
354
+ This is the core question. Here's exactly what happens after you run `loopentx worker start`:
355
+
356
+ ```
357
+ 1. You wrote the loop. You started the worker. You're done.
358
+
359
+ 2. Loopentx scheduler fires the loop at the configured time/event.
360
+
361
+ 3. The loop runs ctx.think() → LLM evaluates state and decides what to do.
362
+ (You are not consulted. The LLM decides.)
363
+
364
+ 4. The loop calls ctx.step() for each action.
365
+ Each step is checkpointed — if the process dies here, it resumes.
366
+ LLM calls inside steps are never repeated.
367
+
368
+ 5. If a step fails → automatic retry with exponential backoff.
369
+ If all retries fail → on_failure hook fires, run is logged.
370
+
371
+ 6. If the loop spawns a child → child runs with its own checkpointing.
372
+ Parent waits (if wait=True) or continues independently.
373
+
374
+ 7. Exit condition is evaluated after each iteration.
375
+ If met → loop stops. Result is stored. Notification sent if configured.
376
+ If not met → loop sleeps until next scheduled time.
377
+
378
+ 8. Trust layer runs in background:
379
+ - Tracks success/failure rate per skill
380
+ - Shadow mode intercepts write actions until cycles complete
381
+ - Trust score updates hourly
382
+ - Skills below threshold flagged for human review
383
+
384
+ 9. You check the dashboard in the morning.
385
+ You see what ran, what succeeded, what failed, what the LLM decided.
386
+ You own the loop. You just don't have to watch it.
387
+ ```
388
+
389
+ ---
390
+
391
+ ## CLI reference
392
+
393
+ ```bash
394
+ # Worker
395
+ loopentx worker start --app myapp.loops # start the execution worker
396
+ loopentx worker status # check worker health
397
+
398
+ # Deploy
399
+ loopentx deploy loop my_loop --app myapp.loops
400
+ loopentx deploy skill my_skill --app myapp.loops
401
+
402
+ # Inspect
403
+ loopentx inspect loop my_loop # status, memory, run history
404
+ loopentx inspect skill my_skill # trust score, policy, recent runs
405
+
406
+ # Runs
407
+ loopentx runs list --last 7d # recent runs
408
+ loopentx runs inspect <run-id> # full step trace
409
+ loopentx runs replay <run-id> # replay a failed run
410
+
411
+ # Trust
412
+ loopentx trust list # trust scores for all skills
413
+ loopentx trust approve my_skill # approve for live execution
414
+ loopentx trust reject my_skill # pause and reject
415
+
416
+ # Memory
417
+ loopentx memory show my_loop # view loop memory
418
+ loopentx memory clear my_loop # reset loop memory
419
+ ```
420
+
421
+ ---
422
+
423
+ ## Integrations
424
+
425
+ Loopentx is designed to sit alongside your existing stack, not replace it.
426
+
427
+ **With LangGraph** — use LangGraph to define agent graph structure; use Loopentx to make each graph execution durable and policy-scoped:
428
+
429
+ ```python
430
+ @policy(can_write=["db"], blast_radius="medium")
431
+ @skill(retries=3)
432
+ async def run_langgraph_agent(ctx, state: dict):
433
+ result = await ctx.step("execute", my_lg_graph.invoke, state)
434
+ return result
435
+ ```
436
+
437
+ **With CrewAI** — use CrewAI for multi-agent conversation; use Loopentx to schedule and govern the crew execution:
438
+
439
+ ```python
440
+ @loop(cron="0 8 * * *", memory=True)
441
+ async def run_daily_crew(ctx):
442
+ result = await ctx.step("crew", my_crew.kickoff, {"topic": ctx.memory.get("topic")})
443
+ ctx.memory.set("last_output", result)
444
+ ```
445
+
446
+ **With OpenAI / Anthropic directly** — `ctx.think()` calls your configured LLM provider. Swap providers in config, loops stay unchanged.
447
+
448
+ ---
449
+
450
+ ## Installation
451
+
452
+ ```bash
453
+ # Core
454
+ pip install loopentx
455
+
456
+ # With Redis backend (production)
457
+ pip install loopentx[redis]
458
+
459
+ # With Postgres backend
460
+ pip install loopentx[postgres]
461
+
462
+ # With OpenAI
463
+ pip install loopentx[openai]
464
+
465
+ # With Anthropic
466
+ pip install loopentx[anthropic]
467
+
468
+ # Full dev install
469
+ pip install loopentx[dev]
470
+ ```
471
+
472
+ ---
473
+
474
+ ## Examples
475
+
476
+ See [`examples/`](./examples/) for complete working code:
477
+
478
+ | Example | Pattern | Demonstrates |
479
+ |---------------------------|-----------------|-------------------------------------------|
480
+ | `examples/heartbeat/` | Heartbeat loop | Monitoring, cron, ctx.think() |
481
+ | `examples/research/` | Research loop | until=, memory, confidence scoring |
482
+ | `examples/supervisor/` | Supervisor loop | ctx.spawn(), ctx.gather(), child loops |
483
+ | `examples/health_monitor/`| Combined | All four layers, shadow mode, trust |
484
+
485
+ ---
486
+
487
+ ## Configuration
488
+
489
+ ```python
490
+ # loopentx_config.py
491
+ from loopentx import configure
492
+ from loopentx.backends import RedisBackend
493
+
494
+ configure(
495
+ backend=RedisBackend(url="redis://localhost:6379"),
496
+ llm_provider="anthropic", # "openai" | "anthropic" | "custom"
497
+ llm_model="claude-sonnet-4-6",
498
+ llm_api_key="sk-ant-...", # or set ANTHROPIC_API_KEY env var
499
+
500
+ # Trust defaults
501
+ default_shadow_cycles=0,
502
+ auto_approve_low_blast=True,
503
+
504
+ # Worker
505
+ worker_concurrency=10,
506
+ worker_poll_interval=1.0,
507
+ )
508
+ ```
509
+
510
+ ---
511
+
512
+ ## Roadmap
513
+
514
+ - [x] `@loop` with cron, event, and interval triggers
515
+ - [x] `ctx.think()` — explicit LLM decision point
516
+ - [x] `ctx.step()` — step checkpointing
517
+ - [x] `ctx.memory` — loop-native persistence
518
+ - [x] `ctx.spawn()` — child loops and ctx.gather()
519
+ - [x] `ctx.escalate()` — optional human checkpoint
520
+ - [x] `@skill` with retries, timeout, on_failure
521
+ - [x] `@policy` — capability scoping, shadow mode, blast radius
522
+ - [x] Trust scoring — UNTRUSTED → AUTONOMOUS pipeline
523
+ - [x] Memory backend (in-memory + Redis)
524
+ - [x] CLI — deploy, inspect, runs, trust, worker
525
+ - [ ] Postgres backend
526
+ - [ ] Web dashboard (run history, trust scores, memory viewer)
527
+ - [ ] Temporal adapter
528
+ - [ ] Loop authoring agent (agent writes its own loops, trust pipeline validates)
529
+ - [ ] Evaluation suite integrations
530
+
531
+ ---
532
+
533
+ ## Contributing
534
+
535
+ See [CONTRIBUTING.md](./CONTRIBUTING.md). The project is young — issues, PRs, and ideas are all welcome.
536
+
537
+ ```bash
538
+ git clone https://github.com/D1EE7P2U9/Loopentx-
539
+ cd Loopentx-
540
+ pip install -e ".[dev]"
541
+ pytest tests/
542
+ ```
543
+
544
+ ---
545
+
546
+ ## Why "Loopentx"?
547
+
548
+ Loop + agent + execution. The framework for loops that run without you.
549
+
550
+ ---
551
+
552
+ ## License
553
+
554
+ MIT — see [LICENSE](./LICENSE)
555
+