(pc?: PageContext)
| 148 | } |
| 149 | |
| 150 | function buildPageContextSection(pc?: PageContext): string { |
| 151 | // The date varies every day, so we keep it out of the cached prefix |
| 152 | // and render it at the bottom of the prompt together with the rest |
| 153 | // of the per-request context. UTC is fine — analytics queries bucket |
| 154 | // by day boundaries, not user timezone. |
| 155 | const today = new Date(); |
| 156 | const todayIso = today.toISOString().slice(0, 10); |
| 157 | const dayName = today.toLocaleDateString('en-US', { |
| 158 | weekday: 'long', |
| 159 | timeZone: 'UTC', |
| 160 | }); |
| 161 | |
| 162 | const lines: string[] = [ |
| 163 | '# Current view', |
| 164 | `Today is **${dayName}, ${todayIso}** (UTC).`, |
| 165 | ]; |
| 166 | |
| 167 | if (!pc) return lines.join('\n'); |
| 168 | |
| 169 | lines.push(`The user is on the **${pc.page}** page.`); |
| 170 | |
| 171 | if (pc.filters?.range) { |
| 172 | const range = pc.filters.range; |
| 173 | // Resolve presets ("6m", "7d", …) to actual dates in the project's |
| 174 | // timezone so the model sees the same window the dashboard shows. |
| 175 | // Falls through gracefully if the range isn't a preset. |
| 176 | const resolved = resolveDateRange(pc.filters); |
| 177 | const dates = ` (${resolved.startDate} to ${resolved.endDate})`; |
| 178 | const interval = pc.filters.interval ?? 'day'; |
| 179 | lines.push(`Date range: ${range}${dates}, interval: ${interval}.`); |
| 180 | } |
| 181 | |
| 182 | if (pc.filters?.eventNames && pc.filters.eventNames.length > 0) { |
| 183 | lines.push( |
| 184 | `Active event-name filter: ${JSON.stringify(pc.filters.eventNames)}`, |
| 185 | ); |
| 186 | } |
| 187 | |
| 188 | if (pc.filters?.eventFilters && pc.filters.eventFilters.length > 0) { |
| 189 | lines.push( |
| 190 | `Active property filters: ${JSON.stringify(pc.filters.eventFilters)}`, |
| 191 | ); |
| 192 | } |
| 193 | |
| 194 | if (pc.ids?.profileId) { |
| 195 | lines.push( |
| 196 | `They are viewing profile \`${pc.ids.profileId}\`. Profile-specific tools below are pre-bound to this profile by default.`, |
| 197 | ); |
| 198 | } |
| 199 | if (pc.ids?.sessionId) { |
| 200 | lines.push( |
| 201 | `They are viewing session \`${pc.ids.sessionId}\`. Session-specific tools are pre-bound to this session.`, |
| 202 | ); |
| 203 | } |
| 204 | if (pc.ids?.groupId) { |
| 205 | lines.push( |
| 206 | `They are viewing group \`${pc.ids.groupId}\`. Group-specific tools are pre-bound to this group.`, |
| 207 | ); |
no test coverage detected