Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .changeset/copilot-capability-drift.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
'hotcrm': patch
---

Write the two AI skill pages' capability lists back to what the skill sources
actually declare, in all three languages.

`content/docs/ai-copilot/service-copilot.mdx` and
`content/docs/ai-copilot/sales-copilot.mdx` (plus their `.zh-Hans` / `.zh-Hant`
siblings) listed abilities that `src/skills/case-triage.skill.ts` and
`src/skills/customer-360.skill.ts` do not have. PR #848 corrected one bullet on
each page (the ghost **Customer Since** field); this is the rest of the same
sweep, and it separates two different severities rather than treating them
alike.

**Class one — the tool surface cannot reach it (`case_triage`).**
`case-triage.skill.ts` declares `tools: ['describe_object', 'get_record']`.
`get_record` fetches one record by ID and there is no query tool of any kind, so
the Case Triage page's promises of *historical cases from the same account and
contact*, *the Support Knowledge knowledge base for matching articles* and *top
matching KB articles* were not merely unwritten instructions — nothing in the
skill can perform them. The *draft first reply* was worse still: it contradicted
the skill's own step 6, which hands the customer-facing reply to the
`email_drafting` skill by name. *Suggested category* named a job the
instructions never assign (they define a priority and one reason), and its
option list was wrong twice over — `crm_case.type` ships Question / Problem /
Feature Request / Bug, with no Billing option.

**Class two — reachable, but the instructions do not enumerate it
(`customer_360`).** That skill does carry `query_records`, so *recent activity*,
*contracts* and *marketing engagement* on the sales page, and *contract status*
and *last touchpoints* on the service page, are a narrower miss: the skill could
read `crm_contract` / `crm_campaign` / `crm_event` / `crm_task` and is simply
not told to. Both Customer 360° sections are now written from steps 2-4 of the
instructions — the related objects it does enumerate (`crm_contact`, `crm_case`
filtered on `is_closed`, `crm_opportunity`, published `crm_knowledge_article`),
the totals it takes from `aggregate_data` instead of adding up by hand, and the
three sections it answers in (**Account Snapshot** · **Active Work** ·
**Risks & Notes**) with record IDs cited inline.

Following PR #841 and PR #848, no capability name is deleted in silence. A
reader who arrives looking for case history, KB article matching or a first-reply
draft lands on a paragraph that says which skill does own it — Customer 360° for
the history and the article matches, Email Drafting for the reply — or that the
data has to come from the record's own related lists for now.

Whether either skill *should* be given more reach stays a product decision under
ADR-0109 and is deliberately not pre-empted here: `src/**` is untouched and no
tool list changed. Whether the **Support Knowledge** knowledge base exists as an
entity is likewise out of scope — that is issue #808; this change speaks only to
what tools the skills hold and what their instructions say.

