Skip to main content

Qontak | AI Agent | Knowledge — Phase 1: Conversation History

Conversation History — Phase 1 PRD under the AI Agent: Knowledge ANCHOR. Adds a new dynamic knowledge-source type that lets the AI Agent learn from selected expert agents' resolved conversations (PII-masked, 3-month rolling window, daily sync). Imported from Confluence and reconciled against code (chatbot, chatbot-fe, qontak-designer).

HEADER BLOCK

FieldValue
PMDimas Fauzi Hidayat
PRD Version1.4
StatusDRAFT
PRD TypePHASE
EpicTBD — Epic not yet created (stories tracked as TEMP placeholders)
SquadBOT (Hadiningbot)
DesignerWulan Febyazzahra Putri (Bulan)
PMMYosephine Dhisaclara (Ocie)
RFC LinkPlanned — RFC to be created with engineering and the Data & AI team
Figma MasterFigma — AI Agent config (node 18883-4459) · AI Resources (node 10853-57617)
AnchorAI Agent: Knowledge — ANCHOR (Confluence)
Labelsepic:qontak-chatbot | module:ai-agent | feature:ai-agent-knowledge
Last Updated2026-06-30

Scope Changes

Backend · Frontend · Data — new conversation_history knowledge type + agent/division config UI (chatbot, chatbot-fe), and the ingestion/PII-masking/daily-sync pipeline (Data).


2. Phase Context

  • Anchor PRD: AI Agent: Knowledge — ANCHOR
  • Phase Number: Phase 1 of N (phasing by knowledge source; static PDF/URL pre-exist)
  • Phase Goal: Let the AI Agent learn from selected expert agents' resolved conversations — a dynamic, PII-masked, self-updating knowledge source — to lower the AI adoption barrier for Qontak360 clients.
  • Prior phases: N/A as a phase, but static PDF/Website knowledge already ships and this source plugs into the same Knowledge module and "Training Source" UI.
  • This phase: The conversation_history knowledge type — division + expert-agent selection, ingestion with quality/PII gates, daily sync over a 3-month rolling window, referencing with room-id source links, and management (status, remove, delete).
  • Deferred to next: Data-driven agent selection, automated knowledge weighting, multi-media ingestion, real-time sync, cross-division pooling, proactive gap detection (see §16 / ANCHOR future phases).
  • Cross-phase deps: Reuses the existing Knowledge Base schema (new conversation_history type) and the AI vector DB. The type/index contract here must remain stable for future dynamic sources.

3. One-liner + Problem

One-liner: Enable AI Agents to learn from high-performing human agents' resolved conversations, so they give more "human-like", contextually accurate answers — without manual knowledge-base building.

Problem: Admins struggle to keep AI knowledge updated because official docs (PDFs/websites) miss the edge cases and brand tone agents use daily. That "tribal knowledge" is locked in chat logs and lost to the AI, so agents hit knowledge gaps (slower resolution) and SPVs carry a heavy manual coaching/onboarding burden. For Qontak360 clients, the effort to compile training sources is the real barrier to AI adoption. For full initiative context, see the ANCHOR PRD.


4. Target Users + Persona Context

PersonaRoleGoalPainWorkaround
Primary — AgentFront-line agent handling daily inquiriesImmediate, "proven" Airene Copilot answers based on how the team solved similar issues, without leaving the InboxMisinformation / knowledge gaps for specific inquiries → slow resolutionSearches old chats / Slack; waits for an SPV
Primary — SPV / AdminSupervisor / Admin configuring AI knowledgeSet up AI knowledge sources without weeks of manual documentationManual onboarding + constant micro-coaching; high effort to compile sourcesManually compiles PDFs/FAQs; coaches 1:1

Target profile: Qontak360 AI-Agent users — companies with large agent teams (>100) or high transaction volumes (tax/PPN) needing high accuracy; want AI for daily inquiries but lack resources to build a manual KB from scratch.


5. Non-Goals

  1. Automated agent selection — the system will not auto-select agents by CSAT/tenure; selection stays a manual Admin task (this phase).
  2. Real-time knowledge ingestion — knowledge updates daily (once/24h), not as chats happen.
  3. Multi-media knowledge — text-only; images/files within chats are not indexed.
  4. Cross-division knowledge sharing — one Division has exactly one Conversation History source; no sharing across divisions.
  5. Performance reporting overhaul — no new reporting dashboards (handled by a separate initiative).

6. Constraints

  • Platform: Web only (AI Agent configuration + AI Resources). Copilot suggestions surface in the Inbox.
  • Performance: Initial training completes within ~1 hour for 15 agents. Conversation training runs in a dedicated/isolated service to avoid "noisy neighbor" effects on the main app.
  • Tier (plan scope): Qontak360 only — Service Suite and Pro-above. Not on lower tiers.
  • Feature flag: TBD (align with engineering) | default: OFF.
  • Read/write: Admin / Super Admin can configure, save, remove, and delete the source. Agents consume Copilot suggestions; reference-link access is permission-scoped by room.
  • Data limits: Max 15 agents per division-source. 3-month (90-day) rolling lookback. Text-only messages. Excludes internal notes/whispers. Rooms with < 5 bubble messages ignored. One Division = one Conversation History source.
  • Quota: Usage governed by a monthly Copilot quota (e.g., 15 quota/seat for Service Suite).

6.1 Data Lifecycle

Artifact TypeRetentionCleanup TriggerUser-Visible Effect
Indexed conversation vectors (per division-source)Rolling 90 daysDaily sync purges data older than 90 daysKnowledge stays "fresh"; "Last Updated" timestamp advances
Indexed vectors on source removalUntil source deletedHard delete of all associated vectors for that division when the source is deletedSource disappears from Knowledge Index / AI Resources
Transient ingestion payload (raw chat pre-masking)Not persisted post-processingDiscarded after PII masking + indexingNone

7. Feature Changes

