power-loop 7.1.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.
- {power_loop-7.1.0 → power_loop-7.2.0}/PKG-INFO +1 -1
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/__init__.py +1 -1
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/interface.py +4 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/llm_factory.py +9 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/event_payloads.py +7 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/pipeline.py +17 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop.egg-info/PKG-INFO +1 -1
- {power_loop-7.1.0 → power_loop-7.2.0}/LICENSE +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/README.md +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/anthropic_factory.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/attempt_scope.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/capabilities.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/llm_tooling.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/llm_utils.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/multimodal.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/_vendor/llm_client/proxy_fallback.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/agent/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/agent/follow_up.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/agent/sink.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/agent/stateful_loop.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/agent/system_prompt.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/agent/types.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/context_policy.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/errors.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/events.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/handlers.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/hook_contexts.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/hooks.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/messages.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/protocols.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contracts/tools.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/_redact.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/jsonl_sink.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/logging_sink.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/mcp.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/metrics_sink.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/contrib/otel_sink.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/agent_context.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/events.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/hooks.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/phase.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/runner.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/core/state.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/py.typed +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/background.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/bash_capture.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/blackboard.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/budget.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/cancellation.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/capability_probe.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/compact.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/context_worker.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/env.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/exec_backend.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/fold.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/fold_adapter.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/history_projector.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/history_sanitize.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/human_input.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/image_recall.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/lineage.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/memory.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/notes.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/provider.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/representation.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/retry.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/runtime_state.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/session_store.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/skills.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/spec.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/steer.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/stop_policy.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/mysql.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/postgres.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/backends/sqlite.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/capabilities.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/context_cache.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/db.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/dialect.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/factory.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/schema.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/store.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/store/types.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/structured.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/stub_provider.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/timers.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/todos.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/tool_archive.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/tool_context.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/tool_truncation.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/runtime/usage_estimate.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/blackboard.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/command_policy.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/command_rules.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/default_manifest.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/default_tools.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/registry.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/tools/spawn_agent.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/__init__.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/admission.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/api.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/engine.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/introspect.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/journal.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/result.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/resume.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/runner.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/spec.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/subprocess_executor.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/tool.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop/workflow/worker.py +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop.egg-info/SOURCES.txt +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop.egg-info/dependency_links.txt +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop.egg-info/requires.txt +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/power_loop.egg-info/top_level.txt +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/pyproject.toml +0 -0
- {power_loop-7.1.0 → power_loop-7.2.0}/setup.cfg +0 -0
|
@@ -15,7 +15,7 @@ Stability tiers
|
|
|
15
15
|
无版本承诺,可随时变更或删除。
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
__version__ = "7.
|
|
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:
|
|
@@ -80,6 +80,13 @@ class LlmCallCompletedPayload(BaseEventPayload):
|
|
|
80
80
|
#: ``ok`` · ``error`` · ``timeout`` · ``aborted`` (the attempt's task was cancelled: a retry
|
|
81
81
|
#: deadline, steering, a stop).
|
|
82
82
|
outcome: str = "ok"
|
|
83
|
+
#: 7.2: which endpoint served the call (the transport's base URL) — hosts price per connection,
|
|
84
|
+
#: and one model name can be served by several providers at different prices.
|
|
85
|
+
endpoint: str = ""
|
|
86
|
+
#: 7.2: charge the provider reported for this call (``LLMTokenUsage.cost``), ``None`` if not reported.
|
|
87
|
+
provider_cost: float | None = None
|
|
88
|
+
#: 7.2: image input tokens, when the provider splits them out (``None`` = not reported).
|
|
89
|
+
prompt_image_tokens: int | None = None
|
|
83
90
|
|
|
84
91
|
|
|
85
92
|
@dataclass
|
|
@@ -202,6 +202,19 @@ def _maybe_compact_accepts_context(func: Any) -> bool:
|
|
|
202
202
|
|
|
203
203
|
# ── Utility functions (unchanged from old agent.py) ──
|
|
204
204
|
|
|
205
|
+
def _llm_endpoint(llm: Any) -> str:
|
|
206
|
+
"""The base URL that serves this LLM (unwrapping retry / proxy wrappers), or ""."""
|
|
207
|
+
for _ in range(5):
|
|
208
|
+
if llm is None:
|
|
209
|
+
break
|
|
210
|
+
cfg = getattr(llm, "_cfg", None) or getattr(llm, "config", None)
|
|
211
|
+
url = getattr(cfg, "base_url", None)
|
|
212
|
+
if url:
|
|
213
|
+
return str(url)
|
|
214
|
+
llm = getattr(llm, "inner", None) or getattr(llm, "_inner", None) or getattr(llm, "llm", None)
|
|
215
|
+
return ""
|
|
216
|
+
|
|
217
|
+
|
|
205
218
|
def _truncate_result(output: Any, limit: int | None = RESULT_MAX_CHARS) -> str:
|
|
206
219
|
"""Cap a tool result before it enters history and the audit log (None = no cap). Keeps the
|
|
207
220
|
head and the tail: errors and summaries are usually at the end."""
|
|
@@ -1333,6 +1346,7 @@ class AgentPipeline:
|
|
|
1333
1346
|
success=False, error_type=type(exc).__name__,
|
|
1334
1347
|
prompt_tokens=p_est, completion_tokens=c_est,
|
|
1335
1348
|
total_tokens=p_est + c_est, estimated=True, outcome=outcome,
|
|
1349
|
+
endpoint=_llm_endpoint(self.llm),
|
|
1336
1350
|
),
|
|
1337
1351
|
round_index=round_index, stream_id="main",
|
|
1338
1352
|
)
|
|
@@ -1364,6 +1378,9 @@ class AgentPipeline:
|
|
|
1364
1378
|
prompt_cached_tokens=getattr(usage, "prompt_cached_tokens", None),
|
|
1365
1379
|
prompt_cache_miss_tokens=getattr(usage, "prompt_cache_miss_tokens", None),
|
|
1366
1380
|
estimated=estimated,
|
|
1381
|
+
endpoint=_llm_endpoint(self.llm),
|
|
1382
|
+
provider_cost=getattr(usage, "cost", None),
|
|
1383
|
+
prompt_image_tokens=getattr(usage, "prompt_image_tokens", None),
|
|
1367
1384
|
),
|
|
1368
1385
|
round_index=round_index, stream_id="main",
|
|
1369
1386
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|