Chinese field and option names follow `src/translations/zh-CN.ts` (the #825
precedent): the case type options are 咨询 / 故障 / 功能需求 / 缺陷, and
`crm_campaign` is 营销活动 in zh-Hans (PR #849) and 行銷活動 in zh-Hant.

Documentation only — no metadata, behaviour, field or skill changes.
Fixes #847.
24 changes: 19 additions & 5 deletions content/docs/ai-copilot/sales-copilot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,25 @@ manager sees their team's, a director sees the rollup.
On any account or contact, ask *"Give me a 360° view"* and you get:

- **Relationship snapshot** — the account's **Customer Tier** and its owner, read straight off the account record. There is no *customer-since* date to snapshot: `crm_account` carries no field of any name for when an account became a customer, so "how long have they been with us?" has to be answered from the contract's **Signed Date** or **Start Date**.
- **Active deals** — open opportunities with stage and amount.
- **Recent activity** — last call, meeting, email.
- **Open cases** — any service tickets, with priority and age.
- **Contracts** — active and upcoming renewals.
- **Marketing engagement** — recent campaigns the customer engaged with.
- **The people** — the account's contacts, primary contact first.
- **Active deals** — open opportunities with stage, amount and close date, plus the open pipeline total read from `aggregate_data` rather than added up row by row.
- **Open cases** — service cases where `is_closed` is false, newest first, with the case count by status.
- **Matching knowledge** — published `crm_knowledge_article` records, matched on the category or tags of those cases.

The answer comes back in three sections — **Account Snapshot** · **Active Work** ·
**Risks & Notes** — with record IDs cited inline (`CASE-01234`, `KA-0007`) so the UI
can deep link. A risk has to name its record and the signal behind it: an escalated
case, a close date already past, a deal with no activity in 30+ days. A section with
no records is reported as empty rather than filled.

**What Customer 360° does not pull.** Three lines this page used to carry — **recent
activity** (last call, meeting, email), **contracts** (active and upcoming renewals)
and **marketing engagement** (recent campaigns the customer engaged with) — are not in
the skill's instructions, so they will not appear in the answer. This is not a tool
ceiling: the skill carries `query_records` and could reach `crm_contract`,
`crm_campaign`, `crm_event` and `crm_task`. It is simply not told to read them, and
widening what a skill reads is a product decision rather than a documentation one.
Until then, read those from the account's own related lists.

Perfect for prep before a meeting — "give me Customer 360 on Acme" and you walk in
informed.
Expand Down
22 changes: 17 additions & 5 deletions content/docs/ai-copilot/sales-copilot.zh-Hans.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,23 @@ ObjectStack 环境已经自带的 **平台助手**(`ask`)之上。当你在
在任意客户或联系人上,问 *"给我一个 360° 视图"*,你会得到:

- **关系快照**——客户的**客户分层**与**客户负责人**,直接从客户记录上读到。没有"成为客户的日期"可供快照:`crm_account` 上没有任何名字的字段记录客户何时成为客户,所以"这家客户跟了我们多久"只能从合同的**签署日期**或**开始日期**去回答。
- **进行中的交易**——带阶段和金额的开放商机。
- **近期活动**——最近一次通话、会议、邮件。
- **未结工单**——任何服务工单,及其优先级和存续时长。
- **合同**——有效及即将到来的续约。
- **营销参与**——客户近期参与的活动。
- **相关的人**——这家客户的联系人,主要联系人排在最前。
- **进行中的交易**——带阶段、金额和预计成交日期的开放商机,外加开放管道总额——这个数取自 `aggregate_data`,而不是逐行加出来的。
- **未结工单**——`is_closed` 为 false 的服务工单,最新的排在最前,并附按状态分组的工单数。
- **匹配的知识**——已发布的 `crm_knowledge_article` 记录,按上述工单的分类或标签来匹配。

回答固定分三段——**Account Snapshot**(客户快照)·**Active Work**(进行中的工作)·
**Risks & Notes**(风险与备注),这三个小标题在技能里就是英文原文。每条都会内联引用记录
ID(`CASE-01234`、`KA-0007`),便于界面深链。风险必须点名它依据的记录和信号:一条已升级
的工单、一个已经过去的预计成交日期、一笔 30 天以上没有动静的交易。某一段没有记录时,它会
如实说没有,而不是拿东西填满。

**Customer 360° 不会拉取的东西。** 本页过去列过的三条——**近期活动**(最近一次通话、会议、
邮件)、**合同**(有效及即将到来的续约)、**营销参与**(客户近期参与的营销活动)——都不在
这个技能的 instructions 里,所以答案里不会出现它们。这不是工具面够不着:这个技能带
`query_records`,也够得着 `crm_contract`、`crm_campaign`、`crm_event` 和 `crm_task`;只是
没有被要求去读,而放宽一个技能读什么是产品决策,不是文档决策。在此之前,这些请从客户自己
的相关列表里看。

非常适合会前准备——"给我 Acme 的 Customer 360",你就能有备而来。

Expand Down
22 changes: 17 additions & 5 deletions content/docs/ai-copilot/sales-copilot.zh-Hant.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,23 @@ ObjectStack 環境已經自帶的 **平台助手**(`ask`)之上。當你在
在任意客戶或聯絡人上,問 *「給我一個 360° 視圖」*,你會得到:

- **關係快照**——客戶的**客戶分層**與**客戶負責人**,直接從客戶記錄上讀到。沒有「成為客戶的日期」可供快照:`crm_account` 上沒有任何名字的欄位記錄客戶何時成為客戶,所以「這家客戶跟了我們多久」只能從合約的**簽署日期**或**開始日期**去回答。
- **進行中的交易**——帶階段和金額的開放商機。
- **近期活動**——最近一次通話、會議、郵件。
- **未結工單**——任何服務工單,及其優先順序和存續時長。
- **合約**——有效及即將到來的續約。
- **行銷參與**——客戶近期參與的活動。
- **相關的人**——這家客戶的聯絡人,主要聯絡人排在最前。
- **進行中的交易**——帶階段、金額和預計成交日期的開放商機,外加開放管道總額——這個數取自 `aggregate_data`,而不是逐列加出來的。
- **未結工單**——`is_closed` 為 false 的服務工單,最新的排在最前,並附按狀態分組的工單數。
- **匹配的知識**——已發布的 `crm_knowledge_article` 記錄,按上述工單的分類或標籤來匹配。

回答固定分三段——**Account Snapshot**(客戶快照)·**Active Work**(進行中的工作)·
**Risks & Notes**(風險與備註),這三個小標題在技能裡就是英文原文。每條都會內聯引用記錄
ID(`CASE-01234`、`KA-0007`),便於介面深層連結。風險必須點名它依據的記錄和訊號:一筆已
升級的工單、一個已經過去的預計成交日期、一筆 30 天以上沒有動靜的交易。某一段沒有記錄時,
它會如實說沒有,而不是拿東西填滿。

**Customer 360° 不會拉取的東西。** 本頁過去列過的三條——**近期活動**(最近一次通話、會議、
郵件)、**合約**(有效及即將到來的續約)、**行銷參與**(客戶近期參與的行銷活動)——都不在
這個技能的 instructions 裡,所以答案裡不會出現它們。這不是工具面夠不著:這個技能帶
`query_records`,也夠得著 `crm_contract`、`crm_campaign`、`crm_event` 和 `crm_task`;只是
沒有被要求去讀,而放寬一個技能讀什麼是產品決策,不是文件決策。在此之前,這些請從客戶自己
的相關列表裡看。

非常適合會前準備——「給我 Acme 的 Customer 360」,你就能有備而來。

Expand Down
40 changes: 28 additions & 12 deletions content/docs/ai-copilot/service-copilot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,19 @@ Ask the assistant to triage a case and it analyses:

- The **subject** and **description**.
- The **customer's profile** — the account's **Customer Tier** and the **Contract Value**, which the triage rubric weighs first. How long they have been a customer is not weighed, and could not be: `crm_account` has no *customer-since* field under any name, and the closest real date sits on the contract (**Signed Date**).
- **Historical cases** from the same account and contact.
- The **product** referenced in the case.
- The **Support Knowledge** knowledge base for matching articles.

It returns:

- **Suggested priority** (Low / Medium / High / Critical) with a rationale tied to the [SLA matrix](/docs/service/sla-and-escalation).
- **Suggested category** (Bug, Question, Feature Request, Billing).
- **Top matching KB articles**.
- A **draft first reply** that acknowledges the issue and links to the KB articles.
- A pointer to the right next action — **Escalate Case** or **Close Case**.
- **Suggested priority** (Low / Medium / High / Critical) with the one reason that drove it, citing the case ID and the field values it read. After tier and contract value, the rubric weighs whether the customer is blocked with no workaround, how long the case has been open against the [SLA matrix](/docs/service/sla-and-escalation), and the sentiment of the latest customer message.
- A pointer to the right next action — **Escalate Case** with a ready-to-paste `reason`, or **Close Case** with a `resolution` summary.

**What triage does not do.** Three abilities this page used to list are outside the
skill, and it is worth saying where each one actually lives:

- **Historical cases, and matching Support Knowledge articles.** Triage declares exactly two tools — `describe_object` and `get_record`. `get_record` fetches one record by ID and the skill has no query tool at all, so it cannot pull the account's or contact's *other* cases and cannot search for articles. **Customer 360°** below is the skill that carries `query_records`: it reads `crm_case` and `crm_knowledge_article`, so ask it for the history and the article matches.
- **A suggested category.** Triage assigns a priority and stops there. **Case Type** stays a field a person sets on the case, and its real options are Question, Problem, Feature Request and Bug — there is no Billing type.
- **A draft first reply.** The skill hands the customer-facing reply to **Email Drafting** (section 3 below) by name rather than writing it itself. Ask for the draft as a second question and that skill takes it.

Agents accept, edit, or reject each suggestion individually. The skill never changes
the case on its own: it hands off to the same `escalate_case` / `close_case` actions
Expand All @@ -56,11 +58,25 @@ an agent would click.

On any case, ask *"Give me the customer's history"* and you get:

- **All prior cases** (open and closed) for the same contact and account.
- **Contract status** — what they've bought, when it expires, what tier of support they're entitled to.
- **Active opportunities** — so the agent knows if they're talking to a customer mid-purchase.
- **Last touchpoints** — recent emails, calls, meetings.
- **Account health signals** — escalations, churn risk flags, satisfaction scores.
- **The people** — the account's contacts, primary contact first.
- **Open cases** — the account's cases where `is_closed` is false, newest first. Closed cases are not listed row by row; the case count by status comes from `aggregate_data`, which is what makes *"the 3rd time this quarter"* countable.
- **Active opportunities** — open deals with stage, amount and close date, so the agent knows whether they are talking to a customer mid-purchase.
- **Matching knowledge** — published `crm_knowledge_article` records, matched on the category or tags of the cases it just read.

The answer comes back in three sections — **Account Snapshot** · **Active Work** ·
**Risks & Notes** — with record IDs cited inline (`CASE-01234`, `KA-0007`) so the UI
can deep link. A risk has to name its record and the signal behind it: an escalated
case, a close date already past, a deal with no activity in 30+ days.

**What Customer 360° does not pull.** **Contract status** (what they bought, when it
expires, the support tier they are entitled to) and **last touchpoints** (recent
emails, calls, meetings) are not in the skill's instructions, and neither is a churn
or satisfaction roll-up. This is a narrower miss than the triage one above: the skill
*does* carry `query_records` and could reach `crm_contract`, `crm_event` and
`crm_task` — it is simply not told to read them, and widening what a skill reads is a
product decision rather than a documentation one. Until then, read those from the
account's own related lists; the one health signal the skill does report is the
escalation, cited from the case record.

This is the difference between *"I see this is your first case"* and *"I see this is
the 3rd time you've hit this issue this quarter — let me escalate."*
Expand Down
Loading
Loading