power-loop 3.8.1__tar.gz → 3.9.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 (104) hide show
  1. {power_loop-3.8.1 → power_loop-3.9.0}/PKG-INFO +1 -1
  2. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/__init__.py +1 -1
  3. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/hook_contexts.py +9 -0
  4. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/pipeline.py +10 -0
  5. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop.egg-info/PKG-INFO +1 -1
  6. {power_loop-3.8.1 → power_loop-3.9.0}/LICENSE +0 -0
  7. {power_loop-3.8.1 → power_loop-3.9.0}/README.md +0 -0
  8. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/__init__.py +0 -0
  9. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/__init__.py +0 -0
  10. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/anthropic_factory.py +0 -0
  11. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/capabilities.py +0 -0
  12. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/interface.py +0 -0
  13. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/llm_factory.py +0 -0
  14. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/llm_tooling.py +0 -0
  15. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/llm_utils.py +0 -0
  16. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/_vendor/llm_client/multimodal.py +0 -0
  17. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/agent/__init__.py +0 -0
  18. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/agent/follow_up.py +0 -0
  19. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/agent/sink.py +0 -0
  20. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/agent/stateful_loop.py +0 -0
  21. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/agent/system_prompt.py +0 -0
  22. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/agent/types.py +0 -0
  23. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/__init__.py +0 -0
  24. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/errors.py +0 -0
  25. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/event_payloads.py +0 -0
  26. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/events.py +0 -0
  27. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/handlers.py +0 -0
  28. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/hooks.py +0 -0
  29. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/messages.py +0 -0
  30. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/protocols.py +0 -0
  31. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contracts/tools.py +0 -0
  32. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/__init__.py +0 -0
  33. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/_redact.py +0 -0
  34. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/jsonl_sink.py +0 -0
  35. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/logging_sink.py +0 -0
  36. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/mcp.py +0 -0
  37. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/metrics_sink.py +0 -0
  38. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/contrib/otel_sink.py +0 -0
  39. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/agent_context.py +0 -0
  40. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/events.py +0 -0
  41. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/hooks.py +0 -0
  42. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/phase.py +0 -0
  43. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/runner.py +0 -0
  44. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/core/state.py +0 -0
  45. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/py.typed +0 -0
  46. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/blackboard.py +0 -0
  47. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/budget.py +0 -0
  48. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/cancellation.py +0 -0
  49. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/compact.py +0 -0
  50. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/env.py +0 -0
  51. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/exec_backend.py +0 -0
  52. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/fold.py +0 -0
  53. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/fold_adapter.py +0 -0
  54. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/history_projector.py +0 -0
  55. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/history_sanitize.py +0 -0
  56. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/human_input.py +0 -0
  57. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/memory.py +0 -0
  58. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/notes.py +0 -0
  59. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/provider.py +0 -0
  60. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/representation.py +0 -0
  61. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/retry.py +0 -0
  62. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/runtime_state.py +0 -0
  63. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/session_store.py +0 -0
  64. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/skills.py +0 -0
  65. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/spec.py +0 -0
  66. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/__init__.py +0 -0
  67. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/backends/__init__.py +0 -0
  68. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/backends/mysql.py +0 -0
  69. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/backends/postgres.py +0 -0
  70. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/backends/sqlite.py +0 -0
  71. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/capabilities.py +0 -0
  72. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/db.py +0 -0
  73. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/dialect.py +0 -0
  74. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/factory.py +0 -0
  75. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/schema.py +0 -0
  76. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/store.py +0 -0
  77. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/store/types.py +0 -0
  78. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/structured.py +0 -0
  79. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/stub_provider.py +0 -0
  80. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/runtime/timers.py +0 -0
  81. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/tools/__init__.py +0 -0
  82. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/tools/blackboard.py +0 -0
  83. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/tools/default_manifest.py +0 -0
  84. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/tools/default_tools.py +0 -0
  85. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/tools/registry.py +0 -0
  86. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/tools/spawn_agent.py +0 -0
  87. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/__init__.py +0 -0
  88. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/api.py +0 -0
  89. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/engine.py +0 -0
  90. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/introspect.py +0 -0
  91. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/journal.py +0 -0
  92. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/result.py +0 -0
  93. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/resume.py +0 -0
  94. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/runner.py +0 -0
  95. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/spec.py +0 -0
  96. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/subprocess_executor.py +0 -0
  97. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/tool.py +0 -0
  98. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop/workflow/worker.py +0 -0
  99. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop.egg-info/SOURCES.txt +0 -0
  100. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop.egg-info/dependency_links.txt +0 -0
  101. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop.egg-info/requires.txt +0 -0
  102. {power_loop-3.8.1 → power_loop-3.9.0}/power_loop.egg-info/top_level.txt +0 -0
  103. {power_loop-3.8.1 → power_loop-3.9.0}/pyproject.toml +0 -0
  104. {power_loop-3.8.1 → power_loop-3.9.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: power-loop
3
- Version: 3.8.1
3
+ Version: 3.9.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__ = "3.8.1"
18
+ __version__ = "3.9.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).
@@ -125,6 +125,13 @@ class LlmBeforeCtx(BaseHookCtx):
125
125
  Handler may modify any input field. ``messages`` is the fresh per-call list
126
126
  actually sent to the LLM — mutating it (e.g. appending an ephemeral memory
127
127
  block) never touches the loop's persisted history.
128
+
129
+ ``persist_messages`` is the durable counterpart: any message a handler appends
130
+ here becomes a REAL history/store row (stamped with the round's send_index, via
131
+ the same append path as the loop's own turns) AND is added to this round's
132
+ request. Use it for injected turns that must survive the send — e.g. a periodic
133
+ "you haven't called X in N rounds" reminder — as opposed to the ephemeral,
134
+ request-only edits to ``messages``. Appended in order, at the tail of the request.
128
135
  """
129
136
 
130
137
  messages: list[LoopMessage] = field(default_factory=list)
@@ -133,6 +140,8 @@ class LlmBeforeCtx(BaseHookCtx):
133
140
  max_tokens: int = 8000
134
141
  temperature: float = 0.0
135
142
  session_id: str | None = None
143
+ # Durable injections: persisted as real turns after LLM_BEFORE, then added to the request.
144
+ persist_messages: list[LoopMessage] = field(default_factory=list)
136
145
  # Handler output (for SHORT_CIRCUIT)
137
146
  output: LLMResponse | None = None
138
147
 
@@ -944,6 +944,16 @@ class AgentPipeline:
944
944
  llm_before.messages, _pre_hook_ids, _hook_audit_mode
945
945
  )
946
946
 
947
+ # Durable LLM_BEFORE injections (persist_messages): unlike the ephemeral, request-only
948
+ # edits to `messages` (captured by hook_audit above), each of these becomes a REAL turn —
949
+ # persisted to history + store with the round's send_index via the loop's own append path
950
+ # — and is added to this round's request tail. Used for injected turns that must survive
951
+ # the send (e.g. a periodic "you haven't called X in N rounds" reminder). Computed AFTER
952
+ # hook_audit so these durable rows don't get counted as ephemeral injections.
953
+ for _pm in llm_before.persist_messages:
954
+ await self._append_message(_pm, round_index=round_idx)
955
+ llm_before.messages.append(dict(_pm))
956
+
947
957
  if llm_before.directive == HookDirective.SHORT_CIRCUIT:
948
958
  response = llm_before.output
949
959
  if not isinstance(response, LLMResponse):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: power-loop
3
- Version: 3.8.1
3
+ Version: 3.9.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
File without changes
File without changes
File without changes
File without changes