penguiflow 2.2.0__py3-none-any.whl → 2.2.1__py3-none-any.whl

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.

Potentially problematic release.


This version of penguiflow might be problematic. Click here for more details.

penguiflow/__init__.py CHANGED
@@ -105,4 +105,4 @@ __all__ = [
105
105
  "TrajectoryStep",
106
106
  ]
107
107
 
108
- __version__ = "2.2.0"
108
+ __version__ = "2.2.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: penguiflow
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Async agent orchestration primitives.
5
5
  Author: PenguiFlow Team
6
6
  License: MIT License
@@ -53,21 +53,11 @@ Dynamic: license-file
53
53
  </p>
54
54
 
55
55
  <p align="center">
56
- <a href="https://github.com/penguiflow/penguiflow/actions/workflows/ci.yml">
57
- <img src="https://github.com/penguiflow/penguiflow/actions/workflows/ci.yml/badge.svg" alt="CI Status">
58
- </a>
59
- <a href="https://github.com/penguiflow/penguiflow">
60
- <img src="https://img.shields.io/badge/coverage-85%25-brightgreen" alt="Coverage">
61
- </a>
62
- <a href="https://nightly.link/penguiflow/penguiflow/workflows/benchmarks/main/benchmarks.json.zip">
63
- <img src="https://img.shields.io/badge/benchmarks-latest-orange" alt="Benchmarks">
64
- </a>
65
- <a href="https://pypi.org/project/penguiflow/">
66
- <img src="https://img.shields.io/pypi/v/penguiflow.svg" alt="PyPI version">
67
- </a>
68
- <a href="https://github.com/penguiflow/penguiflow/blob/main/LICENSE">
69
- <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License">
70
- </a>
56
+ <a href="https://github.com/hurtener/penguiflow/actions/workflows/ci.yml"><img src="https://github.com/hurtener/penguiflow/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
57
+ <a href="https://github.com/hurtener/penguiflow"><img src="https://img.shields.io/badge/coverage-85%25-brightgreen" alt="Coverage"></a>
58
+ <a href="https://nightly.link/hurtener/penguiflow/workflows/benchmarks/main/benchmarks.json.zip"><img src="https://img.shields.io/badge/benchmarks-latest-orange" alt="Benchmarks"></a>
59
+ <a href="https://pypi.org/project/penguiflow/"><img src="https://img.shields.io/pypi/v/penguiflow.svg" alt="PyPI version"></a>
60
+ <a href="https://github.com/hurtener/penguiflow/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License"></a>
71
61
  </p>
72
62
 
73
63
  **Async-first orchestration library for multi-agent and data pipelines**
@@ -81,6 +71,7 @@ It provides:
81
71
  * **Retries, timeouts, backpressure**
82
72
  * **Streaming chunks** (LLM-style token emission with `Context.emit_chunk`)
83
73
  * **Dynamic loops** (controller nodes)
74
+ * **LLM-driven orchestration** (`ReactPlanner` for autonomous multi-step workflows with tool selection, parallel execution, and pause/resume)
84
75
  * **Runtime playbooks** (callable subflows with shared metadata)
85
76
  * **Per-trace cancellation** (`PenguiFlow.cancel` with `TraceCancelled` surfacing in nodes)
86
77
  * **Deadlines & budgets** (`Message.deadline_s`, `WM.budget_hops`, and `WM.budget_tokens` guardrails that you can leave unset/`None`)
@@ -369,69 +360,52 @@ The new `penguiflow.testkit` module keeps unit tests tiny:
369
360
  The harness is covered by `tests/test_testkit.py` and demonstrated in
370
361
  `examples/testkit_demo/`.
371
362
 
372
- ### JSON-only ReAct planner (Phase A)
363
+ ### React Planner - LLM-Driven Orchestration
373
364
 
374
- Phase A introduces a lightweight planner loop that keeps PenguiFlow typed and
375
- deterministic:
365
+ Build autonomous agents that select and execute tools dynamically using the ReAct (Reasoning + Acting) pattern:
376
366
 
