power-loop 7.0.0__tar.gz → 7.2.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 (124) hide show
  1. {power_loop-7.0.0 → power_loop-7.2.0}/PKG-INFO +1 -1
  2. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/__init__.py +1 -1
  3. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/interface.py +4 -0
  4. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/llm_factory.py +9 -0
  5. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/agent/stateful_loop.py +304 -246
  6. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/event_payloads.py +7 -0
  7. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/pipeline.py +17 -0
  8. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/store.py +28 -10
  9. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop.egg-info/PKG-INFO +1 -1
  10. {power_loop-7.0.0 → power_loop-7.2.0}/LICENSE +0 -0
  11. {power_loop-7.0.0 → power_loop-7.2.0}/README.md +0 -0
  12. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/__init__.py +0 -0
  13. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/__init__.py +0 -0
  14. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/anthropic_factory.py +0 -0
  15. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/attempt_scope.py +0 -0
  16. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/capabilities.py +0 -0
  17. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/llm_tooling.py +0 -0
  18. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/llm_utils.py +0 -0
  19. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/multimodal.py +0 -0
  20. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/proxy_fallback.py +0 -0
  21. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/agent/__init__.py +0 -0
  22. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/agent/follow_up.py +0 -0
  23. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/agent/sink.py +0 -0
  24. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/agent/system_prompt.py +0 -0
  25. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/agent/types.py +0 -0
  26. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/__init__.py +0 -0
  27. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/context_policy.py +0 -0
  28. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/errors.py +0 -0
  29. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/events.py +0 -0
  30. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/handlers.py +0 -0
  31. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/hook_contexts.py +0 -0
  32. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/hooks.py +0 -0
  33. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/messages.py +0 -0
  34. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/protocols.py +0 -0
  35. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contracts/tools.py +0 -0
  36. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/__init__.py +0 -0
  37. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/_redact.py +0 -0
  38. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/jsonl_sink.py +0 -0
  39. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/logging_sink.py +0 -0
  40. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/mcp.py +0 -0
  41. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/metrics_sink.py +0 -0
  42. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/contrib/otel_sink.py +0 -0
  43. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/agent_context.py +0 -0
  44. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/events.py +0 -0
  45. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/hooks.py +0 -0
  46. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/phase.py +0 -0
  47. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/runner.py +0 -0
  48. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/core/state.py +0 -0
  49. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/py.typed +0 -0
  50. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/background.py +0 -0
  51. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/bash_capture.py +0 -0
  52. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/blackboard.py +0 -0
  53. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/budget.py +0 -0
  54. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/cancellation.py +0 -0
  55. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/capability_probe.py +0 -0
  56. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/compact.py +0 -0
  57. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/context_worker.py +0 -0
  58. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/env.py +0 -0
  59. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/exec_backend.py +0 -0
  60. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/fold.py +0 -0
  61. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/fold_adapter.py +0 -0
  62. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/history_projector.py +0 -0
  63. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/history_sanitize.py +0 -0
  64. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/human_input.py +0 -0
  65. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/image_recall.py +0 -0
  66. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/lineage.py +0 -0
  67. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/memory.py +0 -0
  68. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/notes.py +0 -0
  69. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/provider.py +0 -0
  70. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/representation.py +0 -0
  71. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/retry.py +0 -0
  72. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/runtime_state.py +0 -0
  73. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/session_store.py +0 -0
  74. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/skills.py +0 -0
  75. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/spec.py +0 -0
  76. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/steer.py +0 -0
  77. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/stop_policy.py +0 -0
  78. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/__init__.py +0 -0
  79. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/__init__.py +0 -0
  80. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/mysql.py +0 -0
  81. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/postgres.py +0 -0
  82. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/sqlite.py +0 -0
  83. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/capabilities.py +0 -0
  84. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/context_cache.py +0 -0
  85. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/db.py +0 -0
  86. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/dialect.py +0 -0
  87. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/factory.py +0 -0
  88. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/schema.py +0 -0
  89. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/store/types.py +0 -0
  90. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/structured.py +0 -0
  91. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/stub_provider.py +0 -0
  92. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/timers.py +0 -0
  93. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/todos.py +0 -0
  94. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/tool_archive.py +0 -0
  95. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/tool_context.py +0 -0
  96. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/tool_truncation.py +0 -0
  97. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/runtime/usage_estimate.py +0 -0
  98. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/__init__.py +0 -0
  99. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/blackboard.py +0 -0
  100. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/command_policy.py +0 -0
  101. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/command_rules.py +0 -0
  102. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/default_manifest.py +0 -0
  103. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/default_tools.py +0 -0
  104. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/registry.py +0 -0
  105. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/tools/spawn_agent.py +0 -0
  106. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/__init__.py +0 -0
  107. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/admission.py +0 -0
  108. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/api.py +0 -0
  109. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/engine.py +0 -0
  110. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/introspect.py +0 -0
  111. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/journal.py +0 -0
  112. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/result.py +0 -0
  113. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/resume.py +0 -0
  114. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/runner.py +0 -0
  115. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/spec.py +0 -0
  116. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/subprocess_executor.py +0 -0
  117. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/tool.py +0 -0
  118. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop/workflow/worker.py +0 -0
  119. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop.egg-info/SOURCES.txt +0 -0
  120. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop.egg-info/dependency_links.txt +0 -0
  121. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop.egg-info/requires.txt +0 -0
  122. {power_loop-7.0.0 → power_loop-7.2.0}/power_loop.egg-info/top_level.txt +0 -0
  123. {power_loop-7.0.0 → power_loop-7.2.0}/pyproject.toml +0 -0
  124. {power_loop-7.0.0 → power_loop-7.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: power-loop
3
- Version: 7.0.0
3
+ Version: 7.2.0
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__ = "7.0.0"
18
+ __version__ = "7.2.0"
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).
@@ -204,6 +204,10 @@ class LLMTokenUsage:
204
204
  accepted_tokens: int | None = None
205
205
  rejected_tokens: int | None = None
206
206
 
207
+ #: Charge the provider itself reported for this call (e.g. OpenRouter's ``usage.cost``), in the
208
+ #: provider's billing currency. ``None`` = not reported; hosts then price tokens themselves.
209
+ cost: float | None = None
210
+
207
211
  def as_dict(self) -> dict[str, int | None]:
208
212
  return dict(self.__dict__)
209
213
 
@@ -419,6 +419,14 @@ class OpenAICompatibleChatLLMService(LLMService):
419
419
  return raw
420
420
 
421
421
  def _usage_obj(self, usage: Any = None) -> LLMTokenUsage:
422
+ def _cost_or_none(v: Any) -> float | None:
423
+ if isinstance(v, bool) or not isinstance(v, (int, float, str)):
424
+ return None
425
+ try:
426
+ return float(v)
427
+ except ValueError:
428
+ return None
429
+
422
430
  d = self._last_usage if usage is None else self._usage_dict_from_any(usage)
423
431
 
424
432
  def _int_or_none(v: Any) -> int | None:
@@ -448,6 +456,7 @@ class OpenAICompatibleChatLLMService(LLMService):
448
456
  reasoning_tokens=_int_or_none(d.get("reasoning_tokens")),
449
457
  accepted_tokens=_int_or_none(d.get("accepted_tokens")),
450
458
  rejected_tokens=_int_or_none(d.get("rejected_tokens")),
459
+ cost=_cost_or_none(d.get("cost")),
451
460
  )
452
461
 
453
462
  async def _with_retries(self, fn, *, method: str) -> Any: