power-loop 6.46.2__tar.gz → 6.46.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.
Files changed (113) hide show
  1. {power_loop-6.46.2 → power_loop-6.46.3}/PKG-INFO +1 -1
  2. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/__init__.py +1 -1
  3. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/runner.py +13 -1
  4. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop.egg-info/PKG-INFO +1 -1
  5. {power_loop-6.46.2 → power_loop-6.46.3}/LICENSE +0 -0
  6. {power_loop-6.46.2 → power_loop-6.46.3}/README.md +0 -0
  7. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/__init__.py +0 -0
  8. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/__init__.py +0 -0
  9. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/anthropic_factory.py +0 -0
  10. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/capabilities.py +0 -0
  11. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/interface.py +0 -0
  12. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/llm_factory.py +0 -0
  13. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/llm_tooling.py +0 -0
  14. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/llm_utils.py +0 -0
  15. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/multimodal.py +0 -0
  16. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/_vendor/llm_client/proxy_fallback.py +0 -0
  17. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/agent/__init__.py +0 -0
  18. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/agent/follow_up.py +0 -0
  19. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/agent/sink.py +0 -0
  20. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/agent/stateful_loop.py +0 -0
  21. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/agent/system_prompt.py +0 -0
  22. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/agent/types.py +0 -0
  23. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/__init__.py +0 -0
  24. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/errors.py +0 -0
  25. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/event_payloads.py +0 -0
  26. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/events.py +0 -0
  27. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/handlers.py +0 -0
  28. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/hook_contexts.py +0 -0
  29. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/hooks.py +0 -0
  30. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/messages.py +0 -0
  31. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/protocols.py +0 -0
  32. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contracts/tools.py +0 -0
  33. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/__init__.py +0 -0
  34. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/_redact.py +0 -0
  35. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/jsonl_sink.py +0 -0
  36. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/logging_sink.py +0 -0
  37. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/mcp.py +0 -0
  38. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/metrics_sink.py +0 -0
  39. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/contrib/otel_sink.py +0 -0
  40. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/agent_context.py +0 -0
  41. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/events.py +0 -0
  42. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/hooks.py +0 -0
  43. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/phase.py +0 -0
  44. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/pipeline.py +0 -0
  45. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/runner.py +0 -0
  46. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/core/state.py +0 -0
  47. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/py.typed +0 -0
  48. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/blackboard.py +0 -0
  49. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/budget.py +0 -0
  50. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/cancellation.py +0 -0
  51. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/capability_probe.py +0 -0
  52. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/compact.py +0 -0
  53. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/env.py +0 -0
  54. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/exec_backend.py +0 -0
  55. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/fold.py +0 -0
  56. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/fold_adapter.py +0 -0
  57. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/history_projector.py +0 -0
  58. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/history_sanitize.py +0 -0
  59. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/human_input.py +0 -0
  60. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/image_recall.py +0 -0
  61. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/memory.py +0 -0
  62. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/notes.py +0 -0
  63. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/provider.py +0 -0
  64. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/representation.py +0 -0
  65. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/retry.py +0 -0
  66. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/runtime_state.py +0 -0
  67. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/session_store.py +0 -0
  68. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/skills.py +0 -0
  69. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/spec.py +0 -0
  70. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/steer.py +0 -0
  71. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/stop_policy.py +0 -0
  72. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/__init__.py +0 -0
  73. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/backends/__init__.py +0 -0
  74. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/backends/mysql.py +0 -0
  75. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/backends/postgres.py +0 -0
  76. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/backends/sqlite.py +0 -0
  77. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/capabilities.py +0 -0
  78. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/db.py +0 -0
  79. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/dialect.py +0 -0
  80. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/factory.py +0 -0
  81. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/schema.py +0 -0
  82. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/store.py +0 -0
  83. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/store/types.py +0 -0
  84. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/structured.py +0 -0
  85. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/stub_provider.py +0 -0
  86. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/timers.py +0 -0
  87. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/todos.py +0 -0
  88. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/runtime/usage_estimate.py +0 -0
  89. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/__init__.py +0 -0
  90. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/blackboard.py +0 -0
  91. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/command_policy.py +0 -0
  92. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/command_rules.py +0 -0
  93. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/default_manifest.py +0 -0
  94. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/default_tools.py +0 -0
  95. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/registry.py +0 -0
  96. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/tools/spawn_agent.py +0 -0
  97. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/__init__.py +0 -0
  98. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/api.py +0 -0
  99. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/engine.py +0 -0
  100. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/introspect.py +0 -0
  101. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/journal.py +0 -0
  102. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/result.py +0 -0
  103. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/resume.py +0 -0
  104. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/spec.py +0 -0
  105. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/subprocess_executor.py +0 -0
  106. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/tool.py +0 -0
  107. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop/workflow/worker.py +0 -0
  108. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop.egg-info/SOURCES.txt +0 -0
  109. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop.egg-info/dependency_links.txt +0 -0
  110. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop.egg-info/requires.txt +0 -0
  111. {power_loop-6.46.2 → power_loop-6.46.3}/power_loop.egg-info/top_level.txt +0 -0
  112. {power_loop-6.46.2 → power_loop-6.46.3}/pyproject.toml +0 -0
  113. {power_loop-6.46.2 → power_loop-6.46.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: power-loop
3
- Version: 6.46.2
3
+ Version: 6.46.3
4
4
  Summary: Embeddable agent execution kernel — LLM loop, hooks, events, tools, dynamic sub-agents.
5
5
  Author-email: zhangran <zhangran24@126.com>
6
6
  License: MIT
@@ -15,7 +15,7 @@ Stability tiers
15
15
  无版本承诺,可随时变更或删除。
16
16
  """
17
17
 
18
- __version__ = "6.46.2"
18
+ __version__ = "6.46.3"
19
19
 
20
20
  # Public LLM contract (SDK-free) re-exported so callers (e.g. writing llm.* hooks or
21
21
  # a custom LLMService) don't reach into the internal vendored transport package (H3.4).
@@ -80,6 +80,11 @@ _HANDLES: dict[str, WorkflowRunHandle] = {}
80
80
  #: runs stopped by :func:`stop_run` — they settle ``cancelled`` and must NOT wake the parent agent
81
81
  #: (the user said stop; a "your workflow finished" wake-up would contradict them).
82
82
  _STOPPED_RUNS: set[str] = set()
83
+ #: runs whose engine finished and whose journal is final, but whose background task is still
84
+ #: delivering the completion (``on_complete`` / wake). From here on the run is NOT live: the woken
85
+ #: parent may nudge / resume its leaves and a stop is a no-op (6.46.3 — the parent's whole wake
86
+ #: turn ran inside that task, so ``nudge`` was refused and ``cancel`` deadlocked on itself).
87
+ _SETTLED_RUNS: set[str] = set()
83
88
 
84
89
 
85
90
  def get_run_handle(run_id: str) -> WorkflowRunHandle | None:
@@ -94,8 +99,10 @@ async def stop_run(run_id: str, *, grace_s: float = 60.0, reason: str = "stopped
94
99
  if handle is None:
95
100
  return "unknown"
96
101
  task = handle.task
97
- if task is None or task.done():
102
+ if task is None or task.done() or run_id in _SETTLED_RUNS:
98
103
  return "finished"
104
+ if task is asyncio.current_task():
105
+ return "finished" # called from inside the run's own completion delivery — never wait on ourselves
99
106
  _STOPPED_RUNS.add(run_id)
100
107
  handle.cancel(reason)
101
108
  done, _ = await asyncio.wait({task}, timeout=grace_s)
@@ -370,6 +377,9 @@ def spawn_background(
370
377
  status = "failed"
371
378
  note = _wake_note(run_id, "failed", repr(exc))
372
379
  _publish(loop, parent_sid, run_id, "failed", "failed", level="error")
380
+ # The journal is final: the run is over even though this task still delivers the wake below.
381
+ _LIVE_RUN_IDS.discard(run_id)
382
+ _SETTLED_RUNS.add(run_id)
373
383
  if run_id in _STOPPED_RUNS:
374
384
  return # stopped by request — journaled as cancelled, no wake (design/124 §8.4)
375
385
  if on_complete is not None:
@@ -386,6 +396,7 @@ def spawn_background(
386
396
  # In-process liveness (workflow-durability-3): mark live now, discard when the task settles —
387
397
  # a crashed run is therefore NOT marked live, so resume-after-crash still works.
388
398
  _LIVE_RUN_IDS.add(run_id)
399
+ _SETTLED_RUNS.discard(run_id) # a resumed run starts unsettled again
389
400
  task.add_done_callback(lambda _t: _LIVE_RUN_IDS.discard(run_id))
390
401
  handle = WorkflowRunHandle(run_id=run_id, task=task, cancel_token=cancel_token)
391
402
  _HANDLES[run_id] = handle
@@ -394,6 +405,7 @@ def spawn_background(
394
405
  if _HANDLES.get(run_id) is handle:
395
406
  _HANDLES.pop(run_id, None)
396
407
  _STOPPED_RUNS.discard(run_id)
408
+ _SETTLED_RUNS.discard(run_id)
397
409
 
398
410
  task.add_done_callback(_forget)
399
411
  return handle
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: power-loop
3
- Version: 6.46.2
3
+ Version: 6.46.3
4
4
  Summary: Embeddable agent execution kernel — LLM loop, hooks, events, tools, dynamic sub-agents.
5
5
  Author-email: zhangran <zhangran24@126.com>
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes