@opencx/mcp 1.11.87 → 1.11.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-sankey.d.ts","sourceRoot":"","sources":["../../src/tools/conversation-sankey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"conversation-sankey.d.ts","sourceRoot":"","sources":["../../src/tools/conversation-sankey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA0DrD,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,QA2HtF"}
|
|
@@ -1,19 +1,62 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { jsonContent } from '../api-client.js';
|
|
3
|
+
// Source of truth: SANKEY_DIMENSION_KEYS in backend/src/reports/dto/sankey.dto.ts. Surfacing the
|
|
4
|
+
// enum (instead of a free-form string) lets the model see the exact valid keys; the public route
|
|
5
|
+
// stays the validation backstop.
|
|
6
|
+
const SANKEY_DIMENSION_KEYS = [
|
|
7
|
+
'all_tickets',
|
|
8
|
+
'replied_by',
|
|
9
|
+
'outcome',
|
|
10
|
+
'handoff',
|
|
11
|
+
'channel',
|
|
12
|
+
'integration_source',
|
|
13
|
+
'assist_mode',
|
|
14
|
+
'contact_custom_data',
|
|
15
|
+
'session_custom_data',
|
|
16
|
+
'sentiment',
|
|
17
|
+
'status',
|
|
18
|
+
'assigned_team',
|
|
19
|
+
'contact_source',
|
|
20
|
+
'csat',
|
|
21
|
+
'handoff_reason',
|
|
22
|
+
'contact_reason',
|
|
23
|
+
];
|
|
24
|
+
// Each element is either a bare dimension key, or {dimension, customDataKey} to give a custom-data
|
|
25
|
+
// column its own jsonb key — so two custom-data dimensions can each read a different key in one
|
|
26
|
+
// request. Mixing is fine: ["channel", {dimension:"contact_custom_data", customDataKey:"tier"}].
|
|
27
|
+
const dimensionsInput = z
|
|
28
|
+
.array(z.union([
|
|
29
|
+
z.enum(SANKEY_DIMENSION_KEYS),
|
|
30
|
+
z.object({
|
|
31
|
+
dimension: z.enum(SANKEY_DIMENSION_KEYS),
|
|
32
|
+
customDataKey: z
|
|
33
|
+
.string()
|
|
34
|
+
.describe('The jsonb key this custom-data column reads (contact/session custom_data).'),
|
|
35
|
+
}),
|
|
36
|
+
]))
|
|
37
|
+
.min(1)
|
|
38
|
+
.max(6)
|
|
39
|
+
.describe('Ordered dimensions, 1–6, built left→right. Each is a key ("outcome") or {dimension, ' +
|
|
40
|
+
'customDataKey} for a per-column custom-data key. E.g. ["replied_by","outcome"] or ' +
|
|
41
|
+
'[{"dimension":"contact_custom_data","customDataKey":"tier"},{"dimension":"session_custom_data","customDataKey":"plan"}].');
|
|
42
|
+
// Forward as the legacy CSV when every element is a bare key (keeps custom_data_key working), or as
|
|
43
|
+
// the JSON [{dimension, customDataKey}] form the public route also accepts once any element carries
|
|
44
|
+
// its own key. JSON keeps keys with commas/colons/spaces intact.
|
|
45
|
+
function encodeDimensions(dimensions) {
|
|
46
|
+
return dimensions.some((d) => typeof d !== 'string')
|
|
47
|
+
? JSON.stringify(dimensions.map((d) => (typeof d === 'string' ? { dimension: d } : d)))
|
|
48
|
+
: dimensions.join(',');
|
|
49
|
+
}
|
|
3
50
|
export function registerConversationSankeyTools(server, client) {
|
|
4
51
|
server.registerTool('get_conversation_sankey', {
|
|
5
52
|
description: 'Get a Sankey breakdown of how conversations flow through a chosen set of attributes. ' +
|
|
6
|
-
'Pass an ordered
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'"assist_mode,contact_custom_data" (assist-mode sessions split by a contact custom_data key). ' +
|
|
12
|
-
'Defaults to the last 30 days.',
|
|
53
|
+
'Pass an ordered list of dimension keys and the flow is built left-to-right between them. ' +
|
|
54
|
+
'Returns { nodes, links }. Examples: ["integration_source","channel"] (e.g. HubSpot → email ' +
|
|
55
|
+
'vs web), ["assist_mode","contact_custom_data"] (assist-mode sessions split by a contact ' +
|
|
56
|
+
'custom_data key), ["handoff_reason","csat"] (why the AI escalated vs the CSAT it earned), ' +
|
|
57
|
+
'["contact_reason","outcome"] (topic → resolution). Defaults to the last 30 days.',
|
|
13
58
|
inputSchema: {
|
|
14
|
-
dimensions:
|
|
15
|
-
.string()
|
|
16
|
-
.describe('Ordered, comma-separated dimension keys, 1–6 of them. E.g. "replied_by,outcome".'),
|
|
59
|
+
dimensions: dimensionsInput,
|
|
17
60
|
custom_data_key: z
|
|
18
61
|
.string()
|
|
19
62
|
.optional()
|
|
@@ -29,7 +72,74 @@ export function registerConversationSankeyTools(server, client) {
|
|
|
29
72
|
},
|
|
30
73
|
}, async ({ dimensions, custom_data_key, start_date, end_date }) => {
|
|
31
74
|
const data = (await client.GET('/impact-report/sankey', {
|
|
32
|
-
params: {
|
|
75
|
+
params: {
|
|
76
|
+
query: { dimensions: encodeDimensions(dimensions), custom_data_key, start_date, end_date },
|
|
77
|
+
},
|
|
78
|
+
})).data;
|
|
79
|
+
return jsonContent(data);
|
|
80
|
+
});
|
|
81
|
+
server.registerTool('get_sankey_dimensions', {
|
|
82
|
+
description: 'List the dimensions a conversation-flow Sankey can be sliced by, and the ' +
|
|
83
|
+
"org's available custom-data keys (with labels). Call this BEFORE " +
|
|
84
|
+
'get_conversation_sankey to pick valid dimension keys and the custom_data_key ' +
|
|
85
|
+
'for contact_custom_data / session_custom_data (which differ per org).',
|
|
86
|
+
inputSchema: {},
|
|
87
|
+
}, async () => {
|
|
88
|
+
const data = (await client.GET('/impact-report/sankey/dimensions')).data;
|
|
89
|
+
return jsonContent(data);
|
|
90
|
+
});
|
|
91
|
+
server.registerTool('get_sankey_tickets', {
|
|
92
|
+
description: 'List the actual tickets (chat sessions) behind a clicked Sankey node or link. Pass the ' +
|
|
93
|
+
'SAME `dimensions` (and custom_data_key/dates) you gave get_conversation_sankey, plus a ' +
|
|
94
|
+
'`path` describing what was clicked: one {layerIndex, bucket} for a node, two for a link ' +
|
|
95
|
+
'(source column then target column). layerIndex is the 0-based position in `dimensions`; ' +
|
|
96
|
+
'bucket is the node\'s exact `bucket` label from the Sankey (an "Other (N)" label is ' +
|
|
97
|
+
'expanded server-side). Returns { tickets, total, hasMore }. Chain into investigate_session ' +
|
|
98
|
+
'on a returned ticket id to diagnose the "why" behind a flow.',
|
|
99
|
+
inputSchema: {
|
|
100
|
+
dimensions: dimensionsInput,
|
|
101
|
+
path: z
|
|
102
|
+
.array(z.object({
|
|
103
|
+
layerIndex: z
|
|
104
|
+
.number()
|
|
105
|
+
.int()
|
|
106
|
+
.min(0)
|
|
107
|
+
.describe('0-based index into `dimensions` (the clicked column).'),
|
|
108
|
+
bucket: z.string().describe("The node's exact bucket label from the Sankey."),
|
|
109
|
+
}))
|
|
110
|
+
.min(1)
|
|
111
|
+
.max(6)
|
|
112
|
+
.describe('1 constraint for a clicked node, 2 for a clicked link.'),
|
|
113
|
+
custom_data_key: z
|
|
114
|
+
.string()
|
|
115
|
+
.optional()
|
|
116
|
+
.describe('The jsonb key to read for a custom-data dimension (contact_custom_data or session_custom_data).'),
|
|
117
|
+
start_date: z
|
|
118
|
+
.string()
|
|
119
|
+
.optional()
|
|
120
|
+
.describe('Start date in ISO 8601 format. Defaults to 30 days ago.'),
|
|
121
|
+
end_date: z.string().optional().describe('End date in ISO 8601 format. Defaults to now.'),
|
|
122
|
+
limit: z.number().int().min(1).max(100).optional().describe('Page size (default 20).'),
|
|
123
|
+
offset: z
|
|
124
|
+
.number()
|
|
125
|
+
.int()
|
|
126
|
+
.min(0)
|
|
127
|
+
.optional()
|
|
128
|
+
.describe('Rows to skip for pagination (default 0).'),
|
|
129
|
+
},
|
|
130
|
+
}, async ({ dimensions, path, custom_data_key, start_date, end_date, limit, offset }) => {
|
|
131
|
+
const data = (await client.GET('/impact-report/sankey/tickets', {
|
|
132
|
+
params: {
|
|
133
|
+
query: {
|
|
134
|
+
dimensions: encodeDimensions(dimensions),
|
|
135
|
+
path: JSON.stringify(path),
|
|
136
|
+
custom_data_key,
|
|
137
|
+
start_date,
|
|
138
|
+
end_date,
|
|
139
|
+
limit,
|
|
140
|
+
offset,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
33
143
|
})).data;
|
|
34
144
|
return jsonContent(data);
|
|
35
145
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-sankey.js","sourceRoot":"","sources":["../../src/tools/conversation-sankey.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,MAAM,UAAU,+BAA+B,CAAC,MAAiB,EAAE,MAAoB;IACrF,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,WAAW,EACT,uFAAuF;YACvF,
|
|
1
|
+
{"version":3,"file":"conversation-sankey.js","sourceRoot":"","sources":["../../src/tools/conversation-sankey.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED