claude-smart 0.2.47 → 0.2.48

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. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/plugin/.claude-plugin/plugin.json +1 -1
  5. package/plugin/.codex-plugin/plugin.json +1 -1
  6. package/plugin/dashboard/app/sessions/[sessionId]/page.tsx +36 -2
  7. package/plugin/dashboard/package-lock.json +61 -390
  8. package/plugin/dashboard/package.json +2 -2
  9. package/plugin/pyproject.toml +1 -1
  10. package/plugin/uv.lock +1 -1
  11. package/plugin/vendor/reflexio/.env.example +7 -0
  12. package/plugin/vendor/reflexio/pyproject.toml +2 -1
  13. package/plugin/vendor/reflexio/reflexio/README.md +8 -5
  14. package/plugin/vendor/reflexio/reflexio/lib/_config.py +23 -18
  15. package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +16 -1
  16. package/plugin/vendor/reflexio/reflexio/lib/_search.py +15 -11
  17. package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +1 -0
  18. package/plugin/vendor/reflexio/reflexio/models/config_schema.py +24 -3
  19. package/plugin/vendor/reflexio/reflexio/server/README.md +25 -8
  20. package/plugin/vendor/reflexio/reflexio/server/__init__.py +21 -2
  21. package/plugin/vendor/reflexio/reflexio/server/api.py +133 -3273
  22. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/README.md +4 -3
  23. package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +16 -1
  24. package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +62 -36
  25. package/plugin/vendor/reflexio/reflexio/server/deployment_profile.py +69 -0
  26. package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_embedding.py +424 -0
  27. package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_json_extraction.py +249 -0
  28. package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_structured_output.py +195 -0
  29. package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_subprocess.py +152 -0
  30. package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_text_generation.py +980 -0
  31. package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_types.py +110 -0
  32. package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +73 -1819
  33. package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +56 -4
  34. package/plugin/vendor/reflexio/reflexio/server/middleware.py +244 -0
  35. package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +9 -1
  36. package/plugin/vendor/reflexio/reflexio/server/rate_limit.py +79 -0
  37. package/plugin/vendor/reflexio/reflexio/server/routes/__init__.py +6 -0
  38. package/plugin/vendor/reflexio/reflexio/server/routes/_common.py +25 -0
  39. package/plugin/vendor/reflexio/reflexio/server/routes/_metering.py +98 -0
  40. package/plugin/vendor/reflexio/reflexio/server/routes/braintrust.py +129 -0
  41. package/plugin/vendor/reflexio/reflexio/server/routes/config.py +210 -0
  42. package/plugin/vendor/reflexio/reflexio/server/routes/evaluation.py +549 -0
  43. package/plugin/vendor/reflexio/reflexio/server/routes/interactions.py +259 -0
  44. package/plugin/vendor/reflexio/reflexio/server/routes/playbooks.py +578 -0
  45. package/plugin/vendor/reflexio/reflexio/server/routes/profiles.py +423 -0
  46. package/plugin/vendor/reflexio/reflexio/server/routes/provenance.py +345 -0
  47. package/plugin/vendor/reflexio/reflexio/server/routes/search.py +349 -0
  48. package/plugin/vendor/reflexio/reflexio/server/routes/system.py +261 -0
  49. package/plugin/vendor/reflexio/reflexio/server/scheduling.py +132 -0
  50. package/plugin/vendor/reflexio/reflexio/server/services/README.md +3 -2
  51. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/__init__.py +38 -0
  52. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_batch_progress.py +298 -0
  53. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_config_filter.py +152 -0
  54. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_extraction_lifecycle.py +243 -0
  55. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_should_run.py +299 -0
  56. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_status_change.py +273 -0
  57. package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_usage_billing.py +258 -0
  58. package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +17 -1183
  59. package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +8 -1
  60. package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +26 -41
  61. package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +232 -123
  62. package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +362 -81
  63. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator.py +68 -490
  64. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator_clustering.py +184 -0
  65. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator_postprocessing.py +130 -0
  66. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator_prompt_formatting.py +212 -0
  67. package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/consolidator.py +258 -69
  68. package/plugin/vendor/reflexio/reflexio/server/services/publish_learning_worker.py +288 -0
  69. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +29 -4
  70. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +10 -1167
  71. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +56 -351
  72. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_governance.py +0 -1513
  73. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +6 -1
  74. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +7 -1281
  75. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +30 -0
  76. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/__init__.py +9 -0
  77. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/_agent_run_store.py +506 -0
  78. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/_pending_tool_call_store.py +704 -0
  79. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/_run_tool_dependency_store.py +123 -0
  80. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/__init__.py +6 -0
  81. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/_deletion.py +263 -0
  82. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/_fts_vec.py +132 -0
  83. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/__init__.py +13 -0
  84. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_audit.py +122 -0
  85. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_erase_execution.py +465 -0
  86. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_purge.py +387 -0
  87. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_rebuild_hide.py +332 -0
  88. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_subject_barrier.py +511 -0
  89. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_agent.py +6 -3
  90. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_user.py +13 -7
  91. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/__init__.py +9 -0
  92. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_interaction_store.py +263 -0
  93. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_profile_store.py +896 -0
  94. package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_search.py +270 -0
  95. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +33 -8
  96. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +64 -370
  97. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +20 -0
  98. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/__init__.py +9 -0
  99. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_agent_run_store.py +86 -0
  100. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_models.py +195 -0
  101. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_pending_tool_call_store.py +148 -0
  102. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_run_tool_dependency_store.py +38 -0
  103. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/__init__.py +13 -0
  104. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_audit.py +29 -0
  105. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_erase_execution.py +30 -0
  106. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_purge.py +74 -0
  107. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_rebuild_hide.py +32 -0
  108. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_subject_barrier.py +49 -0
  109. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/__init__.py +9 -0
  110. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/_interaction_store.py +73 -0
  111. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/{_profiles.py → profiles/_profile_store.py} +44 -86
  112. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/_search.py +32 -0
  113. package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_governance.py +0 -148
@@ -1,378 +1,72 @@
1
- """Shared storage types and helpers for resumable extraction agent runs."""
1
+ """Shared storage types and helpers for resumable extraction agent runs.
2
+
3
+ Residual holder for the ``_agent_run.py`` decomposition. The 18 shared
4
+ non-class symbols live in the leaf ``agent_run/_models.py`` and are re-exported
5
+ here so ``storage_base/__init__.py`` keeps importing them from ``._agent_run``
6
+ byte-identically. ``AgentRunMixin`` survives as a thin COMPOSITE ABC:
7
+ ``AgentRunStoreABC`` supplies the agent-run lifecycle stubs,
8
+ ``PendingToolCallStoreABC`` supplies the pending-tool-call stubs,
9
+ ``RunToolDependencyStoreABC`` supplies the run-tool-dependency stubs, and only
10
+ the public helper staticmethods stay inline here. All twenty-three agent-run
11
+ methods now live in the three ``agent_run`` sub-mixins.
12
+ """
2
13
 
3
14
  from __future__ import annotations
4
15
 
5
- import hashlib
6
- import json
7
- import re
8
- import unicodedata
9
- from dataclasses import dataclass, field
10
- from datetime import datetime
11
- from enum import StrEnum
12
- from typing import Any
13
-
14
- from reflexio.models.api_schema.pending_tool_call_schema import PendingToolCallStatus
15
-
16
- _WHITESPACE_RE = re.compile(r"\s+")
17
-
18
-
19
- class AgentRunStatus(StrEnum):
20
- RUNNING = "running"
21
- AGENT_COMPLETED = "agent_completed"
22
- FINALIZING = "finalizing"
23
- FINALIZED = "finalized"
24
- FINALIZED_PENDING_TOOL = "finalized_pending_tool"
25
- RESUME_READY = "resume_ready"
26
- RESUMING = "resuming"
27
- FINALIZATION_FAILED = "finalization_failed"
28
- FAILED = "failed"
29
- EXPIRED = "expired"
30
- CANCELLED = "cancelled"
31
-
32
-
33
- NOT_APPLICABLE_ANSWER = "User does not have information about this question."
34
-
35
-
36
- class RunToolDependencyKind(StrEnum):
37
- FOLLOWUP = "followup"
38
-
39
-
40
- @dataclass(frozen=True)
41
- class AgentBinding:
42
- """Logical run binding flattened into `_agent_runs` storage columns."""
43
-
44
- org_id: str
45
- extractor_kind: str
46
- user_id: str | None
47
- request_id: str
48
- agent_version: str | None
49
- source: str | None
50
- source_interaction_ids: list[int] = field(default_factory=list)
51
- window_start_interaction_id: int | None = None
52
- window_end_interaction_id: int | None = None
53
- extractor_config_hash: str | None = None
54
-
55
-
56
- @dataclass(frozen=True)
57
- class AgentRunRecord:
58
- id: str
59
- binding: AgentBinding
60
- status: AgentRunStatus
61
- generation_request_snapshot: dict[str, Any]
62
- service_config_snapshot: dict[str, Any] | None = None
63
- agent_context_snapshot: str | None = None
64
- committed_output: dict[str, Any] | None = None
65
- pending_tool_call_ids: list[str] = field(default_factory=list)
66
- max_steps_remaining: int | None = None
67
- resume_attempts: int = 0
68
- finalization_attempts: int = 0
69
- next_resume_at: datetime | None = None
70
- claimed_by: str | None = None
71
- claimed_at: datetime | None = None
72
- agent_completed_at: datetime | None = None
73
- finalized_at: datetime | None = None
74
- created_at: datetime | None = None
75
- updated_at: datetime | None = None
76
- expires_at: datetime | None = None
77
- last_error: str | None = None
78
-
79
-
80
- @dataclass(frozen=True)
81
- class PendingToolCallRecord:
82
- id: str
83
- org_id: str
84
- scope: dict[str, Any]
85
- scope_hash: str
86
- tool_name: str
87
- dedup_key: str
88
- status: PendingToolCallStatus
89
- question_text: str
90
- args: dict[str, Any] = field(default_factory=dict)
91
- tags: list[str] = field(default_factory=list)
92
- user_id: str | None = None
93
- answer_format: str | None = None
94
- result: dict[str, Any] | None = None
95
- embedding: list[float] | None = None
96
- superseded_by: str | None = None
97
- created_at: datetime | None = None
98
- resolved_at: datetime | None = None
99
- expires_at: datetime | None = None
100
- cache_until: datetime | None = None
101
- valid_until: datetime | None = None
102
-
103
-
104
- @dataclass(frozen=True)
105
- class RunToolDependencyRecord:
106
- run_id: str
107
- pending_tool_call_id: str
108
- dependency_kind: RunToolDependencyKind = RunToolDependencyKind.FOLLOWUP
109
- resolved_at: datetime | None = None
110
- consumed_at: datetime | None = None
111
- created_at: datetime | None = None
112
-
113
-
114
- @dataclass(frozen=True)
115
- class PendingToolCallUpsertResult:
116
- pending_tool_call: PendingToolCallRecord
117
- created: bool
118
-
119
-
120
- @dataclass(frozen=True)
121
- class PriorAnswerMatch:
122
- pending_tool_call_id: str
123
- status: PendingToolCallStatus
124
- question_text: str
125
- result: dict[str, Any] | None
126
- valid_until: datetime | None
127
- answer_format: str | None = None
128
- created_at: datetime | None = None
129
- resolved_at: datetime | None = None
130
- expires_at: datetime | None = None
131
- similarity: float | None = None
132
-
133
-
134
- def canonical_json(value: Any) -> str:
135
- """Return deterministic compact JSON for storage hashes."""
136
- return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
137
-
138
-
139
- def build_scope_hash(scope: dict[str, Any]) -> str:
140
- """Stable hash for a tool scope dictionary."""
141
- return hashlib.sha256(canonical_json(scope).encode("utf-8")).hexdigest()
142
-
143
-
144
- def human_feedback_scope(org_id: str) -> dict[str, str]:
145
- """Human feedback is always org-scoped, never user-scoped."""
146
- return {"org_id": org_id, "scope_kind": "org"}
147
-
148
-
149
- def normalize_dedup_text(value: str | None) -> str:
150
- """Normalize text before pending-tool-call dedup hashing."""
151
- if value is None:
152
- return ""
153
- normalized = unicodedata.normalize("NFKC", value)
154
- normalized = _WHITESPACE_RE.sub(" ", normalized.strip())
155
- return normalized.casefold()
156
-
157
-
158
- def build_pending_tool_call_dedup_key(
159
- *,
160
- tool_name: str,
161
- question_text: str,
162
- answer_format: str | None = None,
163
- ) -> str:
164
- """Stable dedup hash for a normalized tool question."""
165
- parts = (
166
- normalize_dedup_text(tool_name),
167
- normalize_dedup_text(question_text),
168
- normalize_dedup_text(answer_format),
169
- )
170
- return hashlib.sha256("\n".join(parts).encode("utf-8")).hexdigest()
171
-
172
-
173
- def not_applicable_tool_result() -> dict[str, Any]:
174
- return {"answer": NOT_APPLICABLE_ANSWER, "not_applicable": True}
175
-
176
-
177
- def is_not_applicable_tool_result(result: dict[str, Any] | None) -> bool:
178
- return isinstance(result, dict) and result.get("not_applicable") is True
179
-
180
-
181
- def embedding_similarity(a: list[float] | None, b: list[float] | None) -> float | None:
182
- """Cosine similarity for optional embedding vectors."""
183
- if not a or not b or len(a) != len(b):
184
- return None
185
- dot = sum(x * y for x, y in zip(a, b, strict=True))
186
- mag_a_sq = sum(x * x for x in a)
187
- mag_b_sq = sum(y * y for y in b)
188
- if mag_a_sq == 0.0 or mag_b_sq == 0.0:
189
- return None
190
- return dot / ((mag_a_sq**0.5) * (mag_b_sq**0.5))
191
-
192
-
193
- class AgentRunMixin:
16
+ from .agent_run import (
17
+ AgentRunStoreABC,
18
+ PendingToolCallStoreABC,
19
+ RunToolDependencyStoreABC,
20
+ )
21
+ from .agent_run._models import (
22
+ NOT_APPLICABLE_ANSWER,
23
+ AgentBinding,
24
+ AgentRunRecord,
25
+ AgentRunStatus,
26
+ PendingToolCallRecord,
27
+ PendingToolCallStatus,
28
+ PendingToolCallUpsertResult,
29
+ PriorAnswerMatch,
30
+ RunToolDependencyKind,
31
+ RunToolDependencyRecord,
32
+ build_pending_tool_call_dedup_key,
33
+ build_scope_hash,
34
+ canonical_json,
35
+ embedding_similarity,
36
+ human_feedback_scope,
37
+ is_not_applicable_tool_result,
38
+ normalize_dedup_text,
39
+ not_applicable_tool_result,
40
+ )
41
+
42
+ __all__ = [
43
+ "NOT_APPLICABLE_ANSWER",
44
+ "AgentBinding",
45
+ "AgentRunMixin",
46
+ "AgentRunRecord",
47
+ "AgentRunStatus",
48
+ "PendingToolCallRecord",
49
+ "PendingToolCallStatus",
50
+ "PendingToolCallUpsertResult",
51
+ "PriorAnswerMatch",
52
+ "RunToolDependencyKind",
53
+ "RunToolDependencyRecord",
54
+ "build_pending_tool_call_dedup_key",
55
+ "build_scope_hash",
56
+ "canonical_json",
57
+ "embedding_similarity",
58
+ "human_feedback_scope",
59
+ "is_not_applicable_tool_result",
60
+ "normalize_dedup_text",
61
+ "not_applicable_tool_result",
62
+ ]
63
+
64
+
65
+ class AgentRunMixin(
66
+ AgentRunStoreABC, PendingToolCallStoreABC, RunToolDependencyStoreABC
67
+ ):
194
68
  """Backend-neutral helpers shared by resumable extraction storage backends."""