CHG-001 — "Conversation History" option in Add Knowledge + status in Knowledge Index

  • Change Type: Modified flow + modified component (Knowledge module).
  • Page: AI Agent → Knowledge Section → "Add Knowledge" (existing agent detail [id].vue); Create AI Agent (create/index.vue) → "What sources does your agent learn from?"; AI Agent detail [id].vue → Capabilities tab (per-capability Sources section); and the Knowledge Index page; and the AI Resources page.
  • Before: "Add Knowledge" offers static sources only (PDF, Website/URL). Knowledge Index lists static sources with no per-source training state for dynamic data.
  • After: "Add Knowledge" shows a new "Conversation History" option (Qontak360 only). The Knowledge Index / AI Resources shows a per-source training status ("Training in Progress" / "Active" / "Error") and a "Last Updated" timestamp.
ElementBeforeAfter
Add Knowledge modalPDF / Website only+ "Conversation History" (Qontak360)
Knowledge Index rowStatic source, no live stateTraining status + "Last Updated" timestamp

Figma: AI Agent config — node 18883-4459.


8. New Features

Design status: IMPLEMENTED on feat/resources-conv-history (branch: qontak-designer). The prototype is updated and covers most UI/UX requirements. Two gaps remain open for designer/engineer follow-up.

Prototype components + Figma nodes:

  • Add-source flow + "Conversation history" option — app/components/bot-automation/sources/AddKnowledgeDrawer.vue · Figma LJ6ePL0PjxKbHYZZdNK4LX (✨ Bot - AI) nodes 20840-30474 / 20840-32079 / 20839-31336
    • "Add source" sub-drawer lists all 4 source types incl. Conversation history
    • showAddConvHistoryModal — agent+division picker modal with division-level checkbox select (addConvToggleDivision) and individual agent toggle (addConvToggleAgent)
    • showConvHistoryDrawer — "Conversation history" drawer (when source already exists) with MpToggle "Use as source" for unlink flow + Agent/Division read-only table
  • Source detail with Agent·Division table — app/components/bot-automation/sources/SourceDetailDrawer.vue · Figma 4eR76oEuKnaW2t40z4dfEa (✨ AI Resources) node 10859:83239
    • Shows source info + Agent/Division table for conversation-history type; footer "Delete" (danger link) for deletion
  • AI Resources list (Status, Last updated, delete) — app/pages/bot-automation/resources/index.vue · Figma LJ6ePL0PjxKbHYZZdNK4LX node 20671:248358
    • Status column: "Active" / "Processing" (= Training in Progress) / "Inactive"; "Last updated" timestamp column

Remaining gaps (designer/engineer to address before build):

  1. 15-agent cap + validation message — PRD CONVHIST-S04. addConvSelectedAgentIds in AddKnowledgeDrawer.vue has no cap, no live "N/15" counter, and no "Please limit selection to your top 15 experts" validation. Must be added.
  2. "Select agents with proven expertise" guidance tooltip — PRD §8 / CONVHIST-S01/AC-3. The modal body has descriptive copy but no tooltip component on the agent picker. Must be added.
  3. Division-first multi-selectResolved. addConvToggleDivision() implements division-level select; individual agents can be deselected (CONVHIST-S05 covered).
  4. Training-status lifecyclePartially resolved. Resources list now shows "Active"/"Processing"; "Error" / "Last Successful Sync" state still absent.

Feature: Conversation History knowledge source

  • Entry points:
    • (a) Existing AI Agent[id].vue → Knowledge Section → Add Knowledge → "Conversation History"
    • (b) AI Resources page/bot-automation/resources → Add source → "Conversation History"
    • (c) Create AI Agentcreate/index.vue → "What sources does your agent learn from?" → Conversation history row → + button (or "N selected" if already added)
    • (d) AI Agent detail — Capabilities tab[id].vue → Capabilities tab → per-capability "Add source" (from capability edit drawer, or inline from the capability card body)
  • Access: Admin / Super Admin on Qontak360 (Service Suite / Pro-above).

Config flow:

  • Select a Division (one Division = one Conversation History source).
  • Select up to 15 Agents/SPVs within that division (or "select division" to mark all agents under it, still capped at 15) — guidance tooltip: "Select agents with high domain expertise for better reference quality."
  • Save → ingestion begins for the last 3 months of resolved chats → status "Training in Progress" → "Active" (~1 hour) with a "Last Updated" timestamp.

Component Tree:

  • CreateAIAgentPage (/bot-automation/ai-agents/create) — entry point (c)

    • KnowledgeSourcesSection — "What sources does your agent learn from?" — purpose: source selection during creation
      • ConversationHistoryRow — purpose: dedicated row with + / "N selected" button; selectedCountFor() shows agent count
      • AddKnowledgeDrawer (:direct-sub-flow="'conversation-history'") — purpose: skips main list, opens directly in conv-history sub-flow
        • → branches to showAddConvHistoryModal or showConvHistoryDrawer depending on hasConvHistory
  • AIAgentDetailPage (/bot-automation/ai-agents/[id]) — entry points (a) and (d)

    • ProfileTab — entry point (a)
      • KnowledgeSectionAddKnowledgeButtonAddKnowledgeDrawer (id="add-source-drawer") — purpose: agent-level source management
    • CapabilitiesTab — entry point (d)
      • CapabilityCard (per capability)
        • SourcePills — purpose: shows conv-history as a chip with TrainingStatusBadge ("Training" warning / "Failed" critical)
        • InlineAddSourceLinkAddKnowledgeDrawer (id="inline-cap-source-drawer") — purpose: add source without opening edit drawer
        • CapabilityEditDrawerSourcesSection (collapsible)
          • StatusBanner — purpose: "N sources in training, M failed" warning
          • SourceRow (per source) + remove button — purpose: list + remove capability-scoped sources
          • AddSourceButtonAddKnowledgeDrawer (addKnowledgeSubDrawerOpen) — purpose: add source scoped to this capability
      • On save: cap-level + agent-level source IDs are merged and deduped via registerAgentSources()
  • ResourcesPage (/bot-automation/resources) — entry point (b)

    • AddKnowledgeButtonAddKnowledgeDrawer (source-type picker) — purpose: choose source type
      • SourceTypeOption: "Conversation history" — purpose: entry to this feature (Qontak360 only)
      • ConversationHistoryModal (showAddConvHistoryModal) — purpose: configure new source
        • DivisionSelect — purpose: pick the one division (one division = one source)
        • AgentMultiSelect (cap 15) — purpose: pick expert agents; shows 15-cap counter + validation
        • ExpertiseTooltip — purpose: guidance ("select agents with proven expertise")
        • SaveButton — purpose: trigger ingestion (disabled until valid)
      • ConversationHistoryDrawer (showConvHistoryDrawer) — purpose: view/unlink existing source
        • MpToggle "Use as source" — purpose: toggle unlinks without deleting
        • AgentsTable (read-only) — purpose: show selected agents
    • KnowledgeIndexTable / SourceRow — purpose: list sources
      • TrainingStatusBadge (Processing / Active / Inactive) — purpose: ingestion state
      • LastUpdatedCell — purpose: freshness signal
      • RowActions (Delete) — purpose: hard-delete
    • SourceDetailDrawer — purpose: view a source
      • AgentsTable (Agent · Division) — purpose: show which agents feed the source
      • DeleteButton (danger link) — purpose: delete the source

UI States:

  • Empty: no Conversation History source yet; primary action = Add Knowledge → Conversation History.
  • Loading: "Training in Progress" while ingestion runs.
  • Error: "Error" / "Last Successful Sync" state if masking/indexing fails, with Admin notification.
  • Success: "Active" with "Last Updated" timestamp; source usable by the AI Agent.

📊 UI State Diagram — Conversation History source lifecycle

stateDiagram-v2
[*] --> Configuring: Add Knowledge → Conversation History
Configuring --> Configuring: select division + agents (≤15)
Configuring --> TrainingInProgress: Save (valid)
Configuring --> [*]: Cancel
TrainingInProgress --> Active: ingestion + masking + indexing OK (~1h)
TrainingInProgress --> Error: masking/indexing fails
Error --> TrainingInProgress: retry / next daily sync
Active --> Active: daily sync (ingest new, purge >90d, Last Updated advances)
Active --> Removed: Remove (−) from agent / Delete source
Error --> Removed: Delete source
Removed --> [*]

Figma: AI Resources — node 10853-57617. Implemented prototype + precise nodes: see the Design status callout at the top of this section.


9. API & Webhook Behavior

Technical fields (HTTP methods, JSON schemas, error codes) resolved during RFC. Provided by the Qontak backend + the Data & AI team.

#BehaviorEntity AffectedTriggered ByExpected BehaviorFailure Behavior
1Fetch divisions + agentsRead division/agent directoryOpening the config modalReturns divisions and the agents within each, to populate selectionDirectory unavailable → modal shows load error + retry
2Create Conversation History sourceNew conversation_history knowledge recordAdmin clicks SavePersists division + selected agent IDs (≤15); triggers ingestion of last-3-month resolved rooms for those agents; status → "Training in Progress">15 agents → validation error, Save disabled. Save fails → error surfaced
3Training-status webhookKnowledge record statusData & AI team training pipelineUpdates Qontak backend: in_progress / completed / failed; on completed sets "Last Updated"On failed/masking error → status "Error"/"Last Successful Sync" + Admin notification
4Daily sync (cron, ~24h @ 01:00)Indexed vectorsScheduled jobIngests previous day's resolved rooms for selected agents; purges data > 90 days; updates "Last Updated"Job failure logged + alerted; previous index retained
5Reference link to source roomRead room by room_idAI answer cites a sourceReturns a link to the original room only if the requesting user has permission to view itUnauthorized (e.g., different division) → access denied / permission error

Ingestion pipeline (Data & AI team): PII masking (NLP redaction → generic tags), quality gate (status: resolved, ≥5 bubble messages), role filter (customer-facing only; exclude internal notes/whispers), recency prioritization on conflicts.


10. System Flow + User Stories + ACs

10.1 System Flow

