SuperAPI AI Directory

iblai-vibe-history

Agents & models

View repository

Updated 10-15 22:16

About this skill

/iblai-vibe-history

Add the user profile History surface -- "Review and export your conversations with AI agents." A user's own chat history across every agent, in two tabs: Conversations (agent / date-range / sentiment / topic filters, a two-column conversation list + transcript preview, per-conversation CSV download, and a filtered Export) and Exports (previously generated reports with status, the filters used, expiry, and a re-download action). Everything rides the user-scoped my-chat-history* endpoints. The backend serves a user's sessions to the user themselves, tenant admins, and watchers of that user — so the tab renders on your own profile, and on someone else's profile (opened from the Management tab) only for admin/watcher viewers; any other caller gets a 403.

This is the user-facing counterpart of /iblai-vibe-agent-history (the admin History tab in agent settings, which shows every user's conversations for one agent).

History — Conversations tab

Conversations — transcript preview with attachments and per-conversation Download

History — Exports tab

Admin viewing another user's history — email instead of "You", full date + time-ago

Common setup (brand, conventions, env files, verification): see docs/skill-setup.md.

Related History surfaces

  • /iblai-vibe-agent-history — the admin History tab in agent settings: one agent, every user's conversations, RBAC-gated. This skill is the mirror image: one user, every agent, own data only.
  • /iblai-vibe-profile — the <Profile> page hosts this surface as its History tab; that is also how it is mounted (Step 2).

Prerequisites

  • Auth must be set up first (/iblai-vibe-auth)
  • MCP server + skills configured (@iblai/mcp in .mcp.json)
  • No RBAC needed for a user's own history. Viewing another user's history requires the viewer to be a tenant admin or a watcher of that user — enforced server-side, mirrored client-side by canViewOtherUsersChatHistory (see the admin view section).

Step 1: Check Environment

Before proceeding, check for an iblai.env in the project root. Look for PLATFORM, DOMAIN, and TOKEN variables. If the file does not exist or is missing these variables, tell the user: "You need an iblai.env with your platform configuration. Download the template and fill in your values: curl -o iblai.env https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/iblai.env"

Step 2: Mount it (via the Profile page's History tab)

The History surface (ChatHistoryTab) is not exported as a standalone component — it ships as the History tab inside <Profile>. Mount the profile page and deep-link to the tab:

// app/(app)/profile/history/page.tsx
"use client";

import { Profile } from "@iblai/iblai-js/web-containers";

export default function ProfileHistoryPage() {
  return (
    <div className="flex h-full flex-col bg-white">
      <Profile {...profileProps} targetTab="chatHistory" /* profileProps = your usual Profile wiring */ />
    </div>
  );
}

See /iblai-vibe-profile Step 3 for the full <Profile> prop wiring (tenant, username, etc.) — this skill only adds the targetTab="chatHistory" entry point. On a read-only profile preview of another user, the tab stays visible only for tenant admins and watchers (see the next section) and is hidden for everyone else. If you need the surface standalone, build it from the data-layer hooks listed below; the SDK source paths in the component map are the reference implementation.

Admin & watcher view (via the Management tab)

Tenant admins can read any user's history without leaving the admin area: the Management tab's user list opens a user's profile preview, and for admin/watcher viewers that preview now includes the History tab, mounted with the viewed user's username. What changes in this mode:

  • Who sees it — the SDK decides with canViewOtherUsersChatHistory(rbacPermissions, tenant) (from @iblai/iblai-js/web-utils): true for a tenant admin (tenant.is_admin) or a holder of the watcher RBAC permission (/watchedgroups/#list — watchers only pass the server check for users they actually watch).
  • Email instead of "You" — on your own profile the human turns are labeled "You"; on someone else's history they show that user's email (resolved from user metadata, falling back to the email on the session payload, then the username).
  • Server is the authority — the backend serves a user's my-chat-history* data to the user, tenant admins, and that user's watchers; anyone else gets a 403, which the tab surfaces as a friendly "no access" message with Export disabled.
  • Exports on behalf — admins and watchers can generate exports for the viewed user; the Exports tab shows a "created by {owner}" line when a report was generated by someone other than the user.

Step 3: Use MCP Tools for Customization

get_component_info("Profile")
get_hook_info("useGetUserChatHistoryQuery")

Component map (web-containers source)

Everything lives under packages/web-containers/src/components/profile/chat-history/ in the SDK. These pieces are internal to the tab (not exported individually) — listed with paths as the reference for custom builds:

Component / hook Path Role
ChatHistoryTab profile/chat-history/chat-history-tab.tsx The surface: Conversations / Exports sub-tabs, filters row, two-column list + preview (dialog preview on mobile), per-conversation CSV download
ReportHistory profile/chat-history/report-history.tsx The Exports table: state badge (Pending / Processing / Completed / Error / Cancelled / Expired), filters summary, expiry, re-download
useUserChatHistory profile/chat-history/use-user-chat-history.ts Filter + pagination + data state (10 per page); exports buildUserChatHistoryReportBody mapping the UI filters onto the report POST body
useChatHistoryExport profile/chat-history/use-chat-history-export.ts Server-side export flow: POST a report task, poll its status every 3s, then stream the finished file down as a browser save
TranscriptFileCards chat/transcript-file-cards.tsx The attachment cards under a message — the same component the live chat uses. Publicly exported, so custom history UI can render attachments the same way
SearchSelect spend-caps/search-select.tsx The shared debounced agent autocomplete used by the "Search Agents" filter (min 2 characters)

What each tab renders

Conversations tab

  • Filters row — agent autocomplete ("Search Agents"), a two-month Pick a Date Range calendar, All Sentiments (values come from the filter endpoint; positive/neutral/negative as the fallback), All Topics (from the filter endpoint), and an Export button that generates a server-side report of everything matching the current filters.
  • Conversation list (left) — 10 per page: the conversation's full date and recency ("Jul 30, 2026, 9:46 PM · about 1 month ago"), sentiment badge (green/gray/red), agent name, title, and a one-line plain-text preview of the first AI reply. Markdown is stripped for list rows.
  • Transcript preview (right) — the selected conversation as alternating You / agent messages (the viewed user's email instead of "You" in the admin/watcher view) rendered as Markdown, with the files and images the user attached shown as file cards under the message (the payload's presigned url opens each one; a turn that was only an attachment has empty text), the same date + time-ago header and the user's real avatar (edX profile image → Gravatar → initial) and the agent's avatar. A Download button saves just this conversation as a client-side CSV. When the list payload carried only session metadata, the full transcript is fetched lazily. On mobile the preview opens in a dialog instead of the second column.
  • Empty state: "Select a conversation to view details."

Exports tab

Previously generated reports, newest first: Status badge, Created (time-ago), Filters summary (agent count or "All agents", date range or "All time", plus topic/sentiment when set), Expires, and a Download button while the report is still available. In-progress states keep a blue badge until the poll reaches a terminal state. When someone other than the user generated a report (an admin or watcher exporting on their behalf), the row carries a "created by {owner}" line.

Related Exports

From @iblai/iblai-js/web-containers:

  • Profile — the profile page hosting this surface as its History tab (targetTab="chatHistory").
  • TranscriptFileCards (+ TranscriptFileCardFile) — the attachment cards this surface renders under a message; take { name, contentType, url } per file.
  • resolveUserIdentity — the shared "what do we call this user" rule the admin transcript surfaces use. This learner surface keeps its own simpler rule (see below); reach for the helper when you build your own.

From @iblai/iblai-js/web-utils:

  • canViewOtherUsersChatHistory(rbacPermissions, tenant) — whether the current viewer may open another user's history (tenant admin or watcher RBAC).
  • WATCHER_RBAC_RESOURCE — the watcher permission the check reads (/watchedgroups/#list).

From @iblai/iblai-js/data-layer — the RTK Query hooks the surface uses, for custom UI on the same endpoints:

  • List + detail: useGetUserChatHistoryQuery, useGetUserChatHistorySessionQuery
  • Filter options: useGetUserChatHistoryFilterQuery (the authority on which sentiment/topic values the backend filters by — never send values it didn't offer)
  • Reports: useCreateUserChatHistoryReportMutation, useGetUserChatHistoryReportStatusQuery (poll until a terminal state), useGetUserChatHistoryReportsQuery (the Exports list), useLazyGetDownloadReportFromURLQuery (stream the finished file)
  • Constants + types: USER_CHAT_HISTORY_REPORT_ACTIVE_STATES, UserChatHistorySession, UserChatHistoryMessage (carries human_files / ai_files: TranscriptFile[] with a presigned url), TranscriptFile, UserChatHistoryReportListItem, UserChatHistoryReportState, CreateUserChatHistoryReportBody

Step 4: Verify

Run /iblai-vibe-ops-test before telling the user the work is ready:

  1. pnpm build -- must pass with zero errors
  2. pnpm test -- vitest must pass
  3. Start dev server and touch test:
    pnpm dev &
    npx playwright screenshot http://localhost:3000/profile/history /tmp/user-history.png
    

Important Notes

  • Redux store: Must include mentorReducer and mentorMiddleware
  • initializeDataLayer(): 5 args (v1.2+)
  • @reduxjs/toolkit: Deduplicated via webpack aliases in next.config.ts
  • Peer deps: sonner and @iblai/iblai-web-mentor must be installed (pnpm add sonner @iblai/iblai-web-mentor)
  • Not standalone (yet): ChatHistoryTab is internal to the SDK's Profile component. Reach it with <Profile targetTab="chatHistory">; for a bare custom page, rebuild from the data-layer hooks using the component map above as the reference.
  • Cross-user access is admin/watcher only: on another user's profile preview the tab appears only when canViewOtherUsersChatHistory passes, and the backend independently enforces the same rule (403 otherwise — even for a watcher on a user they don't watch). Per-user history here complements /iblai-vibe-agent-history (one agent, all users).
  • Two export paths: the filters-row Export POSTs a server-side report (async task, polled every 3s, listed under Exports with an expiry); the preview's Download builds a CSV of that single conversation client-side — no report involved.
  • Attachments: a turn's human_files / ai_files render as file cards with the payload's presigned url — those links expire, so re-fetch rather than caching them. A turn that was only an attachment carries empty text, which is why the card renders even with no message body.
  • Who the message is from: on your own profile the human turns read You; in the admin/watcher view they show the viewed user's email (user metadata → the session payload's email → username). The admin surfaces (/iblai-vibe-agent-history, the analytics Transcripts tab) use the richer shared resolveUserIdentity rule instead, which prefers a real full name.
  • Message shape tolerance: the list endpoint may serialize messages as a JSON string while the detail endpoint returns a proper array — custom consumers should accept both (the SDK normalizes them).
  • Brand guidelines: BRAND.md

User Chat History REST API

For custom UI beyond the tab. All endpoints are prefixed with ${dmUrl}/api/ai-analytics/orgs/{org}/users/{user_id}/ where dmUrl is NEXT_PUBLIC_API_BASE_URL. Auth: Authorization: Token <token>. {user_id} is the user whose history is read: the endpoints answer for the user themselves, tenant admins, and watchers of that user — any other caller gets a 403.

Method Path Purpose
GET my-chat-history/ List the user's sessions — page, page_size, plus mentor_id, start_date, end_date, topic, sentiment filters
GET my-chat-history/{session_id}/ One session with its full messages transcript
GET my-chat-history-filter/ The sentiment/topic values available to filter by
POST my-chat-history-report/ Start an export — { format: "csv" | "json", start_date?, end_date?, filters?: { mentor_id?: [..], topic?, sentiment? } } (mentor_id is an array even for one agent)
GET my-chat-history-report/ List generated reports (the Exports tab)
GET my-chat-history-report/{task_id}/ Poll a report task's state (pending / running / accumulating / processing / storing → completed / error / cancelled / expired)
GET my-chat-history-report/{task_id}/download/ Download the finished file (?format=csv|json)

Reports expire — the Exports tab shows the expiry and the Download action disappears once a report is no longer available.