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.
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/dashboard/app/sessions/[sessionId]/page.tsx +36 -2
- package/plugin/dashboard/package-lock.json +61 -390
- package/plugin/dashboard/package.json +2 -2
- package/plugin/pyproject.toml +1 -1
- package/plugin/uv.lock +1 -1
- package/plugin/vendor/reflexio/.env.example +7 -0
- package/plugin/vendor/reflexio/pyproject.toml +2 -1
- package/plugin/vendor/reflexio/reflexio/README.md +8 -5
- package/plugin/vendor/reflexio/reflexio/lib/_config.py +23 -18
- package/plugin/vendor/reflexio/reflexio/lib/_interactions.py +16 -1
- package/plugin/vendor/reflexio/reflexio/lib/_search.py +15 -11
- package/plugin/vendor/reflexio/reflexio/models/api_schema/domain/enums.py +1 -0
- package/plugin/vendor/reflexio/reflexio/models/config_schema.py +24 -3
- package/plugin/vendor/reflexio/reflexio/server/README.md +25 -8
- package/plugin/vendor/reflexio/reflexio/server/__init__.py +21 -2
- package/plugin/vendor/reflexio/reflexio/server/api.py +133 -3273
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/README.md +4 -3
- package/plugin/vendor/reflexio/reflexio/server/api_endpoints/publisher_api.py +16 -1
- package/plugin/vendor/reflexio/reflexio/server/cache/reflexio_cache.py +62 -36
- package/plugin/vendor/reflexio/reflexio/server/deployment_profile.py +69 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_embedding.py +424 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_json_extraction.py +249 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_structured_output.py +195 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_subprocess.py +152 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_text_generation.py +980 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/_litellm_types.py +110 -0
- package/plugin/vendor/reflexio/reflexio/server/llm/litellm_client.py +73 -1819
- package/plugin/vendor/reflexio/reflexio/server/llm/providers/claude_code_provider.py +56 -4
- package/plugin/vendor/reflexio/reflexio/server/middleware.py +244 -0
- package/plugin/vendor/reflexio/reflexio/server/operation_limiter.py +9 -1
- package/plugin/vendor/reflexio/reflexio/server/rate_limit.py +79 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/__init__.py +6 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/_common.py +25 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/_metering.py +98 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/braintrust.py +129 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/config.py +210 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/evaluation.py +549 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/interactions.py +259 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/playbooks.py +578 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/profiles.py +423 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/provenance.py +345 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/search.py +349 -0
- package/plugin/vendor/reflexio/reflexio/server/routes/system.py +261 -0
- package/plugin/vendor/reflexio/reflexio/server/scheduling.py +132 -0
- package/plugin/vendor/reflexio/reflexio/server/services/README.md +3 -2
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/__init__.py +38 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_batch_progress.py +298 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_config_filter.py +152 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_extraction_lifecycle.py +243 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_should_run.py +299 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_status_change.py +273 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation/_usage_billing.py +258 -0
- package/plugin/vendor/reflexio/reflexio/server/services/base_generation_service.py +17 -1183
- package/plugin/vendor/reflexio/reflexio/server/services/deduplication_utils.py +8 -1
- package/plugin/vendor/reflexio/reflexio/server/services/extraction/resume_scheduler.py +26 -41
- package/plugin/vendor/reflexio/reflexio/server/services/generation_service.py +232 -123
- package/plugin/vendor/reflexio/reflexio/server/services/lineage/gc_scheduler.py +362 -81
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator.py +68 -490
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator_clustering.py +184 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator_postprocessing.py +130 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/aggregator_prompt_formatting.py +212 -0
- package/plugin/vendor/reflexio/reflexio/server/services/playbook/components/consolidator.py +258 -69
- package/plugin/vendor/reflexio/reflexio/server/services/publish_learning_worker.py +288 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/__init__.py +29 -4
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_agent_run.py +10 -1167
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_base.py +56 -351
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_governance.py +0 -1513
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_lineage.py +6 -1
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_profiles.py +7 -1281
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/_share_links.py +30 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/__init__.py +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/_agent_run_store.py +506 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/_pending_tool_call_store.py +704 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/agent_run/_run_tool_dependency_store.py +123 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/__init__.py +6 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/_deletion.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/base/_fts_vec.py +132 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_audit.py +122 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_erase_execution.py +465 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_purge.py +387 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_rebuild_hide.py +332 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/governance/_subject_barrier.py +511 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_agent.py +6 -3
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/playbook/_user.py +13 -7
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/__init__.py +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_interaction_store.py +263 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_profile_store.py +896 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/sqlite_storage/profiles/_search.py +270 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/__init__.py +33 -8
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_agent_run.py +64 -370
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_share_links.py +20 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/__init__.py +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_agent_run_store.py +86 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_models.py +195 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_pending_tool_call_store.py +148 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/agent_run/_run_tool_dependency_store.py +38 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/__init__.py +13 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_audit.py +29 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_erase_execution.py +30 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_purge.py +74 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_rebuild_hide.py +32 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/governance/_subject_barrier.py +49 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/__init__.py +9 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/_interaction_store.py +73 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/{_profiles.py → profiles/_profile_store.py} +44 -86
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/profiles/_search.py +32 -0
- package/plugin/vendor/reflexio/reflexio/server/services/storage/storage_base/_governance.py +0 -148
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"""Interaction route handlers (extracted from api.py, Tier3 A2)."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
from fastapi import (
|
|
10
|
+
APIRouter,
|
|
11
|
+
BackgroundTasks,
|
|
12
|
+
Depends,
|
|
13
|
+
Request,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from reflexio.models.api_schema.retriever_schema import (
|
|
17
|
+
GetInteractionsRequest,
|
|
18
|
+
GetInteractionsViewResponse,
|
|
19
|
+
GetRequestsRequest,
|
|
20
|
+
GetRequestsViewResponse,
|
|
21
|
+
RequestDataView,
|
|
22
|
+
SessionView,
|
|
23
|
+
)
|
|
24
|
+
from reflexio.models.api_schema.service_schemas import (
|
|
25
|
+
BulkDeleteResponse,
|
|
26
|
+
DeleteRequestRequest,
|
|
27
|
+
DeleteRequestResponse,
|
|
28
|
+
DeleteRequestsByIdsRequest,
|
|
29
|
+
DeleteSessionRequest,
|
|
30
|
+
DeleteSessionResponse,
|
|
31
|
+
DeleteUserInteractionRequest,
|
|
32
|
+
DeleteUserInteractionResponse,
|
|
33
|
+
PublishUserInteractionRequest,
|
|
34
|
+
PublishUserInteractionResponse,
|
|
35
|
+
)
|
|
36
|
+
from reflexio.models.api_schema.ui.converters import (
|
|
37
|
+
to_interaction_view,
|
|
38
|
+
)
|
|
39
|
+
from reflexio.server.api_endpoints import (
|
|
40
|
+
publisher_api,
|
|
41
|
+
)
|
|
42
|
+
from reflexio.server.auth import (
|
|
43
|
+
default_billing_gate,
|
|
44
|
+
default_get_org_id,
|
|
45
|
+
)
|
|
46
|
+
from reflexio.server.cache import reflexio_cache
|
|
47
|
+
from reflexio.server.rate_limit import limiter
|
|
48
|
+
from reflexio.server.routes._common import _run_limited_api
|
|
49
|
+
|
|
50
|
+
logger = logging.getLogger(__name__)
|
|
51
|
+
router = APIRouter()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@router.post(
|
|
55
|
+
"/api/publish_interaction",
|
|
56
|
+
response_model=PublishUserInteractionResponse,
|
|
57
|
+
response_model_exclude_none=True,
|
|
58
|
+
)
|
|
59
|
+
@limiter.limit("60/minute") # Rate limit for write operations
|
|
60
|
+
def publish_user_interaction(
|
|
61
|
+
request: Request,
|
|
62
|
+
payload: PublishUserInteractionRequest,
|
|
63
|
+
background_tasks: BackgroundTasks,
|
|
64
|
+
org_id: str = Depends(default_get_org_id),
|
|
65
|
+
wait_for_response: bool = False,
|
|
66
|
+
_gate: None = Depends(default_billing_gate("learnings_generated")), # noqa: B008
|
|
67
|
+
) -> PublishUserInteractionResponse:
|
|
68
|
+
if wait_for_response:
|
|
69
|
+
# Sync callers wait for the real result, so preserve bounded backpressure
|
|
70
|
+
# before any storage side effects. The inner service limiter is disabled
|
|
71
|
+
# because this route already owns the publish slot.
|
|
72
|
+
return _run_limited_api(
|
|
73
|
+
org_id,
|
|
74
|
+
"publish",
|
|
75
|
+
lambda: publisher_api.add_user_interaction(
|
|
76
|
+
org_id=org_id,
|
|
77
|
+
request=payload,
|
|
78
|
+
use_publish_limiter=False,
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def _publish_task() -> None:
|
|
83
|
+
try:
|
|
84
|
+
publisher_api.add_user_interaction(
|
|
85
|
+
org_id=org_id,
|
|
86
|
+
request=payload,
|
|
87
|
+
defer_learning=True,
|
|
88
|
+
)
|
|
89
|
+
except Exception:
|
|
90
|
+
logger.exception("Background publish failed for org %s", org_id)
|
|
91
|
+
|
|
92
|
+
# Run in background — caller gets immediate acknowledgement
|
|
93
|
+
background_tasks.add_task(_publish_task)
|
|
94
|
+
return PublishUserInteractionResponse(
|
|
95
|
+
success=True, message="Interaction queued for processing"
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@router.delete(
|
|
100
|
+
"/api/delete_interaction",
|
|
101
|
+
response_model=DeleteUserInteractionResponse,
|
|
102
|
+
response_model_exclude_none=True,
|
|
103
|
+
)
|
|
104
|
+
def delete_interaction(
|
|
105
|
+
request: DeleteUserInteractionRequest,
|
|
106
|
+
org_id: str = Depends(default_get_org_id),
|
|
107
|
+
) -> DeleteUserInteractionResponse:
|
|
108
|
+
return publisher_api.delete_user_interaction(org_id=org_id, request=request)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@router.delete(
|
|
112
|
+
"/api/delete_request",
|
|
113
|
+
response_model=DeleteRequestResponse,
|
|
114
|
+
response_model_exclude_none=True,
|
|
115
|
+
)
|
|
116
|
+
def delete_request(
|
|
117
|
+
request: DeleteRequestRequest,
|
|
118
|
+
org_id: str = Depends(default_get_org_id),
|
|
119
|
+
) -> DeleteRequestResponse:
|
|
120
|
+
return publisher_api.delete_request(org_id=org_id, request=request)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@router.delete(
|
|
124
|
+
"/api/delete_session",
|
|
125
|
+
response_model=DeleteSessionResponse,
|
|
126
|
+
response_model_exclude_none=True,
|
|
127
|
+
)
|
|
128
|
+
def delete_session(
|
|
129
|
+
request: DeleteSessionRequest,
|
|
130
|
+
org_id: str = Depends(default_get_org_id),
|
|
131
|
+
) -> DeleteSessionResponse:
|
|
132
|
+
return publisher_api.delete_session(org_id=org_id, request=request)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@router.delete(
|
|
136
|
+
"/api/delete_requests_by_ids",
|
|
137
|
+
response_model=BulkDeleteResponse,
|
|
138
|
+
response_model_exclude_none=True,
|
|
139
|
+
)
|
|
140
|
+
def delete_requests_by_ids(
|
|
141
|
+
request: DeleteRequestsByIdsRequest,
|
|
142
|
+
org_id: str = Depends(default_get_org_id),
|
|
143
|
+
) -> BulkDeleteResponse:
|
|
144
|
+
"""Delete multiple requests by their IDs.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
request (DeleteRequestsByIdsRequest): Request containing list of request IDs to delete
|
|
148
|
+
org_id (str): Organization ID
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
BulkDeleteResponse: Response containing success status and deleted count
|
|
152
|
+
"""
|
|
153
|
+
return publisher_api.delete_requests_by_ids(org_id=org_id, request=request)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@router.delete(
|
|
157
|
+
"/api/delete_all_interactions",
|
|
158
|
+
response_model=BulkDeleteResponse,
|
|
159
|
+
response_model_exclude_none=True,
|
|
160
|
+
)
|
|
161
|
+
@limiter.limit("10/minute")
|
|
162
|
+
def delete_all_interactions(
|
|
163
|
+
request: Request,
|
|
164
|
+
org_id: str = Depends(default_get_org_id),
|
|
165
|
+
) -> BulkDeleteResponse:
|
|
166
|
+
"""Delete all requests and their associated interactions.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
org_id (str): Organization ID
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
BulkDeleteResponse: Response containing success status and deleted count
|
|
173
|
+
"""
|
|
174
|
+
return publisher_api.delete_all_interactions_bulk(org_id=org_id)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@router.post(
|
|
178
|
+
"/api/get_interactions",
|
|
179
|
+
response_model=GetInteractionsViewResponse,
|
|
180
|
+
response_model_exclude_none=True,
|
|
181
|
+
)
|
|
182
|
+
def get_interactions(
|
|
183
|
+
request: GetInteractionsRequest,
|
|
184
|
+
org_id: str = Depends(default_get_org_id),
|
|
185
|
+
) -> GetInteractionsViewResponse:
|
|
186
|
+
response = reflexio_cache.get_reflexio(org_id=org_id).get_interactions(request)
|
|
187
|
+
return GetInteractionsViewResponse(
|
|
188
|
+
success=response.success,
|
|
189
|
+
interactions=[to_interaction_view(i) for i in response.interactions],
|
|
190
|
+
msg=response.msg,
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@router.get(
|
|
195
|
+
"/api/get_all_interactions",
|
|
196
|
+
response_model=GetInteractionsViewResponse,
|
|
197
|
+
response_model_exclude_none=True,
|
|
198
|
+
)
|
|
199
|
+
@limiter.limit("30/minute")
|
|
200
|
+
def get_all_interactions(
|
|
201
|
+
request: Request,
|
|
202
|
+
limit: int = 100,
|
|
203
|
+
org_id: str = Depends(default_get_org_id),
|
|
204
|
+
) -> GetInteractionsViewResponse:
|
|
205
|
+
"""Get all user interactions across all users.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
limit (int, optional): Maximum number of interactions to return. Defaults to 100.
|
|
209
|
+
org_id (str): Organization ID
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
GetInteractionsViewResponse: Response containing all user interactions
|
|
213
|
+
"""
|
|
214
|
+
reflexio = reflexio_cache.get_reflexio(org_id=org_id)
|
|
215
|
+
response = reflexio.get_all_interactions(limit=limit)
|
|
216
|
+
return GetInteractionsViewResponse(
|
|
217
|
+
success=response.success,
|
|
218
|
+
interactions=[to_interaction_view(i) for i in response.interactions],
|
|
219
|
+
msg=response.msg,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@router.post(
|
|
224
|
+
"/api/get_requests",
|
|
225
|
+
response_model=GetRequestsViewResponse,
|
|
226
|
+
response_model_exclude_none=True,
|
|
227
|
+
)
|
|
228
|
+
def get_requests_endpoint(
|
|
229
|
+
request: GetRequestsRequest,
|
|
230
|
+
org_id: str = Depends(default_get_org_id),
|
|
231
|
+
) -> GetRequestsViewResponse:
|
|
232
|
+
"""Get requests with their associated interactions.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
request (GetRequestsRequest): The get request
|
|
236
|
+
org_id (str): Organization ID
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
GetRequestsViewResponse: Response containing requests with their interactions
|
|
240
|
+
"""
|
|
241
|
+
internal_response = reflexio_cache.get_reflexio(org_id=org_id).get_requests(request)
|
|
242
|
+
return GetRequestsViewResponse(
|
|
243
|
+
success=internal_response.success,
|
|
244
|
+
sessions=[
|
|
245
|
+
SessionView(
|
|
246
|
+
session_id=s.session_id,
|
|
247
|
+
requests=[
|
|
248
|
+
RequestDataView(
|
|
249
|
+
request=rd.request,
|
|
250
|
+
interactions=[to_interaction_view(i) for i in rd.interactions],
|
|
251
|
+
)
|
|
252
|
+
for rd in s.requests
|
|
253
|
+
],
|
|
254
|
+
)
|
|
255
|
+
for s in internal_response.sessions
|
|
256
|
+
],
|
|
257
|
+
has_more=internal_response.has_more,
|
|
258
|
+
msg=internal_response.msg,
|
|
259
|
+
)
|