Flow: Configure & ingest a Conversation History knowledge source
Type: User Journey + API Sequence
  1. Admin opens AI Agent → Knowledge Section (or AI Resources) → clicks "Add Knowledge".
  2. Selects "Conversation History" (Qontak360 only). Branch: if the account is not Qontak360 → option not shown (NEG-1).
  3. Selects one Division (one Division = one source). Branch: if the division already has a source → blocked (NEG-3).
  4. Selects up to 15 Agents/SPVs (or selects the division to include all, capped at 15); tooltip guides expert selection. Branch: 16th selection → validation message, Save disabled (S04).
  5. Clicks Save → backend creates the source (POST create, §9 #2) and triggers ingestion of the last 3 months of resolved rooms for those agents → status "Training in Progress".
  6. Quality gate: only resolved rooms with ≥5 bubble messages; text-only; exclude internal whispers. Branch: a selected agent with zero qualifying rooms → ignored, others proceed (NEG-2).
  7. PII masking redacts emails/phones/addresses/financial/identity → generic tags, then indexes to the vector DB. Failure branch: masking/indexing fails → room skipped, source status → "Error"/"Last Successful Sync", Admin notified (S06/ERR-1).
  8. Training-status webhook (§9 #3) flips status "Training in Progress" → "Active" (~1h) and sets a "Last Updated" timestamp.
  9. End-user asks the AI Agent a question → AI searches the indexed history → returns an answer from a past successful resolution. Branch: conflicting resolutions → prioritize the most recent (S09).
  10. AI answer may include a reference link to the source room_id. Branch: requester lacks room permission → access denied (S11/ERR-1).
  11. Daily (24h) sync (§9 #4) ingests the prior day's resolutions and purges data older than 90 days. Failure branch: sync job fails → previous index retained, alert raised (S10/ERR-1).

📊 System Flow — configure & ingest

graph TD
A[Admin: Add Knowledge] --> B{Qontak360?}
B -- No --> B0[Option hidden NEG-1]
B -- Yes --> C[Select Conversation history]
C --> D{Division has a source?}
D -- Yes --> D0[Blocked: one division = one source NEG-3]
D -- No --> E[Select agents]
E --> F{More than 15?}
F -- Yes --> F0[Validation; Save disabled S04]
F -- No --> G[Save → create source + trigger ingestion]
G --> H[Quality gate: resolved, >=5 msgs, text-only, no whispers]
H --> I[PII masking → index vectors]
I -- masking/index fails --> X[Status: Error + notify admin S06]
I -- ok --> J[Webhook: Training in Progress → Active + Last Updated]
J --> K[AI answers from history]
K --> L{Conflicting resolutions?}
L -- Yes --> M[Prioritize most recent S09]
L -- No --> N[Return answer + optional room-id reference]
N --> O{Requester has room permission?}
O -- No --> O0[Access denied S11]
O -- Yes --> P[Open source room]
J --> Q[Daily 24h sync: ingest new, purge >90d]
Q -- sync fails --> R[Retain prior index + alert S10]

10.2 User Stories

All stories carry their original TEMP ticket placeholders from the Confluence draft (real Jira epic/keys TBD — §17 Open Question #2). Priority preserved from the source.


CONVHIST-S01 — Source configuration | Must Have

Story: As an Admin, I want to select "Conversation History" as a knowledge source, so that the AI can learn from agent expertise. (TEMP-15afd22e)

Before: Add Knowledge offers static sources (PDF/Website) only. After: Add Knowledge offers a "Conversation History" option (Qontak360) configurable from both AI Agent config and AI Resources.

Data Fields:

FieldTypeRequiredSource
division_iduuidYesUser selection
agent_idsarray (≤15)YesUser selection
source_typeenum (conversation_history)YesSystem

Happy Path:

  • AC-1: Given I am in the Knowledge Section of a Qontak360 AI Agent, when I select "Conversation History", choose a Division and pick agents, then the system initiates ingestion and shows "Training in Progress".
  • AC-2: Given I go to the AI Resources menu, when I click "Add source", then a "Conversation History" option is shown and I can choose a Division or pick agents.
  • AC-3: Given I save a valid source, when creation succeeds, then a new row appears in the Knowledge Index with status "Training in Progress" and a guidance tooltip ("Select agents with proven expertise") was shown during selection.
  • AC-4: Given I am creating a new AI Agent, when I reach "What sources does your agent learn from?", then a "Conversation history" row is shown; clicking + opens the division+agent picker (bypassing the main source list); after saving, the button updates to "N selected" showing the agent count.
  • AC-5: Given I am in the Capabilities tab of an existing AI Agent ([id].vue), when I click "Add source" in a capability edit drawer or inline from the capability card, then "Conversation history" is available; the added source appears as a pill with a "Training" badge; the capability edit drawer shows a status banner for in-progress or failed sources.

Error Path:

  • ERR-1: Given the division/agent directory fails to load, when the modal opens, then a load error with Retry is shown and Save is disabled.

Permission Model: CAN: Admin/Super Admin (Qontak360). CANNOT: Agents, lower tiers. Unauthorized: option not rendered for ineligible roles/plans.

UI States: Loading (directory fetch), Empty (no source yet), Error (load failed + Retry), Success ("Training in Progress" entry created).

Figma: node 18883-4459 / 10853-57617. Dependencies: None.

Prototype (feat/resources-conv-history):

  • AddKnowledgeDrawer.vue — "Add source" sub-drawer lists Conversation History, calling handleNewSourceSelect() (AC-1/2 entry). showAddConvHistoryModal — division+agent picker modal with addConvFilteredDivisions + per-division agent checkboxes. resources/index.vue — source row appears with "Processing" status after save (AC-3).
  • create/index.vue (AC-4) — knowledgeSources array (line 1064–1069) includes the "Conversation history" row. AddKnowledgeDrawer bound with :direct-sub-flow="'conversation-history'" (line 398–411) bypasses the main list and jumps to the conv-history sub-flow. selectedCountFor("conversation-history") (line 1278–1285) returns agentIds.length or agentCount for the "N selected" label. Present in both Guided form and Write prompt tab sections.
  • [id].vue (AC-5) — three AddKnowledgeDrawer usages: capability edit drawer (line 3521), global agent-level Sources (line 3537), inline from capability card body (line 3546). Capability card body (line 1055–1092) renders conv-history as a source pill with "Training" (warning) / "Failed" (critical) TrainingStatusBadge. Capability edit drawer (line 2362–2432) shows a status banner with counts of in-progress and failed sources.
  • ERR-1 (directory load error) not in prototype.

CONVHIST-S02 — Remove Conversation History from an AI Agent | Must Have

Story: As a user, I want to remove the Conversation History knowledge from my AI Agent. (TEMP-3452f2e4)

Before: No way to unlink a conversation-history source from an agent. After: A minus (−) control unlinks the source from the agent without deleting the underlying knowledge.

Data Fields:

FieldTypeRequiredSource
ai_agent_iduuidYesRoute
knowledge_source_iduuidYesSelected row

Happy Path:

  • AC-1: Given I edit an AI Agent and go to the Knowledge section, when I click the − button beside the Conversation History knowledge, then it is unlinked from this agent.
  • AC-2: Given I unlink the source, when the action completes, then the underlying Conversation History knowledge is not deleted (it remains available in AI Resources).
  • AC-3: Given the source is unlinked, when the agent next answers, then it no longer references that conversation history.

Error Path:

  • ERR-1: Given the unlink request fails, when I click −, then the source stays linked and an error is shown.

Permission Model: CAN: Admin/Super Admin. CANNOT: Agents.

UI States: Loading (removing), Empty (no sources linked), Error (failed), Success (source removed from list).

Dependencies: CONVHIST-S01.

Prototype (feat/resources-conv-history):

  • AddKnowledgeDrawer.vueshowConvHistoryDrawer — "Conversation history" drawer with MpToggle id="conv-history-toggle" v-model:is-checked="convHistoryEnabled" implements the unlink toggle (AC-1/2); toggling off unlinks without deleting the underlying source.
  • [id].vue (capability-level removal) — removeKnowledge(index) called from the minus-circular button in the capability edit drawer Sources section (line 2433–2468) removes conv-history from an individual capability without deleting the underlying source (AC-1/2).
  • ERR-1 (unlink failure) not in prototype.

CONVHIST-S03 — Delete Conversation History knowledge | Must Have

Story: As a user, I want to delete the Conversation History knowledge for my AI Agent. (TEMP-2bcdd6e5)

Before: No delete path with usage protection. After: Delete from AI Resources, guarded by an "in use" check; deletion hard-deletes the indexed vectors.

Data Fields:

FieldTypeRequiredSource
knowledge_source_iduuidYesSelected row
in_usebooleanYesSystem (computed)

Happy Path:

  • AC-1: Given I am in the AI Resources menu viewing a Conversation History knowledge, when I click Delete and no AI Agent uses it, then the system shows a confirmation prompt.
  • AC-2: Given I confirm deletion of an unused source, when deletion proceeds, then all associated indexed vectors for that division are hard-deleted and the row is removed.
  • AC-3: Given a source has been deleted, when I want it back, then it cannot be restored — I must create a new source to re-index (no undo).

Error Path:

  • ERR-1: Given the knowledge is used by one or more active AI Agents, when I click Delete, then the system blocks deletion and shows an error: I must remove it from those AI Agents first.

Permission Model: CAN: Admin/Super Admin. CANNOT: Agents. CANNOT: a deleted source cannot be restored (re-create to re-index).

UI States: Loading (deleting), Empty (N/A), Error (in-use block), Success (knowledge removed).

Dependencies: CONVHIST-S02.

Prototype (feat/resources-conv-history): SourceDetailDrawer.vue — footer renders a "Delete" danger text-link (deleteLinkClass) for conversation-history type (AC-1/2). resources/index.vue — row delete action available. AC-3 (no restore) and ERR-1 (in-use block) are backend behaviors not in prototype.


CONVHIST-S04 — Agent selection cap (15) | Must Have

Story: As QA, I want the system to limit agent selection to 15, so that processing performance and quality are maintained. (TEMP-12664d21)

Before: No cap on selectable agents. After: Selection is capped at 15 with a live counter and validation.

Data Fields:

FieldTypeRequiredSource
agent_idsarrayYesUser selection
max_agentsint (15)YesSystem constant

Happy Path:

  • AC-1: Given I am selecting agents, when I select up to 15, then selection is allowed and Save is enabled.
  • AC-2: Given I am selecting agents, when the count changes, then a live counter shows "N/15 selected".
  • AC-3: Given I am at 16 and over the cap, when I deselect back to ≤15, then the validation message clears and Save re-enables.

Error Path:

  • ERR-1: Given I have selected 15 agents, when I attempt to select the 16th, then a validation message appears ("Please limit selection to your top 15 experts") and Save is disabled.

Permission Model: CAN: Admin/Super Admin.

UI States: Loading (N/A), Empty (none selected → Save disabled), Error (cap exceeded message), Success (≤15 selected → Save enabled).

Dependencies: CONVHIST-S01.

⚠️ Prototype (feat/resources-conv-history): Not implemented. addConvSelectedAgentIds in AddKnowledgeDrawer.vue has no 15-agent cap, no live "N/15" counter, and no validation message. Must be implemented before build.


CONVHIST-S05 — Select a whole division | Must Have

Story: As an Admin, I want to quickly add a selected division as a Conversation History source, so that all agents under that division become a knowledge source. (TEMP-77aff3c9)

Before: Agents must be picked individually. After: Selecting a division marks its agents as selected (still capped at 15); individuals can be deselected.

Data Fields:

FieldTypeRequiredSource
division_iduuidYesUser selection
included_agent_idsarray (≤15)YesSystem (derived) + user edits

Happy Path:

  • AC-1: Given I am in the Knowledge Section, when I open the selector, then the system shows all divisions including the agents under each.
  • AC-2: Given I select a division, when I confirm, then all agents under it are marked as selected (capped at 15) and I can click Save.
  • AC-3: Given a division is selected, when I deselect specific agents, then those are excluded while the rest remain selected.

Error Path:

  • ERR-1: Given a division has more than 15 agents, when I select it, then the cap rule (S04) applies — I must narrow to 15 before Save.

Permission Model: CAN: Admin/Super Admin.

UI States: Loading (division/agent fetch), Empty (no divisions), Error (cap exceeded), Success (division's agents selected).

Dependencies: CONVHIST-S04.

Prototype (feat/resources-conv-history): AddKnowledgeDrawer.vueaddConvToggleDivision(divId) implements division-level checkbox select (AC-2); addConvIsDivisionAll(divId) / addConvIsDivisionPartial(divId) drive the full/indeterminate checkbox state; addConvToggleAgent() deselects individual agents within a division (AC-3). ERR-1 (cap triggered on division select) is blocked by the S04 gap — cap not yet enforced.


CONVHIST-S06 — PII data masking | Must Have

Story: As a Compliance Officer, I want PII redacted, so that sensitive customer data is not leaked into AI responses. (TEMP-abb97fb2 — Data & AI team)

Before: Raw chat data would carry PII into the vector DB. After: A mandatory masking service redacts PII to generic tags before indexing.

Data Fields:

FieldTypeRequiredSource
raw_messagetextYesChat ingestion
masked_messagetextYesMasking engine
entity_tagsarray (e.g. [EMAIL], [PHONE_NUMBER])YesMasking engine

Happy Path:

  • AC-1: Given a chat contains an email ("customer@email.com") and a phone ("0812345678"), when the ingestion engine processes the room, then the indexed data replaces them with [EMAIL] and [PHONE_NUMBER] tags.
  • AC-2: Given a chat contains an address, credit-card/bank, or national-ID, when ingested, then those entities are redacted to generic tags.
  • AC-3: Given redaction occurs, when the message is indexed, then conversation structure is preserved (the AI sees [PHONE_NUMBER], not the digits).

Error Path:

  • ERR-1: Given the masking service fails for a room, when ingestion runs, then that room is not indexed and the source status reflects "Error"/"Last Successful Sync" with an Admin notification.

Permission Model: System rule (Data & AI pipeline).

UI States: N/A (backend) — surfaced via source status.

Dependencies: CONVHIST-S01.


CONVHIST-S07 — Quality gate (noise filter) | Should Have

Story: As a PM, I want to exclude short/junk chats, so that the AI doesn't learn from "empty" interactions. (TEMP-383496c3)

Before: All resolved rooms would be eligible. After: Rooms with fewer than 5 bubble messages are skipped.

Data Fields:

FieldTypeRequiredSource
room_iduuidYesChat service
message_countintYesSystem (customer-facing only)
min_messagesint (5)YesSystem constant

Happy Path:

  • AC-1: Given a resolved room has only 3 messages, when the daily sync / ingestion runs, then the system skips the room and does not index it.
  • AC-2: Given a resolved room has ≥5 customer-facing messages, when ingestion runs, then it is eligible for indexing.
  • AC-3: Given a room has ≥5 messages but only 4 are customer-facing after whisper exclusion (S08), when counted, then it is treated as <5 and skipped.

Error Path:

  • ERR-1: Given a room has ≥5 messages but they are all non-text, when filtered, then it yields no indexable content and is skipped (see S13).

Permission Model: System rule.

UI States: N/A (backend).

Dependencies: CONVHIST-S06.


CONVHIST-S08 — Internal privacy (exclude whispers) | Must Have

Story: As an Agent, I want my internal notes/whispers excluded, so that they aren't exposed to customers by the AI. (TEMP-1cef587e)

Before: Ingestion could pick up internal-only messages. After: Only customer-facing bubbles are indexed; internal notes/whispers excluded.

Data Fields:

FieldTypeRequiredSource
message_typeenum (customer_facing / internal_note)YesChat service
is_indexablebooleanYesSystem (derived)

Happy Path:

  • AC-1: Given a room has 10 customer-facing bubbles and 2 "Internal Whispers", when the system ingests the room, then only the 10 customer-facing bubbles are indexed.
  • AC-2: Given an internal whisper contains PII, when ingestion runs, then it is excluded entirely (independent of masking).
  • AC-3: Given a room mixes customer bubbles and system/bot internal events, when ingested, then only customer-facing agent/customer bubbles are indexed.

Error Path:

  • ERR-1: Given a room contains only internal whispers, when ingestion runs, then nothing is indexed for that room.

Permission Model: System rule.

UI States: N/A (backend).

Dependencies: CONVHIST-S06.


CONVHIST-S09 — Recency prioritization | Should Have

Story: As an AI Agent, I want to prioritize the most recent resolutions when conflicts occur, so that I follow the latest SOP. (TEMP-00bf245c)

Before: No conflict-resolution rule between differing historical answers. After: On conflict, the most recent resolved room wins.

Data Fields:

FieldTypeRequiredSource
resolution_datedatetimeYesChat service
query_typestringYesSystem (matched intent)

Happy Path:

  • AC-1: Given Agent A solved a "Tax" query in January and Agent B solved it differently in March, when a user asks that Tax query, then the AI generates a response based on the March resolution.
  • AC-2: Given several recent resolutions match the same query, when ranked, then the single most-recent resolution is used as the primary reference.
  • AC-3: Given two conflicting resolutions share the same resolution date, when ranked, then a deterministic tie-break applies (e.g., most recent room_id) so output is stable.

Error Path:

  • ERR-1: Given recency metadata is missing for a room, when ranking runs, then that room is de-prioritized rather than crashing the ranking.

Permission Model: System rule.

UI States: N/A (backend).

Dependencies: CONVHIST-S06.


CONVHIST-S10 — Daily maintenance sync (rolling 90 days) | Must Have

Story: As an Admin, I want the knowledge to stay fresh via a rolling 90-day window. (TEMP-0d9af881 — Data & AI team)

Before: No automated freshness; knowledge would go stale. After: A 24-hour cron ingests new resolutions and purges data past 90 days.

Data Fields:

FieldTypeRequiredSource
sync_run_iduuidYesSystem
new_messages_ingestedintYesSystem
purged_messages_countintYesSystem
last_updateddatetimeYesSystem

Happy Path:

  • AC-1: Given the 24-hour cron runs, when data reaches 91 days old, then the system purges the 91st-day data and ingests the last 24 hours' resolutions.
  • AC-2: Given a successful sync, when it completes, then the source "Last Updated" timestamp advances.
  • AC-3: Given there were no new resolutions in the last 24 hours, when the sync runs, then it still purges aged data and updates "Last Updated".

Error Path:

  • ERR-1: Given the sync job fails, when it errors, then the previous index is retained, the failure is alerted, and status reflects "Last Successful Sync".

Permission Model: System rule (scheduled job).

UI States: Success ("Last Updated" advances) / Error (status reflects last successful sync).

Dependencies: CONVHIST-S06.


Story: As an Admin, I want to see the source Room ID for AI answers, so that I can verify accuracy. (TEMP-699b67cf)

Before: AI answers have no traceable source. After: Answers can include a permission-scoped link to the source room.

Data Fields:

FieldTypeRequiredSource
room_iduuidYesIndex reference
requesting_user_permissionsscopeYesAuth session

Happy Path:

  • AC-1: Given the AI provides an answer derived from history, when an authorized Admin views it, then a reference link to the source Room ID is available and opens the room.
  • AC-2: Given an answer drew on multiple rooms, when references render, then the primary (most recent) source room is shown.
  • AC-3: Given an answer used no conversation-history source, when it renders, then no room-id reference is shown.

Error Path:

  • ERR-1: Given the AI answer includes a Room ID link, when a user from a different division clicks it, then access is denied with a permission error.

Permission Model: CAN: users with view permission for that room. CANNOT: users outside the room's division.

UI States: Success (link opens room), Error (permission denied).

Dependencies: CONVHIST-S06.


CONVHIST-S12 — Agent deactivation | Should Have

Story: As QA, I want a departed agent's vetted knowledge to remain useful for a period. (TEMP-76324b9b)

Before: Unclear what happens to a selected agent's history when they leave. After: A deactivated agent's history remains until it ages out of the 90-day window; no new ingestion for them.

Data Fields:

FieldTypeRequiredSource
agent_iduuidYesSource config
agent_statusenum (active / deactivated)YesMekari directory
resolution_datedatetimeYesChat service

Happy Path:

  • AC-1: Given Agent C has been deactivated in Mekari, when the knowledge base is queried, then Agent C's historical data remains usable until it naturally ages out of the 3-month window.
  • AC-2: Given Agent C is deactivated, when the daily sync runs, then no new conversations are ingested for Agent C going forward.
  • AC-3: Given Agent C's data has aged past 90 days, when the daily sync runs, then it is purged like any other expired data.

Error Path:

  • ERR-1: Given Agent C is reactivated within the window, when the next sync runs, then ingestion resumes for new resolutions without duplicating existing indexed data.

Permission Model: System rule.

UI States: N/A (backend).

Dependencies: CONVHIST-S10.


CONVHIST-S13 — Multi-media exclusion (text-only) | Must Have

Story: As a Developer, I want only text processed, so that unsupported formats don't crash ingestion. (TEMP-b54d68cf)

Before: Mixed-content rooms could break ingestion. After: Only text content is indexed; images/attachments/voice are ignored.

Data Fields:

FieldTypeRequiredSource
message_content_typeenum (text / image / file / voice)YesChat service
is_indexablebooleanYesSystem (derived)

Happy Path:

  • AC-1: Given a resolved room contains text and one PDF/image attachment, when ingestion occurs, then the system indexes the text content and ignores/excludes the attachment.
  • AC-2: Given a message is an image with a text caption, when ingested, then the caption text is indexed and the image is excluded.
  • AC-3: Given a message is a voice note, when ingested, then it is excluded and no transcript is generated (out of scope this phase).

Error Path:

  • ERR-1: Given a room contains only non-text content, when ingestion runs, then nothing is indexed for that room and it does not error the batch.

Permission Model: System rule.

UI States: N/A (backend).

Dependencies: CONVHIST-S07.


Negative Scenarios

  • NEG-1: Given a non-Qontak360 account, when an Admin opens Add Knowledge, then "Conversation History" is not offered.
  • NEG-2: Given a selected agent has zero resolved chats in the last 3 months, when ingestion runs, then that agent is ignored and the others proceed.
  • NEG-3: Given an Admin tries to add a second Conversation History source to a division that already has one, when they attempt it, then the system blocks it (one Division = one source).
  • NEG-4: Given an internal whisper contains PII, when ingestion runs, then it is excluded entirely (internal-only), independent of masking.

11. Rollout

  • Feature flag: TBD (align with engineering) | default: OFF. Enabled per account on Qontak360.
  • Stage 1: Internal Alpha — Mekari internal CS/Support team.
  • Stage 2: Closed Beta — 5–10 selected Qontak360 early adopters.
  • Stage 3: Open Beta / Limited GA — all Service Suite and Pro-above clients.
  • GA: All eligible Qontak360 accounts with full GTM.
  • Backward compat: Yes — additive; static PDF/URL sources unaffected.
  • Migration: None — new conversation_history knowledge type; no backfill.

12. Observability

Event NameTriggerProperties
knowledge_source_add_clickAdmin clicks "Add Knowledge"source_type: conversation_history
conv_history_config_saveAdmin clicks Save after selecting agentsdivision_id, agent_count (1–15), source_id
conv_history_training_statusTraining state changesstatus (success/failed/in_progress), duration_seconds, error_message (if failed)
conv_history_daily_sync24-hour background job completesnew_messages_ingested, purged_messages_count, sync_status

Dashboard owner: BOT squad (Hadiningbot).

Alerts:

  • conv_history_training_status = failed (3 consecutive for one source) → Slack: BOT squad alert channel.
  • conv_history_daily_sync = failed → Slack alert + escalation to the Data & AI team.

Post-Launch Monitoring Cadence: Weekly for the first 4 weeks post-GA, then monthly. Owner: Dimas (BOT squad PM). Triggers: training failure rate spikes or daily sync failures → investigate within 48h. Rollback: if masking/indexing failures are widespread and unresolved within the SLA, PM disables the flag for affected accounts pending fix.


13. Success Metrics

Primary KPI: Feature adoption

  • Definition: % of active Qontak360 companies that configured ≥1 "Conversation History" training source
  • Baseline: N/A — new feature
  • Target: ≥ 30% of AI-Agent-active Qontak360 companies within 90 days of GA

Adoption: Knowledge contribution ratio

  • Definition: % of an AI Agent's total "Reference Hits" that come from Conversation History vs PDF/Website sources
  • Baseline: N/A
  • Target: Established during beta

Quality: AI resolution rate uplift + Feature CSAT

  • Definition: Reduction in "Unanswered Question" count after adding Conversation History; SPV/Admin CSAT on ease of training the AI from agent data
  • Baseline: N/A — measured pre/post per client
  • Target: Measurable reduction within 60 days; CSAT target set in beta

Efficiency: Onboarding speed + knowledge freshness

  • Definition: Reduction in new-agent time-to-productivity in active divisions; daily sync success (rolling 3-month window maintained)
  • Baseline: N/A
  • Target: Sync success ≥ 99%; onboarding-speed target set in beta

14. Launch Plan & Stage Gates

StageAudienceDurationSuccess GateOwner
Internal AlphaMekari internal CS/Support2 weeks100% masking of standard phone/email formats; <1h training for 15 agentsPM + QA
Closed Beta5–10 selected Qontak360 early adopters3 weeks>70% of AI suggestions accepted ("Add to Compose") by human agentsPM + CSM
Open Beta / Limited GAAll Service Suite + Pro-above3 weeksNo significant performance degradation during the 24-hour sync windowEng Lead
GAAll eligible Qontak360 accountsOngoingKPIs sustained at scale; GTM/localized marketing in motionPM + PMM

15. Dependencies

DependencyOwning TeamDeliverable NeededBlocking?
PII masking engineData & AI teamNLP redaction of emails/phones/addresses/financial/identity → generic tags, before indexingYES
Conversation training serviceData & AI teamIsolated service to process heavy conversation data + vector indexingYES
Training-status webhookData & AI teamWebhook to update Qontak on in_progress/completed/failedYES
Agent–Division mapping APIBOT (chatbot)Endpoint to list divisions + agents for the config modalYES
Daily sync cronBOT (chatbot)Scheduled 24h job: ingest prior day, purge >90 daysYES
Resolved-room fetch (Inbox/Chat)Inbox / PlatformFetch resolved rooms by agent over a 90-day windowYES
Onboarding consent formLegal / OpsExisting consent covering use of agent–customer interactions for internal AI trainingNO — reuse existing

16. Key Decisions + Alternatives Rejected

Initiative-level decisions live in the ANCHOR PRD §5. Below are phase-specific decisions.

16a — Decisions Made

DateDecisionRationale
2026-04-13Max 15 agents per division-sourceBalances quality (curated experts) with processing speed; avoids noise
2026-04-133-month rolling window + daily syncKeeps knowledge aligned to current SOPs without manual upkeep
2026-04-13Recency rule for conflicting resolutionsL/E processes evolve; the latest resolution most likely follows current SOP
2026-04-13One Division = one Conversation History sourcePrevents conflicting domain knowledge
2026-04-13Reuse existing "Training Source" UIFaster delivery + UI consistency

16b — Alternatives Rejected

AlternativeWhy RejectedDate
Full company-wide history ingestionHigh noise/risk — low-performer and junk data degrade accuracy2026-04-13
Manual QA export + re-upload as PDF/ExcelHigh friction; defeats the automation value prop2026-04-13
Division-wide auto-inclusion without agent selectionNo control to prioritize senior experts over new joiners2026-04-13
Real-time ingestion (MVP)Complexity/cost; daily sync is sufficient for the first release (deferred)2026-04-13
Multi-media ingestion (MVP)Scope/complexity; text-only first (deferred)2026-04-13

17. Open Questions

#TypeQuestionOwnerDeadline
1RiskPII masking must redact all listed entities before indexing. Mitigation: mandatory NLP masking → generic tags; Internal Alpha gate requires 100% masking of standard phone/email formats before GA.Data & AI team2026-07-15
2Open QuestionJira epic + keys not yet created — stories are TEMP placeholders; delivery timeline (week-based in the draft) needs absolute dates.Dimas (PM)2026-07-01
3Open QuestionCopilot quota model for this source (e.g., 15 quota/seat Service Suite) — confirm metering and limits.Dimas (PM)2026-07-15
4Open QuestionTraining-status webhook contract (states, payload, retry/error semantics) from the Data & AI team.Data & AI team2026-07-15
5RiskReference-link permission scoping must deny cross-division access. Mitigation: validate requesting user's room-view permission on every reference open (S11/ERR-1).BOT (chatbot)2026-07-15
6Assumption"Resolved" status + ≥5 bubble messages is a sufficient proxy for a "complete, useful" resolution.Dimas (PM)2026-07-15
7RiskDesign coverage: feat/resources-conv-history implements the core add/unlink/delete flows and division-first multi-select (CONVHIST-S05 resolved), but the 15-agent cap/validation (S04) and expertise tooltip (S01/AC-3) are absent, and the "Error" training-status state is not covered. Mitigation: §8 updated to IMPLEMENTED with remaining gaps documented; engineering and designer (Wulan) to add S04 cap + tooltip before build.Wulan (Design)2026-07-15

PRD CHANGELOG

VersionDateBySectionTypeSummary
1.02026-06-18ClaudeAllCREATEDPhase 1 PRD authored in the documents-repo template under the new AI Agent: Knowledge ANCHOR. Reformatted from the Confluence "AI Agent Knowledge: Conversation History" draft: 13 stories converted to native blocks with composite AC ids (CONVHIST-S01…S13, TEMP tickets preserved); added Phase Context, structured Constraints (+ data lifecycle), Feature Changes, New Features, API table, System Flow, Rollout, Dependencies, and Open Questions (PII/webhook/quota/permission flagged).
1.12026-06-18ClaudeS8, S17MODIFIEDLocated the existing design in qontak-designer (AddKnowledgeDrawer / SourceDetailDrawer / resources page + Figma nodes) and cited it in §8. Marked §8 Design status as DRAFT and added Open Question #7 (Risk) flagging the prototype gaps for the designer to revisit: 15-agent cap/validation, expertise tooltip, division-first multi-select, training-status states.
1.22026-06-18ClaudeS8, S10MODIFIEDApplied score-prd improvements: added a Flow:/Type: declaration + explicit failure branches and a mermaid System Flow diagram (§10.1); added a hierarchical component tree + a mermaid UI-state diagram (§8); lifted every story to ≥3 happy-path ACs and converted all Data Fields to type/required/source tables (§10.2).
1.32026-06-30Claude§8, S01–S05, §17MODIFIEDAttached feat/resources-conv-history prototype implementation to the PRD. §8 Design status updated from DRAFT to IMPLEMENTED; gap list revised: gaps #3 (division-first multi-select) and #4 (training-status) marked resolved/partially resolved; gaps #1 (15-agent cap) and #2 (expertise tooltip) remain open. Prototype notes added to S01–S05 mapping each story's ACs to implementing components (AddKnowledgeDrawer.vue, SourceDetailDrawer.vue, resources/index.vue). S04 flagged ⚠️ not implemented. Open Question #7 updated to reflect current branch state.
1.42026-06-30Claude§7, §8, S01, S02MODIFIEDAdded two missing AI Agent entry points: (c) Create AI Agent (create/index.vue) — "What sources does your agent learn from?" conv-history row with directSubFlow drawer; (d) AI Agent detail [id].vue — Capabilities tab per-capability "Add source" (edit drawer, inline). §8 Component Tree expanded to cover all four entry points. S01 AC-4 and AC-5 added for create and capability flows. S01 prototype note updated to reference create/index.vue (lines 398–411, 1064–1069, 1278–1285) and [id].vue (three AddKnowledgeDrawer usages, source pills, status banners). S02 prototype note updated to add capability-level removal via removeKnowledge() in [id].vue.