claude-smart 0.2.48 → 0.2.50
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/README.md +11 -40
- package/bin/claude-smart.js +393 -55
- package/package.json +3 -2
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/.coverage +0 -0
- package/plugin/README.md +4 -3
- package/plugin/dashboard/app/api/reflexio/[...path]/route.ts +4 -2
- package/plugin/dashboard/app/dashboard/page.tsx +6 -1
- package/plugin/dashboard/app/preferences/[id]/page.tsx +18 -6
- package/plugin/dashboard/app/preferences/page.tsx +32 -35
- package/plugin/dashboard/app/sessions/[sessionId]/page.tsx +16 -1
- package/plugin/dashboard/app/sessions/page.tsx +2 -0
- package/plugin/dashboard/app/skills/page.tsx +65 -50
- package/plugin/dashboard/app/skills/project/[id]/page.tsx +17 -8
- package/plugin/dashboard/app/skills/shared/[id]/page.tsx +1 -6
- package/plugin/dashboard/components/common/host-badge.tsx +118 -0
- package/plugin/dashboard/components/common/learning-application-badge.tsx +34 -0
- package/plugin/dashboard/components/common/learnings-badge.tsx +1 -1
- package/plugin/dashboard/components/common/page-header.tsx +3 -3
- package/plugin/dashboard/lib/config-file.ts +5 -1
- package/plugin/dashboard/lib/host-attribution.ts +62 -0
- package/plugin/dashboard/lib/session-reader.ts +40 -2
- package/plugin/dashboard/lib/types.ts +7 -1
- package/plugin/opencode/dist/server.mjs +60 -2
- package/plugin/opencode/server.mts +64 -2
- package/plugin/pyproject.toml +2 -2
- package/plugin/scripts/_lib.sh +255 -7
- package/plugin/scripts/backend-python-runner.py +46 -0
- package/plugin/scripts/backend-service.sh +766 -123
- package/plugin/scripts/codex-hook.js +79 -229
- package/plugin/scripts/dashboard-open.sh +6 -4
- package/plugin/scripts/dashboard-service.sh +118 -137
- package/plugin/scripts/ensure-plugin-root.sh +106 -8
- package/plugin/scripts/hook_entry.sh +3 -0
- package/plugin/scripts/opencode-claude-compat.js +8 -1
- package/plugin/scripts/smart-install.sh +116 -21
- package/plugin/src/README.md +1 -1
- package/plugin/src/claude_smart/cli.py +93 -29
- package/plugin/src/claude_smart/context_inject.py +3 -0
- package/plugin/src/claude_smart/env_config.py +56 -11
- package/plugin/src/claude_smart/events/post_tool.py +2 -1
- package/plugin/src/claude_smart/events/session_end.py +2 -1
- package/plugin/src/claude_smart/events/stop.py +3 -0
- package/plugin/src/claude_smart/events/user_prompt.py +2 -1
- package/plugin/src/claude_smart/internal_call.py +5 -2
- package/plugin/src/claude_smart/optimizer_assistant.py +59 -13
- package/plugin/src/claude_smart/publish.py +59 -7
- package/plugin/src/claude_smart/reflexio_adapter.py +137 -14
- package/plugin/src/claude_smart/runtime.py +15 -6
- package/plugin/src/claude_smart/state.py +211 -52
- package/plugin/uv.lock +5 -5
- package/plugin/vendor/reflexio/.env.example +13 -0
- package/plugin/vendor/reflexio/reflexio/README.md +7 -3
- package/plugin/vendor/reflexio/reflexio/__init__.py +12 -0
- package/plugin/vendor/reflexio/reflexio/cli/README.md +3 -0
- package/plugin/vendor/reflexio/reflexio/client/client.py +166 -9
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/src/openclaw_smart/state.py +10 -3
- package/plugin/vendor/reflexio/reflexio/integrations/openclaw/plugin/tests/test_state.py +28 -0
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +41 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/entities.py +195 -25
- package/plugin/vendor/reflexio/reflexio/models/api_schema/eval_overview_schema.py +7 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/internal_schema.py +2 -1
- package/plugin/vendor/reflexio/reflexio/models/api_schema/retriever_schema.py +63 -4
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/converters.py +1 -0
- package/plugin/vendor/reflexio/reflexio/models/api_schema/ui/entities.py +8 -1
- package/plugin/vendor/reflexio/reflexio/models/config_schema.py +1 -1
- package/plugin/vendor/reflexio/reflexio/server/README.md +22 -4
- package/plugin/vendor/reflexio/reflexio/server/__init__.py +18 -8
- package/plugin/vendor/reflexio/reflexio/server/__main__.py +6 -0
- package/plugin/vendor/reflexio/reflexio/server/api.py +79 -5
- package/plugin/vendor/reflexio/reflexio/server/billing_meter.py +263 -3
- package/plugin/vendor/reflexio/reflexio/server/callback_executor.py +164 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_embedding.py +81 -81
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_subprocess.py +28 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_text_generation.py +63 -6
- package/plugin/vendor/reflexio/reflexio/server/llm/embedding_service.py +19 -52
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +1 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/model_defaults.py +28 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +9 -1
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedder_warmup.py +329 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/embedding_service_provider.py +85 -10
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/local_embedding_provider.py +199 -2
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/nomic_embedding_provider.py +77 -9
- package/plugin/vendor/reflexio/reflexio/server/org_fanout.py +184 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.0.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/document_expansion/v1.1.0.prompt.md +32 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.3.3.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/playbook_consolidation/v2.4.0.prompt.md +63 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v1.0.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/query_reformulation/v2.0.0.prompt.md +30 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/retrieved_learning_impact/v1.0.0.prompt.md +51 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/retrieved_learning_relevance/v1.0.0.prompt.md +39 -0
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.0.0.prompt.md +1 -1
- package/plugin/vendor/reflexio/reflexio/server/prompt/prompt_bank/shadow_comparison/v1.1.0.prompt.md +43 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/config.py +3 -3
- package/plugin/vendor/reflexio/reflexio/server/routes/evaluation.py +122 -28
- package/plugin/vendor/reflexio/reflexio/server/routes/interactions.py +63 -2
- package/plugin/vendor/reflexio/reflexio/server/routes/system.py +22 -3
- package/plugin/vendor/reflexio/reflexio/server/scheduling.py +64 -3
- package/plugin/vendor/reflexio/reflexio/server/services/README.md +6 -4
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/README.md +3 -2
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/_eval_health.py +41 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/components/retrieved_learning_evaluator.py +554 -0
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/regen_jobs.py +35 -1
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/runner.py +253 -101
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/scheduler.py +5 -7
- package/plugin/vendor/reflexio/reflexio/server/services/agent_success_evaluation/service.py +27 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_extraction_lifecycle.py +11 -5
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_should_run.py +4 -4
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_usage_billing.py +6 -2
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +255 -74
- package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +72 -0
- package/plugin/vendor/reflexio/reflexio/server/services/deferred_learning_plan.py +270 -0
- package/plugin/vendor/reflexio/reflexio/server/services/durable_learning/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/durable_learning/scheduler.py +142 -0
- package/plugin/vendor/reflexio/reflexio/server/services/durable_learning/worker.py +262 -0
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/components/hero_state.py +2 -11
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/components/rule_attribution.py +6 -2
- package/plugin/vendor/reflexio/reflexio/server/services/evaluation_overview/service.py +17 -13
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/agent_run_records.py +18 -3
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/outcome.py +12 -1
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/prior_answer_search.py +1 -1
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resumable_agent.py +2 -1
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +1 -3
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_worker.py +66 -0
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +640 -80
- package/plugin/vendor/reflexio/reflexio/server/services/governance/service.py +2 -0
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +179 -99
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/vector_backfill_sweep.py +139 -0
- package/plugin/vendor/reflexio/reflexio/server/services/operation_state_utils.py +66 -27
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/aggregation_trigger.py +177 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator.py +68 -2
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/consolidator.py +360 -49
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/extractor.py +27 -30
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/playbook_edit_apply.py +8 -1
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/service.py +137 -69
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/optimizer.py +20 -1
- package/plugin/vendor/reflexio/reflexio/server/services/playbook_optimizer/scheduler.py +13 -6
- package/plugin/vendor/reflexio/reflexio/server/services/pre_retrieval/_query_reformulator.py +40 -25
- package/plugin/vendor/reflexio/reflexio/server/services/profile/components/consolidator.py +12 -39
- package/plugin/vendor/reflexio/reflexio/server/services/profile/components/extractor.py +30 -35
- package/plugin/vendor/reflexio/reflexio/server/services/profile/service.py +166 -66
- package/plugin/vendor/reflexio/reflexio/server/services/reflection/service.py +457 -107
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/session_dedup.py +127 -0
- package/plugin/vendor/reflexio/reflexio/server/services/retrieval/temporal.py +104 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/dispatcher.py +139 -0
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/judge.py +16 -6
- package/plugin/vendor/reflexio/reflexio/server/services/shadow_comparison/worker.py +137 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/governance_validation.py +12 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/lifecycle_filters.py +54 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention.py +41 -3
- package/plugin/vendor/reflexio/reflexio/server/services/storage/retention_mixin.py +40 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +2 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +190 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_extras.py +11 -4
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_governance.py +28 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_learning_jobs.py +414 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +11 -5
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_requests.py +8 -3
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_shadow_verdicts.py +4 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/_deletion.py +16 -5
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/_fts_vec.py +86 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_erase_execution.py +104 -42
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_subject_barrier.py +7 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_agent.py +59 -7
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_eval_results.py +430 -5
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_source_linkage.py +8 -3
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_user.py +57 -12
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_interaction_store.py +197 -12
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_profile_store.py +70 -11
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +17 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_commit_scope.py +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_extras.py +9 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_learning_jobs.py +269 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_operations.py +7 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_retrieval_log.py +3 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_shadow_verdicts.py +4 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_models.py +12 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/evaluation_state_keys.py +78 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_agent.py +38 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_eval_results.py +171 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/playbook/_user.py +52 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/_interaction_store.py +82 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/_profile_store.py +74 -2
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/retrieved_learning_state.py +226 -0
- package/plugin/vendor/reflexio/reflexio/server/services/tagging/tagging_scheduler.py +5 -6
- package/plugin/vendor/reflexio/reflexio/server/services/unified_search_service.py +209 -29
- package/plugin/vendor/reflexio/reflexio/server/usage_metrics.py +3 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_mock.py +61 -0
- package/plugin/vendor/reflexio/reflexio/test_support/llm_model_registry.py +33 -0
- package/plugin/vendor/reflexio/reflexio/server/services/search/__init__.py +0 -0
|
@@ -30,7 +30,6 @@ resolve through the composed MRO.
|
|
|
30
30
|
|
|
31
31
|
from __future__ import annotations
|
|
32
32
|
|
|
33
|
-
import json
|
|
34
33
|
import sqlite3
|
|
35
34
|
import threading
|
|
36
35
|
from collections.abc import Callable
|
|
@@ -50,6 +49,14 @@ from reflexio.server.services.storage.governance_validation import (
|
|
|
50
49
|
_successful_erase_identity,
|
|
51
50
|
_validate_governance_purge_id,
|
|
52
51
|
)
|
|
52
|
+
from reflexio.server.services.storage.storage_base.evaluation_state_keys import (
|
|
53
|
+
GRADE_ON_DEMAND_CACHE_PREFIX,
|
|
54
|
+
build_agent_success_marker_key,
|
|
55
|
+
build_grade_on_demand_session_prefix,
|
|
56
|
+
)
|
|
57
|
+
from reflexio.server.services.storage.storage_base.retrieved_learning_state import (
|
|
58
|
+
build_retrieved_learning_state_key,
|
|
59
|
+
)
|
|
53
60
|
|
|
54
61
|
from .._governance import _row_to_audit_event, _row_to_purge_operation
|
|
55
62
|
|
|
@@ -157,13 +164,6 @@ class GovernanceEraseExecutionMixin:
|
|
|
157
164
|
raise ValueError(
|
|
158
165
|
"Current user playbooks no longer match prepared purge snapshot"
|
|
159
166
|
)
|
|
160
|
-
request_ids = [
|
|
161
|
-
str(row["request_id"])
|
|
162
|
-
for row in self.conn.execute(
|
|
163
|
-
"SELECT request_id FROM requests WHERE user_id = ?",
|
|
164
|
-
(user_id,),
|
|
165
|
-
).fetchall()
|
|
166
|
-
]
|
|
167
167
|
profile_rows = self.conn.execute(
|
|
168
168
|
"SELECT rowid, profile_id FROM profiles WHERE user_id = ?",
|
|
169
169
|
(user_id,),
|
|
@@ -183,40 +183,12 @@ class GovernanceEraseExecutionMixin:
|
|
|
183
183
|
)
|
|
184
184
|
purge_upb_ids = [int(entity_id) for entity_id in purge_upb_str_ids]
|
|
185
185
|
delete_upb_ids = [int(entity_id) for entity_id in delete_upb_str_ids]
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if erased_entity_ids:
|
|
193
|
-
erased_entity_id_set = set(erased_entity_ids)
|
|
194
|
-
lineage_source_event_ids: list[int] = []
|
|
195
|
-
for row in self.conn.execute(
|
|
196
|
-
"SELECT event_id, source_ids FROM lineage_event WHERE org_id = ?",
|
|
197
|
-
(self.org_id,),
|
|
198
|
-
).fetchall():
|
|
199
|
-
try:
|
|
200
|
-
source_ids = json.loads(str(row["source_ids"] or "[]"))
|
|
201
|
-
except json.JSONDecodeError:
|
|
202
|
-
source_ids = []
|
|
203
|
-
if any(
|
|
204
|
-
str(source_id) in erased_entity_id_set for source_id in source_ids
|
|
205
|
-
):
|
|
206
|
-
lineage_source_event_ids.append(int(row["event_id"]))
|
|
207
|
-
deps._delete_in_chunks(
|
|
208
|
-
"lineage_event", "event_id", lineage_source_event_ids
|
|
209
|
-
)
|
|
210
|
-
placeholders = ",".join("?" for _ in erased_entity_ids)
|
|
211
|
-
self.conn.execute(
|
|
212
|
-
f"""DELETE FROM lineage_event
|
|
213
|
-
WHERE org_id = ?
|
|
214
|
-
AND (
|
|
215
|
-
request_id IN ({placeholders})
|
|
216
|
-
OR entity_id IN ({placeholders})
|
|
217
|
-
)""", # noqa: S608
|
|
218
|
-
[self.org_id, *erased_entity_ids, *erased_entity_ids],
|
|
219
|
-
)
|
|
186
|
+
# SEC-016: retain the content-free lineage_event skeleton on erase to
|
|
187
|
+
# match Supabase (which never enumerates lineage_event for erasure).
|
|
188
|
+
# lineage_event has no PII/content column, no foreign keys, and no
|
|
189
|
+
# FTS/vec shadow tables, so leaving these rows in place is safe and
|
|
190
|
+
# preserves the audit/lineage skeleton. Content-bearing entities are
|
|
191
|
+
# still deleted/purged below.
|
|
220
192
|
delete_profile_rowids = [
|
|
221
193
|
profile_rowid_by_id[profile_id]
|
|
222
194
|
for profile_id in delete_profile_ids
|
|
@@ -240,6 +212,23 @@ class GovernanceEraseExecutionMixin:
|
|
|
240
212
|
WHERE user_id = ?""",
|
|
241
213
|
(user_id,),
|
|
242
214
|
)
|
|
215
|
+
rle_results_cur = self.conn.execute(
|
|
216
|
+
"""DELETE FROM retrieved_learning_evaluation
|
|
217
|
+
WHERE user_id = ?""",
|
|
218
|
+
(user_id,),
|
|
219
|
+
)
|
|
220
|
+
# Snapshot the user's session ids BEFORE requests are deleted — the
|
|
221
|
+
# evaluation _operation_state namespaces are keyed by session.
|
|
222
|
+
session_ids = [
|
|
223
|
+
str(row["session_id"])
|
|
224
|
+
for row in self.conn.execute(
|
|
225
|
+
"SELECT DISTINCT session_id FROM requests WHERE user_id = ?",
|
|
226
|
+
(user_id,),
|
|
227
|
+
).fetchall()
|
|
228
|
+
]
|
|
229
|
+
eval_operation_states = self._delete_evaluation_operation_states_locked(
|
|
230
|
+
user_id, session_ids
|
|
231
|
+
)
|
|
243
232
|
requests_cur = self.conn.execute(
|
|
244
233
|
"DELETE FROM requests WHERE user_id = ?",
|
|
245
234
|
(user_id,),
|
|
@@ -280,10 +269,75 @@ class GovernanceEraseExecutionMixin:
|
|
|
280
269
|
"profiles": len(delete_profile_ids),
|
|
281
270
|
"requests": requests_cur.rowcount,
|
|
282
271
|
"agent_success_evaluation_results": eval_results_cur.rowcount,
|
|
272
|
+
# Enterprise-only tables absent from the OSS SQLite backend;
|
|
273
|
+
# reported as zero so the delete target matrix stays complete.
|
|
274
|
+
"offline_tuner_reward_labels": 0,
|
|
275
|
+
"offline_tuner_reward_label_targets_by_target_owner": 0,
|
|
276
|
+
"retrieved_learning_evaluation_results": rle_results_cur.rowcount,
|
|
277
|
+
"evaluation_operation_states": eval_operation_states,
|
|
283
278
|
"purged_profiles": purged_profiles,
|
|
284
279
|
"purged_user_playbooks": purged_user_playbooks,
|
|
285
280
|
}
|
|
286
281
|
|
|
282
|
+
def _delete_evaluation_operation_states_locked(
|
|
283
|
+
self, user_id: str, session_ids: list[str]
|
|
284
|
+
) -> int:
|
|
285
|
+
"""Scrub the three evaluation ``_operation_state`` namespaces.
|
|
286
|
+
|
|
287
|
+
Deletes, for every session the user owns: the retrieved-learning
|
|
288
|
+
generation/completion state, the ``agent_success_group_eval`` marker
|
|
289
|
+
(pre-existing RTBF gap), and the ``grade_on_demand`` cache rows
|
|
290
|
+
(pre-existing RTBF gap). Exact keys are used for the first two; the
|
|
291
|
+
grade cache is matched by the injective per-session key prefix so any
|
|
292
|
+
agent_version / evaluation_name variant is covered.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
int: Number of state rows deleted.
|
|
296
|
+
"""
|
|
297
|
+
if not session_ids:
|
|
298
|
+
return 0
|
|
299
|
+
deleted = 0
|
|
300
|
+
exact_keys = [
|
|
301
|
+
build_retrieved_learning_state_key(user_id, session_id)
|
|
302
|
+
for session_id in session_ids
|
|
303
|
+
] + [
|
|
304
|
+
build_agent_success_marker_key(self.org_id, user_id, session_id)
|
|
305
|
+
for session_id in session_ids
|
|
306
|
+
]
|
|
307
|
+
chunk_size = 500
|
|
308
|
+
for start in range(0, len(exact_keys), chunk_size):
|
|
309
|
+
chunk = exact_keys[start : start + chunk_size]
|
|
310
|
+
placeholders = ",".join("?" for _ in chunk)
|
|
311
|
+
cur = self.conn.execute(
|
|
312
|
+
f"DELETE FROM _operation_state WHERE service_name IN ({placeholders})", # noqa: S608
|
|
313
|
+
chunk,
|
|
314
|
+
)
|
|
315
|
+
deleted += cur.rowcount
|
|
316
|
+
# Grade-cache keys embed agent_version/evaluation_name, so enumerate
|
|
317
|
+
# the namespace and match each session's injective prefix in Python
|
|
318
|
+
# (LIKE-escaping free-form session ids is not safe).
|
|
319
|
+
prefixes = tuple(
|
|
320
|
+
build_grade_on_demand_session_prefix(self.org_id, session_id)
|
|
321
|
+
for session_id in session_ids
|
|
322
|
+
)
|
|
323
|
+
grade_keys = [
|
|
324
|
+
str(row["service_name"])
|
|
325
|
+
for row in self.conn.execute(
|
|
326
|
+
"SELECT service_name FROM _operation_state WHERE service_name LIKE ?",
|
|
327
|
+
(f"{GRADE_ON_DEMAND_CACHE_PREFIX}::%",),
|
|
328
|
+
).fetchall()
|
|
329
|
+
if str(row["service_name"]).startswith(prefixes)
|
|
330
|
+
]
|
|
331
|
+
for start in range(0, len(grade_keys), chunk_size):
|
|
332
|
+
chunk = grade_keys[start : start + chunk_size]
|
|
333
|
+
placeholders = ",".join("?" for _ in chunk)
|
|
334
|
+
cur = self.conn.execute(
|
|
335
|
+
f"DELETE FROM _operation_state WHERE service_name IN ({placeholders})", # noqa: S608
|
|
336
|
+
chunk,
|
|
337
|
+
)
|
|
338
|
+
deleted += cur.rowcount
|
|
339
|
+
return deleted
|
|
340
|
+
|
|
287
341
|
def apply_governance_user_data_delete(
|
|
288
342
|
self, purge_id: str, user_id: str
|
|
289
343
|
) -> dict[str, int]:
|
|
@@ -294,6 +348,14 @@ class GovernanceEraseExecutionMixin:
|
|
|
294
348
|
"profiles": "profile",
|
|
295
349
|
"requests": "request",
|
|
296
350
|
"agent_success_evaluation_results": "agent_success_evaluation_result",
|
|
351
|
+
"offline_tuner_reward_labels": "offline_tuner_reward_label",
|
|
352
|
+
"offline_tuner_reward_label_targets_by_target_owner": (
|
|
353
|
+
"offline_tuner_reward_label_target_by_target_owner"
|
|
354
|
+
),
|
|
355
|
+
"retrieved_learning_evaluation_results": (
|
|
356
|
+
"retrieved_learning_evaluation_result"
|
|
357
|
+
),
|
|
358
|
+
"evaluation_operation_states": "evaluation_operation_state",
|
|
297
359
|
"purged_profiles": "profile_purge",
|
|
298
360
|
"purged_user_playbooks": "user_playbook_purge",
|
|
299
361
|
}
|
|
@@ -166,6 +166,7 @@ class SubjectBarrierMixin:
|
|
|
166
166
|
"profiles",
|
|
167
167
|
"user_playbooks",
|
|
168
168
|
"agent_success_evaluation_result",
|
|
169
|
+
"retrieved_learning_evaluation",
|
|
169
170
|
):
|
|
170
171
|
row = self.conn.execute(
|
|
171
172
|
f"""SELECT 1 FROM {table}
|
|
@@ -198,9 +199,14 @@ class SubjectBarrierMixin:
|
|
|
198
199
|
request_id_column="request_id",
|
|
199
200
|
):
|
|
200
201
|
return True
|
|
201
|
-
|
|
202
|
+
if self._legacy_user_id_rows_remain_locked(
|
|
202
203
|
table="agent_success_evaluation_result",
|
|
203
204
|
subject_ref=subject_ref,
|
|
205
|
+
):
|
|
206
|
+
return True
|
|
207
|
+
return self._legacy_user_id_rows_remain_locked(
|
|
208
|
+
table="retrieved_learning_evaluation",
|
|
209
|
+
subject_ref=subject_ref,
|
|
204
210
|
)
|
|
205
211
|
|
|
206
212
|
def begin_subject_erasure_barrier(
|
package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_agent.py
CHANGED
|
@@ -19,6 +19,9 @@ from reflexio.models.api_schema.service_schemas import (
|
|
|
19
19
|
Status,
|
|
20
20
|
)
|
|
21
21
|
from reflexio.models.config_schema import SearchMode, SearchOptions
|
|
22
|
+
from reflexio.server.services.storage.lifecycle_filters import (
|
|
23
|
+
validate_include_inactive,
|
|
24
|
+
)
|
|
22
25
|
from reflexio.server.services.storage.storage_base._playbook import (
|
|
23
26
|
AGGREGATE_REASON_PREFIX,
|
|
24
27
|
)
|
|
@@ -87,6 +90,7 @@ class AgentPlaybookStoreMixin:
|
|
|
87
90
|
_fts_upsert: Any
|
|
88
91
|
_vec_upsert: Any
|
|
89
92
|
_delete_playbook_search_rows: Any
|
|
93
|
+
_own_transaction: Any
|
|
90
94
|
|
|
91
95
|
def _index_agent_playbook_fts_vec(self, ap: AgentPlaybook) -> None:
|
|
92
96
|
"""Update the FTS and vector indexes for a single agent playbook row.
|
|
@@ -178,7 +182,8 @@ class AgentPlaybookStoreMixin:
|
|
|
178
182
|
created_at_iso = _epoch_to_iso(ap.created_at)
|
|
179
183
|
with self._lock:
|
|
180
184
|
self._insert_agent_playbook_row(self.conn, ap, created_at_iso)
|
|
181
|
-
self.
|
|
185
|
+
if self._own_transaction():
|
|
186
|
+
self.conn.commit()
|
|
182
187
|
|
|
183
188
|
self._index_agent_playbook_fts_vec(ap)
|
|
184
189
|
saved.append(ap)
|
|
@@ -228,6 +233,7 @@ class AgentPlaybookStoreMixin:
|
|
|
228
233
|
|
|
229
234
|
created_at_iso = _epoch_to_iso(ap.created_at)
|
|
230
235
|
with self._lock:
|
|
236
|
+
own_txn = self._own_transaction()
|
|
231
237
|
try:
|
|
232
238
|
self._insert_agent_playbook_row(self.conn, ap, created_at_iso)
|
|
233
239
|
_append_event_stmt(
|
|
@@ -242,9 +248,11 @@ class AgentPlaybookStoreMixin:
|
|
|
242
248
|
request_id=request_id,
|
|
243
249
|
reason=f"{AGGREGATE_REASON_PREFIX}{run_mode}",
|
|
244
250
|
)
|
|
245
|
-
|
|
251
|
+
if own_txn:
|
|
252
|
+
self.conn.commit()
|
|
246
253
|
except Exception:
|
|
247
|
-
|
|
254
|
+
if own_txn:
|
|
255
|
+
self.conn.rollback()
|
|
248
256
|
raise
|
|
249
257
|
|
|
250
258
|
# FTS/vec indexing AFTER commit — these helpers self-commit and must
|
|
@@ -339,6 +347,46 @@ class AgentPlaybookStoreMixin:
|
|
|
339
347
|
row = self._fetchone(sql, (agent_playbook_id,))
|
|
340
348
|
return _row_to_agent_playbook(row) if row else None
|
|
341
349
|
|
|
350
|
+
@SQLiteStorageBase.handle_exceptions
|
|
351
|
+
def get_agent_playbooks_by_ids(
|
|
352
|
+
self,
|
|
353
|
+
agent_playbook_ids: list[int],
|
|
354
|
+
*,
|
|
355
|
+
status_filter: list[Status | None] | None = None,
|
|
356
|
+
playbook_status_filter: list[PlaybookStatus] | None = None,
|
|
357
|
+
include_inactive: bool = False,
|
|
358
|
+
) -> list[AgentPlaybook]:
|
|
359
|
+
validate_include_inactive(
|
|
360
|
+
include_inactive=include_inactive,
|
|
361
|
+
status_filter=status_filter,
|
|
362
|
+
playbook_status_filter=playbook_status_filter,
|
|
363
|
+
)
|
|
364
|
+
if not agent_playbook_ids:
|
|
365
|
+
return []
|
|
366
|
+
unique_ids = list(dict.fromkeys(agent_playbook_ids))
|
|
367
|
+
rows: list[sqlite3.Row] = []
|
|
368
|
+
for start in range(0, len(unique_ids), 900):
|
|
369
|
+
chunk = unique_ids[start : start + 900]
|
|
370
|
+
placeholders = ",".join("?" for _ in chunk)
|
|
371
|
+
query = (
|
|
372
|
+
"SELECT * FROM agent_playbooks "
|
|
373
|
+
f"WHERE agent_playbook_id IN ({placeholders})"
|
|
374
|
+
)
|
|
375
|
+
params: list[Any] = list(chunk)
|
|
376
|
+
if not include_inactive:
|
|
377
|
+
if status_filter is not None:
|
|
378
|
+
fragment, status_params = _build_status_sql(status_filter)
|
|
379
|
+
query += f" AND {fragment}"
|
|
380
|
+
params.extend(status_params)
|
|
381
|
+
else:
|
|
382
|
+
query += " AND status IS NULL"
|
|
383
|
+
if playbook_status_filter:
|
|
384
|
+
status_placeholders = ",".join("?" for _ in playbook_status_filter)
|
|
385
|
+
query += f" AND playbook_status IN ({status_placeholders})"
|
|
386
|
+
params.extend(status.value for status in playbook_status_filter)
|
|
387
|
+
rows.extend(self._fetchall(query, params))
|
|
388
|
+
return [_row_to_agent_playbook(row) for row in rows]
|
|
389
|
+
|
|
342
390
|
@SQLiteStorageBase.handle_exceptions
|
|
343
391
|
def delete_all_agent_playbooks(self) -> None:
|
|
344
392
|
batch_request_id = uuid.uuid4().hex
|
|
@@ -609,7 +657,8 @@ class AgentPlaybookStoreMixin:
|
|
|
609
657
|
to_status="archived",
|
|
610
658
|
status_namespace="lifecycle_status",
|
|
611
659
|
)
|
|
612
|
-
self.
|
|
660
|
+
if self._own_transaction():
|
|
661
|
+
self.conn.commit()
|
|
613
662
|
|
|
614
663
|
@SQLiteStorageBase.handle_exceptions
|
|
615
664
|
def archive_agent_playbooks_by_ids(self, agent_playbook_ids: list[int]) -> None:
|
|
@@ -648,7 +697,8 @@ class AgentPlaybookStoreMixin:
|
|
|
648
697
|
to_status="archived",
|
|
649
698
|
status_namespace="lifecycle_status",
|
|
650
699
|
)
|
|
651
|
-
self.
|
|
700
|
+
if self._own_transaction():
|
|
701
|
+
self.conn.commit()
|
|
652
702
|
|
|
653
703
|
@SQLiteStorageBase.handle_exceptions
|
|
654
704
|
def supersede_agent_playbooks_by_ids(
|
|
@@ -712,7 +762,8 @@ class AgentPlaybookStoreMixin:
|
|
|
712
762
|
request_id=request_id,
|
|
713
763
|
)
|
|
714
764
|
updated += 1
|
|
715
|
-
self.
|
|
765
|
+
if self._own_transaction():
|
|
766
|
+
self.conn.commit()
|
|
716
767
|
return updated
|
|
717
768
|
|
|
718
769
|
@SQLiteStorageBase.handle_exceptions
|
|
@@ -773,7 +824,8 @@ class AgentPlaybookStoreMixin:
|
|
|
773
824
|
request_id=request_id,
|
|
774
825
|
)
|
|
775
826
|
updated += 1
|
|
776
|
-
self.
|
|
827
|
+
if self._own_transaction():
|
|
828
|
+
self.conn.commit()
|
|
777
829
|
return updated
|
|
778
830
|
|
|
779
831
|
@SQLiteStorageBase.handle_exceptions
|