195
69
 
196
70
  build_scope_hash = staticmethod(build_scope_hash)
197
71
  human_feedback_scope = staticmethod(human_feedback_scope)
198
72
  build_pending_tool_call_dedup_key = staticmethod(build_pending_tool_call_dedup_key)
199
-
200
- def create_agent_run(self, record: AgentRunRecord) -> AgentRunRecord:
201
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
202
-
203
- def get_agent_run(self, run_id: str) -> AgentRunRecord | None:
204
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
205
-
206
- def update_agent_run_status(
207
- self,
208
- run_id: str,
209
- status: AgentRunStatus,
210
- *,
211
- committed_output: dict[str, Any] | None = None,
212
- pending_tool_call_ids: list[str] | None = None,
213
- max_steps_remaining: int | None = None,
214
- next_resume_at: datetime | None = None,
215
- last_error: str | None = None,
216
- increment_finalization_attempts: bool = False,
217
- expected_statuses: tuple[AgentRunStatus, ...] | None = None,
218
- ) -> AgentRunRecord | None:
219
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
220
-
221
- def fail_running_agent_runs_for_request(
222
- self,
223
- *,
224
- org_id: str,
225
- extractor_kind: str,
226
- user_id: str | None,
227
- request_id: str,
228
- last_error: str,
229
- ) -> int:
230
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
231
-
232
- def create_pending_tool_call(
233
- self, record: PendingToolCallRecord
234
- ) -> PendingToolCallRecord:
235
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
236
-
237
- def create_or_attach_pending_tool_call(
238
- self,
239
- *,
240
- record: PendingToolCallRecord,
241
- dependency: RunToolDependencyRecord,
242
- now: datetime | None = None,
243
- ) -> PendingToolCallUpsertResult:
244
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
245
-
246
- def get_pending_tool_call(self, call_id: str) -> PendingToolCallRecord | None:
247
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
248
-
249
- def list_pending_tool_calls(
250
- self,
251
- *,
252
- status: PendingToolCallStatus | None = None,
253
- limit: int = 100,
254
- ) -> list[PendingToolCallRecord]:
255
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
256
-
257
- def cancel_pending_tool_call(
258
- self,
259
- call_id: str,
260
- *,
261
- cancelled_at: datetime | None = None,
262
- ) -> PendingToolCallRecord | None:
263
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
264
-
265
- def expire_pending_tool_calls(
266
- self,
267
- *,
268
- now: datetime | None = None,
269
- limit: int = 100,
270
- ) -> int:
271
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
272
-
273
- def find_active_pending_tool_call(
274
- self,
275
- *,
276
- org_id: str,
277
- scope_hash: str,
278
- tool_name: str,
279
- dedup_key: str,
280
- now: datetime | None = None,
281
- ) -> PendingToolCallRecord | None:
282
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
283
-
284
- def search_prior_tool_calls(
285
- self,
286
- *,
287
- org_id: str,
288
- scope_hash: str,
289
- tool_name: str,
290
- query_embedding: list[float] | None = None,
291
- now: datetime | None = None,
292
- limit: int = 8,
293
- ) -> list[PriorAnswerMatch]:
294
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
295
-
296
- def attach_run_tool_dependency(
297
- self, record: RunToolDependencyRecord
298
- ) -> RunToolDependencyRecord:
299
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
300
-
301
- def count_unresolved_followup_dependencies(
302
- self,
303
- *,
304
- org_id: str,
305
- extractor_kind: str,
306
- tool_name: str,
307
- ) -> int:
308
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
309
-
310
- def list_run_tool_dependencies(self, run_id: str) -> list[RunToolDependencyRecord]:
311
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
312
-
313
- def resolve_pending_tool_call(
314
- self,
315
- call_id: str,
316
- *,
317
- result: dict[str, Any],
318
- resolved_at: datetime | None = None,
319
- valid_for_seconds: int,
320
- ) -> PendingToolCallRecord | None:
321
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
322
-
323
- def update_resolved_pending_tool_call_result(
324
- self,
325
- call_id: str,
326
- *,
327
- result: dict[str, Any],
328
- resolved_at: datetime | None = None,
329
- valid_for_seconds: int,
330
- ) -> PendingToolCallRecord | None:
331
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
332
-
333
- def mark_pending_tool_call_not_applicable(
334
- self,
335
- call_id: str,
336
- *,
337
- resolved_at: datetime | None = None,
338
- valid_for_seconds: int,
339
- ) -> PendingToolCallRecord | None:
340
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
341
-
342
- def claim_ready_agent_run(
343
- self,
344
- *,
345
- org_id: str,
346
- worker_id: str,
347
- now: datetime | None = None,
348
- claim_ttl_seconds: int = 600,
349
- ) -> AgentRunRecord | None:
350
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
351
-
352
- def claim_finalization_failed_agent_run(
353
- self,
354
- *,
355
- org_id: str,
356
- worker_id: str,
357
- now: datetime | None = None,
358
- claim_ttl_seconds: int = 600,
359
- ) -> AgentRunRecord | None:
360
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
361
-
362
- def list_resumable_work_org_ids(
363
- self,
364
- *,
365
- now: datetime | None = None,
366
- limit: int = 1000,
367
- ) -> list[str]:
368
- """Return distinct org_ids that have actionable resumable-extraction work.
369
-
370
- Cross-org maintenance query (intentionally NOT scoped to ``self.org_id``):
371
- the resume scheduler uses it to discover every org that has a run ready
372
- to resume, a run awaiting finalization retry, or a pending tool call that
373
- can be expired, so per-org workers can be driven for all of them.
374
- """
375
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
376
-
377
- def consume_run_tool_dependencies(self, run_id: str) -> int:
378
- raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
@@ -91,3 +91,23 @@ class ShareLinkMixin:
91
91
  int: Number of links deleted.
