|
9 | 9 | from fastapi import APIRouter, Query, Path |
10 | 10 | from loguru import logger |
11 | 11 |
|
| 12 | +from basic_memory import telemetry |
12 | 13 | from basic_memory.deps import ContextServiceV2ExternalDep, EntityRepositoryV2ExternalDep |
13 | 14 | from basic_memory.schemas.base import TimeFrame, parse_timeframe |
14 | 15 | from basic_memory.schemas.memory import ( |
@@ -50,30 +51,55 @@ async def recent( |
50 | 51 | Returns: |
51 | 52 | GraphContext with recent activity and related entities |
52 | 53 | """ |
53 | | - # return all types by default |
54 | | - types = ( |
55 | | - [SearchItemType.ENTITY, SearchItemType.RELATION, SearchItemType.OBSERVATION] |
56 | | - if not type |
57 | | - else type |
58 | | - ) |
59 | | - |
60 | | - logger.debug( |
61 | | - f"V2 Getting recent context for project {project_id}: `{types}` depth: `{depth}` timeframe: `{timeframe}` page: `{page}` page_size: `{page_size}` max_related: `{max_related}`" |
62 | | - ) |
63 | | - # Parse timeframe |
64 | | - since = parse_timeframe(timeframe) |
65 | | - limit = page_size |
66 | | - offset = (page - 1) * page_size |
67 | | - |
68 | | - # Build context |
69 | | - context = await context_service.build_context( |
70 | | - types=types, depth=depth, since=since, limit=limit, offset=offset, max_related=max_related |
71 | | - ) |
72 | | - recent_context = await to_graph_context( |
73 | | - context, entity_repository=entity_repository, page=page, page_size=page_size |
74 | | - ) |
75 | | - logger.debug(f"V2 Recent context: {recent_context.model_dump_json()}") |
76 | | - return recent_context |
| 54 | + with telemetry.operation( |
| 55 | + "api.request.memory.recent_activity", |
| 56 | + entrypoint="api", |
| 57 | + domain="memory", |
| 58 | + action="recent_activity", |
| 59 | + page=page, |
| 60 | + page_size=page_size, |
| 61 | + ): |
| 62 | + types = ( |
| 63 | + [SearchItemType.ENTITY, SearchItemType.RELATION, SearchItemType.OBSERVATION] |
| 64 | + if not type |
| 65 | + else type |
| 66 | + ) |
| 67 | + |
| 68 | + logger.debug( |
| 69 | + f"V2 Getting recent context for project {project_id}: `{types}` depth: `{depth}` timeframe: `{timeframe}` page: `{page}` page_size: `{page_size}` max_related: `{max_related}`" |
| 70 | + ) |
| 71 | + since = parse_timeframe(timeframe) |
| 72 | + limit = page_size |
| 73 | + offset = (page - 1) * page_size |
| 74 | + |
| 75 | + with telemetry.scope( |
| 76 | + "api.memory.recent_activity.build_context", |
| 77 | + domain="memory", |
| 78 | + action="recent_activity", |
| 79 | + phase="build_context", |
| 80 | + page=page, |
| 81 | + page_size=page_size, |
| 82 | + ): |
| 83 | + context = await context_service.build_context( |
| 84 | + types=types, |
| 85 | + depth=depth, |
| 86 | + since=since, |
| 87 | + limit=limit, |
| 88 | + offset=offset, |
| 89 | + max_related=max_related, |
| 90 | + ) |
| 91 | + with telemetry.scope( |
| 92 | + "api.memory.recent_activity.shape_response", |
| 93 | + domain="memory", |
| 94 | + action="recent_activity", |
| 95 | + phase="shape_response", |
| 96 | + result_count=len(context.results), |
| 97 | + ): |
| 98 | + recent_context = await to_graph_context( |
| 99 | + context, entity_repository=entity_repository, page=page, page_size=page_size |
| 100 | + ) |
| 101 | + logger.debug(f"V2 Recent context: {recent_context.model_dump_json()}") |
| 102 | + return recent_context |
77 | 103 |
|
78 | 104 |
|
79 | 105 | # get_memory_context needs to be declared last so other paths can match |
@@ -111,20 +137,46 @@ async def get_memory_context( |
111 | 137 | Returns: |
112 | 138 | GraphContext with the entity and its related context |
113 | 139 | """ |
114 | | - logger.debug( |
115 | | - f"V2 Getting context for project {project_id}, URI: `{uri}` depth: `{depth}` timeframe: `{timeframe}` page: `{page}` page_size: `{page_size}` max_related: `{max_related}`" |
116 | | - ) |
117 | | - memory_url = normalize_memory_url(uri) |
118 | | - |
119 | | - # Parse timeframe |
120 | | - since = parse_timeframe(timeframe) if timeframe else None |
121 | | - limit = page_size |
122 | | - offset = (page - 1) * page_size |
123 | | - |
124 | | - # Build context |
125 | | - context = await context_service.build_context( |
126 | | - memory_url, depth=depth, since=since, limit=limit, offset=offset, max_related=max_related |
127 | | - ) |
128 | | - return await to_graph_context( |
129 | | - context, entity_repository=entity_repository, page=page, page_size=page_size |
130 | | - ) |
| 140 | + with telemetry.operation( |
| 141 | + "api.request.memory.build_context", |
| 142 | + entrypoint="api", |
| 143 | + domain="memory", |
| 144 | + action="build_context", |
| 145 | + page=page, |
| 146 | + page_size=page_size, |
| 147 | + ): |
| 148 | + logger.debug( |
| 149 | + f"V2 Getting context for project {project_id}, URI: `{uri}` depth: `{depth}` timeframe: `{timeframe}` page: `{page}` page_size: `{page_size}` max_related: `{max_related}`" |
| 150 | + ) |
| 151 | + memory_url = normalize_memory_url(uri) |
| 152 | + |
| 153 | + since = parse_timeframe(timeframe) if timeframe else None |
| 154 | + limit = page_size |
| 155 | + offset = (page - 1) * page_size |
| 156 | + |
| 157 | + with telemetry.scope( |
| 158 | + "api.memory.build_context.build_context", |
| 159 | + domain="memory", |
| 160 | + action="build_context", |
| 161 | + phase="build_context", |
| 162 | + page=page, |
| 163 | + page_size=page_size, |
| 164 | + ): |
| 165 | + context = await context_service.build_context( |
| 166 | + memory_url, |
| 167 | + depth=depth, |
| 168 | + since=since, |
| 169 | + limit=limit, |
| 170 | + offset=offset, |
| 171 | + max_related=max_related, |
| 172 | + ) |
| 173 | + with telemetry.scope( |
| 174 | + "api.memory.build_context.shape_response", |
| 175 | + domain="memory", |
| 176 | + action="build_context", |
| 177 | + phase="shape_response", |
| 178 | + result_count=len(context.results), |
| 179 | + ): |
| 180 | + return await to_graph_context( |
| 181 | + context, entity_repository=entity_repository, page=page, page_size=page_size |
| 182 | + ) |
0 commit comments