377
- * `penguiflow.catalog.NodeSpec` + `build_catalog` turn registered nodes into
378
- tool descriptors with JSON Schemas derived from your Pydantic models.
379
- * `penguiflow.planner.ReactPlanner` drives a JSON-only ReAct loop over those
380
- descriptors, validating every LLM action with Pydantic and replaying invalid
381
- steps to request corrections.
382
- * LiteLLM stays optional—install `penguiflow[planner]` or inject a custom
383
- `llm_client` for deterministic/offline runs.
384
-
385
- See `examples/react_minimal/` for a stubbed end-to-end run.
386
-
387
- ### Trajectory summarisation & pause/resume (Phase B)
388
-
389
- Phase B adds the tools you need for longer-running, approval-driven flows:
390
-
391
- * **Token-aware summaries** — `Trajectory.compress()` keeps a compact state and
392
- the planner can route summaries through a cheaper `summarizer_llm` before
393
- asking for the next action.
394
- * **`PlannerPause` contract** — nodes can call `await ctx.pause(...)` to return a
395
- typed pause payload. Resume the run later with `ReactPlanner.resume(token, user_input=...)`.
396
- * **Developer hints** — pass `planning_hints={...}` to enforce disallowed tools,
397
- preferred ordering, or parallelism ceilings.
367
+ ```python
368
+ from penguiflow import ReactPlanner, tool, build_catalog
398
369
 
399
- All three features are exercised in `examples/react_pause_resume/`, which runs
400
- entirely offline with stubbed LLM responses.
370
+ @tool(desc="Search documentation")
371
+ async def search_docs(args: Query, ctx) -> Documents:
372
+ return Documents(results=await search(args.text))
401
373
 
402
- ### Adaptive re-planning & budgets (Phase C)
374
+ @tool(desc="Summarize results")
375
+ async def summarize(args: Documents, ctx) -> Summary:
376
+ return Summary(text=await llm_summarize(args.results))
403
377
 
404
- Phase C closes the loop when things go sideways:
378
+ planner = ReactPlanner(
379
+ llm="gpt-4",
380
+ catalog=build_catalog([search_docs, summarize], registry),
381
+ max_iters=10
382
+ )
405
383
 
406
- * **Structured failure feedback** if a tool raises after exhausting its retries,
407
- the planner records `{failure: {node, args, error_code, suggestion}}` and feeds
408
- it back to the LLM, prompting a constrained re-plan instead of aborting.
409
- * **Hard guardrails** — configure wall-clock deadlines and hop budgets directly
410
- on `ReactPlanner`; attempts beyond the allotted hops surface deterministic
411
- violations and ultimately finish with `reason="budget_exhausted"` alongside a
412
- constraint snapshot.
413
- * **Typed exit reasons** — runs now finish with one of
414
- `answer_complete`, `no_path`, or `budget_exhausted`, keeping downstream code
415
- simple and machine-checkable.
384
+ result = await planner.run("Explain PenguiFlow routing")
385
+ print(result.payload) # LLM orchestrated search summarize automatically
386
+ ```
416
387
 
417
- The new `examples/react_replan/` sample shows a retrieval timeout automatically
418
- recover via a cached index without leaving the JSON-only contract.
388
+ **Key capabilities:**
419
389
 
420
- ### Parallel fan-out & joins (Phase D)
390
+ * **Autonomous tool selection** LLM decides which tools to call and in what order based on your query
391
+ * **Type-safe execution** — All tool inputs/outputs validated with Pydantic, JSON schemas auto-generated from models
392
+ * **Parallel execution** — LLM can fan out to multiple tools concurrently with automatic result joining
393
+ * **Pause/resume workflows** — Add approval gates with `await ctx.pause()`, resume later with user input
394
+ * **Adaptive replanning** — Tool failures feed structured error suggestions back to LLM for recovery
395
+ * **Constraint enforcement** — Set hop budgets, deadlines, and token limits to prevent runaway execution
396
+ * **Planning hints** — Guide LLM behavior with ordering preferences, parallel groups, and tool filters
421
397
 
422
- Phase D lets the planner propose sets of independent tool calls and join them
423
- without leaving the typed surface area:
398
+ **Model support:**
399
+ * Install `penguiflow[planner]` for LiteLLM integration (100+ models: OpenAI, Anthropic, Azure, etc.)
400
+ * Or inject a custom `llm_client` for deterministic/offline testing
424
401
 