92
92
  """
93
93
  raise NotImplementedError
94
+
95
+ @abstractmethod
96
+ def delete_expired_share_links(
97
+ self, *, now: int, grace_seconds: int, limit: int = 1000
98
+ ) -> int:
99
+ """Physically delete share links whose expires_at < now - grace_seconds.
100
+
101
+ Rows where expires_at IS NULL (never expire) are always preserved.
102
+
103
+ Args:
104
+ now (int): Current Unix epoch timestamp.
105
+ grace_seconds (int): Additional grace window; only rows with
106
+ expires_at < (now - grace_seconds) are deleted.
107
+ limit (int): Maximum number of rows to delete in one call.
108
+ Rows are processed in expires_at ASC order (oldest first).
109
+
110
+ Returns:
111
+ int: Number of rows physically deleted.
112
+ """
113
+ raise NotImplementedError
@@ -0,0 +1,9 @@
1
+ from ._agent_run_store import AgentRunStoreABC
2
+ from ._pending_tool_call_store import PendingToolCallStoreABC
3
+ from ._run_tool_dependency_store import RunToolDependencyStoreABC
4
+
5
+ __all__ = [
6
+ "AgentRunStoreABC",
7
+ "PendingToolCallStoreABC",
8
+ "RunToolDependencyStoreABC",
9
+ ]
@@ -0,0 +1,86 @@
1
+ """Backend-neutral AgentRunStore contract (the AgentRunStore bucket).
2
+
3
+ Extracted verbatim from ``_agent_run.py`` (the AgentRunStore bucket): the seven
4
+ agent-run lifecycle methods. The residual ``AgentRunMixin`` composite stays
5
+ composed alongside this class and holds the remaining pending-tool-call /
6
+ run-tool-dependency stubs plus the shared ``build_scope_hash`` /
7
+ ``human_feedback_scope`` / ``build_pending_tool_call_dedup_key`` staticmethods.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from datetime import datetime
13
+ from typing import Any
14
+
15
+ from ._models import AgentRunRecord, AgentRunStatus
16
+
17
+
18
+ class AgentRunStoreABC:
19
+ """Backend-neutral agent-run lifecycle store contract."""
20
+
21
+ def create_agent_run(self, record: AgentRunRecord) -> AgentRunRecord:
22
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
23
+
24
+ def get_agent_run(self, run_id: str) -> AgentRunRecord | None:
25
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
26
+
27
+ def update_agent_run_status(
28
+ self,
29
+ run_id: str,
30
+ status: AgentRunStatus,
31
+ *,
32
+ committed_output: dict[str, Any] | None = None,
33
+ pending_tool_call_ids: list[str] | None = None,
34
+ max_steps_remaining: int | None = None,
35
+ next_resume_at: datetime | None = None,
36
+ last_error: str | None = None,
37
+ increment_finalization_attempts: bool = False,
38
+ expected_statuses: tuple[AgentRunStatus, ...] | None = None,
39
+ ) -> AgentRunRecord | None:
40
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
41
+
42
+ def fail_running_agent_runs_for_request(
43
+ self,
44
+ *,
45
+ org_id: str,
46
+ extractor_kind: str,
47
+ user_id: str | None,
48
+ request_id: str,
49
+ last_error: str,
50
+ ) -> int:
51
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
52
+
53
+ def claim_ready_agent_run(
54
+ self,
55
+ *,
56
+ org_id: str,
57
+ worker_id: str,
58
+ now: datetime | None = None,
59
+ claim_ttl_seconds: int = 600,
60
+ ) -> AgentRunRecord | None:
61
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
62
+
63
+ def claim_finalization_failed_agent_run(
64
+ self,
65
+ *,
66
+ org_id: str,
67
+ worker_id: str,
68
+ now: datetime | None = None,
69
+ claim_ttl_seconds: int = 600,
70
+ ) -> AgentRunRecord | None:
71
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")
72
+
73
+ def list_resumable_work_org_ids(
74
+ self,
75
+ *,
76
+ now: datetime | None = None,
77
+ limit: int = 1000,
78
+ ) -> list[str]:
79
+ """Return distinct org_ids that have actionable resumable-extraction work.
80
+
81
+ Cross-org maintenance query (intentionally NOT scoped to ``self.org_id``):
82
+ the resume scheduler uses it to discover every org that has a run ready
83
+ to resume, a run awaiting finalization retry, or a pending tool call that
84
+ can be expired, so per-org workers can be driven for all of them.
85
+ """
86
+ raise NotImplementedError(f"{type(self).__name__} does not support agent runs")