425
- * **Parallel `plan` blocks** — the LLM can return `{"plan": [...]}` actions
426
- where each branch is validated against the catalog and executed concurrently.
427
- * **Typed joins** provide a `{"join": {"node": ...}}` descriptor and the
428
- planner will aggregate results, auto-populate fields like `expect`, `results`,
429
- or `failures`, and feed branch metadata through `ctx.meta` for the join node.
430
- * **Deterministic telemetry** — branch errors, pauses, and joins are recorded as
431
- structured observations so follow-up actions can re-plan or finish cleanly.
402
+ **Examples:**
403
+ * `examples/react_minimal/` Basic sequential flow with stub LLM
404
+ * `examples/react_parallel/`Parallel shard fan-out with join node
405
+ * `examples/react_pause_resume/` Approval workflow with planning hints
406
+ * `examples/react_replan/` Adaptive recovery from tool failures
432
407
 
433
- See `examples/react_parallel/` for a shard fan-out that merges responses in one
434
- round-trip.
408
+ See **manual.md Section 19** for complete documentation.
435
409
 
436
410
 
437
411
  ## 🧭 Repo Structure
@@ -1,4 +1,4 @@
1
- penguiflow/__init__.py,sha256=Hsoc0UtuilT77kVd0VKPlgnliaRlHgkA3XYd_PvQOYw,2435
1
+ penguiflow/__init__.py,sha256=kc4GWt5h5HFqOWMoL8Holk_QSxhOr8KHKsLSLJEeuz0,2435
2
2
  penguiflow/admin.py,sha256=093xFkE4bM_2ZhLrzhrEUKtmKHi_yVfMPyaGfwi1rcA,5382
3
3
  penguiflow/bus.py,sha256=mb29509_n97A6zwC-6EDpYorfAWFSpwqsMu_WeZhLE8,732
4
4
  penguiflow/catalog.py,sha256=z-Drf6PbEkvd65PcBvsVJZBBnM9GwT8ctcMdiIoQ5HY,4673
@@ -17,11 +17,11 @@ penguiflow/streaming.py,sha256=RKMm4VfaDA2ceEM_pB2Cuhmpwtdcjj7og-kjXQQDcbc,3863
17
17
  penguiflow/testkit.py,sha256=pIFYpu1RfJnW2mbGvUkPhMpL-xDAw0E959oTMxLkLh8,11806
18
18
  penguiflow/types.py,sha256=Fl56-b7OwIEUbPMDD1CY09nbOG_tmBw3FUhioojeG5M,1503
19
19
  penguiflow/viz.py,sha256=KbBb9kKoL223vj0NgJV_jo5ny-0RTc2gcSBACm0jG8w,5508
20
- penguiflow-2.2.0.dist-info/licenses/LICENSE,sha256=JSvodvLXxSct_kI9IBsZOBpVKoESQTB_AGbkClwZ7HI,1065
20
+ penguiflow-2.2.1.dist-info/licenses/LICENSE,sha256=JSvodvLXxSct_kI9IBsZOBpVKoESQTB_AGbkClwZ7HI,1065
21
21
  penguiflow_a2a/__init__.py,sha256=JuK_ov06yS2H97D2OVXhgX8LcgdOqE3EujUPaDKaduc,342
22
22
  penguiflow_a2a/server.py,sha256=VMBO-oGjB6Z9mtRBU0z7ZFGprDUC_kihZJukh3budbs,25932
23
- penguiflow-2.2.0.dist-info/METADATA,sha256=Rp0MN4Yovee2HoJOKpio9PE8A2UBTNUsECAsXBt6lLk,28872
24
- penguiflow-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- penguiflow-2.2.0.dist-info/entry_points.txt,sha256=F2KxANLEVGRbpWLmcHcvYrTVLWbKWdmk3VOe98a7t9I,59
26
- penguiflow-2.2.0.dist-info/top_level.txt,sha256=K-fTwLA14n0u_LDxDBCV7FmeBnJffhTOtUbTtOymQns,26
27
- penguiflow-2.2.0.dist-info/RECORD,,
23
+ penguiflow-2.2.1.dist-info/METADATA,sha256=ve8PUCCS-W-ws6LYxSaiudqmLeArnH-tYqINRBJS48w,27930
24
+ penguiflow-2.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ penguiflow-2.2.1.dist-info/entry_points.txt,sha256=F2KxANLEVGRbpWLmcHcvYrTVLWbKWdmk3VOe98a7t9I,59
26
+ penguiflow-2.2.1.dist-info/top_level.txt,sha256=K-fTwLA14n0u_LDxDBCV7FmeBnJffhTOtUbTtOymQns,26
27
+ penguiflow-2.2.1.dist-info/RECORD,,