@posthog/mcp 0.14.1 → 0.16.0
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.
- package/LICENSE +64 -0
- package/README.md +64 -0
- package/dist/extensions/constants.d.ts +9 -0
- package/dist/extensions/constants.d.ts.map +1 -1
- package/dist/extensions/constants.js +9 -0
- package/dist/extensions/constants.mjs +9 -0
- package/dist/extensions/event-types.d.ts +1 -0
- package/dist/extensions/event-types.d.ts.map +1 -1
- package/dist/extensions/event-types.js +1 -0
- package/dist/extensions/event-types.mjs +1 -0
- package/dist/extensions/feedback.d.ts +41 -0
- package/dist/extensions/feedback.d.ts.map +1 -0
- package/dist/extensions/feedback.js +259 -0
- package/dist/extensions/feedback.mjs +200 -0
- package/dist/extensions/instrument-highlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-highlevel.js +23 -2
- package/dist/extensions/instrument-highlevel.mjs +25 -4
- package/dist/extensions/instrument-lowlevel.d.ts +4 -3
- package/dist/extensions/instrument-lowlevel.d.ts.map +1 -1
- package/dist/extensions/instrument-lowlevel.js +23 -2
- package/dist/extensions/instrument-lowlevel.mjs +25 -4
- package/dist/extensions/instrumentation.d.ts +33 -13
- package/dist/extensions/instrumentation.d.ts.map +1 -1
- package/dist/extensions/instrumentation.js +103 -9
- package/dist/extensions/instrumentation.mjs +99 -8
- package/dist/extensions/internal.js +9 -2
- package/dist/extensions/internal.mjs +9 -2
- package/dist/extensions/mcp-payloads.d.ts +19 -0
- package/dist/extensions/mcp-payloads.d.ts.map +1 -1
- package/dist/extensions/mcp-payloads.js +217 -7
- package/dist/extensions/mcp-payloads.mjs +210 -6
- package/dist/extensions/posthog-events.d.ts.map +1 -1
- package/dist/extensions/posthog-events.js +1 -0
- package/dist/extensions/posthog-events.mjs +1 -0
- package/dist/extensions/posthog-mcp.d.ts +23 -3
- package/dist/extensions/posthog-mcp.d.ts.map +1 -1
- package/dist/extensions/posthog-mcp.js +27 -1
- package/dist/extensions/posthog-mcp.mjs +27 -1
- package/dist/extensions/sanitization.d.ts.map +1 -1
- package/dist/extensions/sanitization.js +2 -1
- package/dist/extensions/sanitization.mjs +3 -2
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.mjs +5 -1
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +4 -4
- package/src/extensions/constants.ts +9 -0
- package/src/extensions/event-types.ts +1 -0
- package/src/extensions/feedback.ts +349 -0
- package/src/extensions/instrument-highlevel.ts +45 -2
- package/src/extensions/instrument-lowlevel.ts +49 -5
- package/src/extensions/instrumentation.ts +170 -17
- package/src/extensions/internal.ts +13 -2
- package/src/extensions/mcp-payloads.ts +443 -7
- package/src/extensions/posthog-events.ts +1 -0
- package/src/extensions/posthog-mcp.ts +74 -3
- package/src/extensions/sanitization.ts +14 -6
- package/src/index.ts +24 -3
- package/src/types.ts +120 -0
- package/src/version.ts +1 -1
package/LICENSE
CHANGED
|
@@ -217,6 +217,70 @@ limitations under the License.
|
|
|
217
217
|
limitations under the License.
|
|
218
218
|
|
|
219
219
|
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
The @posthog/core package in packages/core is licensed under the MIT License below.
|
|
223
|
+
Third-party code remains subject to its respective notices in this file.
|
|
224
|
+
This owning notice is preserved from posthog-js-lite, from which @posthog/core was migrated:
|
|
225
|
+
https://github.com/PostHog/posthog-js-lite/blob/5fb7bee96f739b243dfea5589e2027f16629e8cd/LICENSE
|
|
226
|
+
|
|
227
|
+
MIT License
|
|
228
|
+
|
|
229
|
+
Copyright (c) 2022 PostHog (part of Hiberly Inc)
|
|
230
|
+
|
|
231
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
232
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
233
|
+
in the Software without restriction, including without limitation the rights
|
|
234
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
235
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
236
|
+
furnished to do so, subject to the following conditions:
|
|
237
|
+
|
|
238
|
+
The above copyright notice and this permission notice shall be included in all
|
|
239
|
+
copies or substantial portions of the Software.
|
|
240
|
+
|
|
241
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
242
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
243
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
244
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
245
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
246
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
247
|
+
SOFTWARE.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
packages/core/src/error-tracking/parsers/index.ts and its compiled distributions contain code
|
|
252
|
+
derived from TraceKit. This license only applies to the relevant code.
|
|
253
|
+
|
|
254
|
+
MIT License
|
|
255
|
+
|
|
256
|
+
Copyright (c) 2013 Onur Can Cakmak onur.cakmak@gmail.com and all TraceKit contributors.
|
|
257
|
+
|
|
258
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
259
|
+
software and associated documentation files(the 'Software'), to deal in the Software
|
|
260
|
+
without restriction, including without limitation the rights to use, copy, modify,
|
|
261
|
+
merge, publish, distribute, sublicense, and / or sell copies of the Software, and to
|
|
262
|
+
permit persons to whom the Software is furnished to do so, subject to the following
|
|
263
|
+
conditions:
|
|
264
|
+
|
|
265
|
+
The above copyright notice and this permission notice shall be included in all copies
|
|
266
|
+
or substantial portions of the Software.
|
|
267
|
+
|
|
268
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
269
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
270
|
+
PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
271
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
272
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
273
|
+
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
packages/core/src/vendor/uuidv7.ts and its compiled distributions contain code from uuidv7:
|
|
278
|
+
https://github.com/LiosK/uuidv7/blob/f30b7a7faff73afbce0b27a46c638310f96912ba/src/index.ts
|
|
279
|
+
|
|
280
|
+
Copyright 2021-2023 LiosK
|
|
281
|
+
|
|
282
|
+
This code is licensed under the Apache License, Version 2.0, reproduced above.
|
|
283
|
+
|
|
220
284
|
---
|
|
221
285
|
|
|
222
286
|
Some files in this codebase contain code from getsentry/sentry-javascript.
|
package/README.md
CHANGED
|
@@ -213,6 +213,70 @@ A persistent single-process dispatcher can omit `originalTool` after it has prep
|
|
|
213
213
|
Pass `requestMeta` whenever the request supplies `_meta`; this enables recognized client metadata
|
|
214
214
|
without changing the arguments sent to the tool.
|
|
215
215
|
|
|
216
|
+
### Collecting agent feedback (`send_feedback`)
|
|
217
|
+
|
|
218
|
+
`collectFeedback` is **off** by default. Turn it on and the SDK advertises a `send_feedback` virtual
|
|
219
|
+
tool: an honest, general feedback channel from the agent to your team. The tool description makes
|
|
220
|
+
missing capabilities the priority category ("report a missing capability whenever no available tool
|
|
221
|
+
fits your task, even if you can work around it") and also invites reports about a tool that failed
|
|
222
|
+
or confused the agent, and praise. Every call emits one `$mcp_feedback` event — never a
|
|
223
|
+
`$mcp_tool_call` — with `$mcp_feedback_type`, `$mcp_feedback_summary`, and the other
|
|
224
|
+
`$mcp_feedback_*` properties; the summary and details double as `$mcp_intent`. The agent receives an
|
|
225
|
+
acknowledgement that says exactly what happened: the report was recorded, no tools were added.
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
instrument(server, posthog, {
|
|
229
|
+
collectFeedback: {
|
|
230
|
+
// All fields optional; `collectFeedback: true` uses the defaults.
|
|
231
|
+
toolName: 'send_feedback',
|
|
232
|
+
extraProperties: {
|
|
233
|
+
product_area: { type: 'string', description: 'The product or feature the feedback is about.' },
|
|
234
|
+
},
|
|
235
|
+
extraRequired: ['product_area'],
|
|
236
|
+
onFeedback: async (report) => {
|
|
237
|
+
await myFeedbackBackend.record(report) // report.extras.product_area, report.raw, ...
|
|
238
|
+
return 'Thanks - your feedback reached the team.' // replaces the default acknowledgement
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
})
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Host-declared `extraProperties` are merged into the advertised schema and captured as
|
|
245
|
+
`$mcp_feedback_<key>` (sanitized and bounded like every captured value). Arguments the agent invents
|
|
246
|
+
beyond the schema are never captured — they reach `onFeedback` via `report.raw` only. A key that
|
|
247
|
+
collides with a core field fails at configuration time. Free-text fields go through the same PII
|
|
248
|
+
redaction as `$mcp_intent`.
|
|
249
|
+
|
|
250
|
+
`onFeedback`'s returned string replaces the acknowledgement and is captured as `$mcp_response`
|
|
251
|
+
through the generic sanitize pipeline only — it does not get the structured-PII redaction applied to
|
|
252
|
+
`$mcp_feedback_summary`/`details`, so don't echo the agent's raw report text back in it.
|
|
253
|
+
|
|
254
|
+
On the custom-dispatcher path, configure the tool on the `PostHogMCP` constructor and route reports
|
|
255
|
+
yourself (`onFeedback` does not apply there):
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const posthog = new PostHogMCP(process.env.POSTHOG_PROJECT_TOKEN, {
|
|
259
|
+
collectFeedback: { toolName: 'send_feedback' },
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// tools/list handler
|
|
263
|
+
return { tools: posthog.prepareToolList(myTools, { collectFeedback: true }) }
|
|
264
|
+
|
|
265
|
+
// tools/call dispatcher
|
|
266
|
+
const prepared = posthog.prepareToolCall(name, rawArgs)
|
|
267
|
+
if (prepared.isFeedback) {
|
|
268
|
+
posthog.captureFeedback({ report: prepared.feedbackReport!, ...identity })
|
|
269
|
+
await myFeedbackBackend.record(prepared.feedbackReport!)
|
|
270
|
+
return sendFeedbackResult() // or a custom text reply
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
`send_feedback` covers what `reportMissing` covers — a capability gap is
|
|
275
|
+
`feedback_type: "missing_capability"` — so new integrations should enable only `collectFeedback`.
|
|
276
|
+
`reportMissing` and its `$mcp_missing_capability` event stay unchanged for existing users; enabling
|
|
277
|
+
both advertises both tools. Like `get_more_tools`, a real tool that already uses the configured name
|
|
278
|
+
wins: the SDK warns, skips injection, and delegates calls to the real handler.
|
|
279
|
+
|
|
216
280
|
### If you switched to `instrument(server.server)`
|
|
217
281
|
|
|
218
282
|
Before v2 support landed, the compatibility gate rejected high-level v2 servers, and the usual
|
|
@@ -7,6 +7,7 @@ export declare const POSTHOG_MCP_LIB_NAME = "posthog-node-mcp";
|
|
|
7
7
|
export declare const PostHogMCPAnalyticsEvent: {
|
|
8
8
|
readonly Custom: "$mcp_custom";
|
|
9
9
|
readonly Exception: "$exception";
|
|
10
|
+
readonly Feedback: "$mcp_feedback";
|
|
10
11
|
readonly Identify: "$identify";
|
|
11
12
|
readonly Initialize: "$mcp_initialize";
|
|
12
13
|
readonly MissingCapability: "$mcp_missing_capability";
|
|
@@ -26,6 +27,14 @@ export declare const PostHogMCPAnalyticsProperty: {
|
|
|
26
27
|
readonly DurationMs: "$mcp_duration_ms";
|
|
27
28
|
readonly ErrorMessage: "$mcp_error_message";
|
|
28
29
|
readonly ErrorType: "$mcp_error_type";
|
|
30
|
+
readonly FeedbackDetails: "$mcp_feedback_details";
|
|
31
|
+
readonly FeedbackFrictionPoints: "$mcp_feedback_friction_points";
|
|
32
|
+
readonly FeedbackSentiment: "$mcp_feedback_sentiment";
|
|
33
|
+
readonly FeedbackSuggestedImprovement: "$mcp_feedback_suggested_improvement";
|
|
34
|
+
readonly FeedbackSummary: "$mcp_feedback_summary";
|
|
35
|
+
readonly FeedbackTaskCompleted: "$mcp_feedback_task_completed";
|
|
36
|
+
readonly FeedbackTool: "$mcp_feedback_tool";
|
|
37
|
+
readonly FeedbackType: "$mcp_feedback_type";
|
|
29
38
|
readonly IsError: "$mcp_is_error";
|
|
30
39
|
readonly Intent: "$mcp_intent";
|
|
31
40
|
readonly IntentSource: "$mcp_intent_source";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/extensions/constants.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C,eAAO,MAAM,qCAAqC,onBAA4mB,CAAA;AAE9pB,eAAO,MAAM,mCAAmC,gRAAqQ,CAAA;AAErT,eAAO,MAAM,mCAAmC,4LACsI,CAAA;AAEtL,eAAO,MAAM,4BAA4B,0BAA0B,CAAA;AAMnE,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AAItD,eAAO,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/extensions/constants.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,6BAA6B,KAAK,CAAA;AAE/C,eAAO,MAAM,qCAAqC,onBAA4mB,CAAA;AAE9pB,eAAO,MAAM,mCAAmC,gRAAqQ,CAAA;AAErT,eAAO,MAAM,mCAAmC,4LACsI,CAAA;AAEtL,eAAO,MAAM,4BAA4B,0BAA0B,CAAA;AAMnE,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AAItD,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;CAa3B,CAAA;AAEV,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAA;AAE/G,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkC9B,CAAA;AAEV,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,OAAO,2BAA2B,CAAC,CAAA"}
|
|
@@ -36,6 +36,7 @@ const POSTHOG_MCP_LIB_NAME = 'posthog-node-mcp';
|
|
|
36
36
|
const PostHogMCPAnalyticsEvent = {
|
|
37
37
|
Custom: '$mcp_custom',
|
|
38
38
|
Exception: '$exception',
|
|
39
|
+
Feedback: '$mcp_feedback',
|
|
39
40
|
Identify: '$identify',
|
|
40
41
|
Initialize: '$mcp_initialize',
|
|
41
42
|
MissingCapability: '$mcp_missing_capability',
|
|
@@ -54,6 +55,14 @@ const PostHogMCPAnalyticsProperty = {
|
|
|
54
55
|
DurationMs: '$mcp_duration_ms',
|
|
55
56
|
ErrorMessage: '$mcp_error_message',
|
|
56
57
|
ErrorType: '$mcp_error_type',
|
|
58
|
+
FeedbackDetails: '$mcp_feedback_details',
|
|
59
|
+
FeedbackFrictionPoints: '$mcp_feedback_friction_points',
|
|
60
|
+
FeedbackSentiment: '$mcp_feedback_sentiment',
|
|
61
|
+
FeedbackSuggestedImprovement: '$mcp_feedback_suggested_improvement',
|
|
62
|
+
FeedbackSummary: '$mcp_feedback_summary',
|
|
63
|
+
FeedbackTaskCompleted: '$mcp_feedback_task_completed',
|
|
64
|
+
FeedbackTool: '$mcp_feedback_tool',
|
|
65
|
+
FeedbackType: '$mcp_feedback_type',
|
|
57
66
|
IsError: '$mcp_is_error',
|
|
58
67
|
Intent: '$mcp_intent',
|
|
59
68
|
IntentSource: '$mcp_intent_source',
|
|
@@ -7,6 +7,7 @@ const POSTHOG_MCP_LIB_NAME = 'posthog-node-mcp';
|
|
|
7
7
|
const PostHogMCPAnalyticsEvent = {
|
|
8
8
|
Custom: '$mcp_custom',
|
|
9
9
|
Exception: '$exception',
|
|
10
|
+
Feedback: '$mcp_feedback',
|
|
10
11
|
Identify: '$identify',
|
|
11
12
|
Initialize: '$mcp_initialize',
|
|
12
13
|
MissingCapability: '$mcp_missing_capability',
|
|
@@ -25,6 +26,14 @@ const PostHogMCPAnalyticsProperty = {
|
|
|
25
26
|
DurationMs: '$mcp_duration_ms',
|
|
26
27
|
ErrorMessage: '$mcp_error_message',
|
|
27
28
|
ErrorType: '$mcp_error_type',
|
|
29
|
+
FeedbackDetails: '$mcp_feedback_details',
|
|
30
|
+
FeedbackFrictionPoints: '$mcp_feedback_friction_points',
|
|
31
|
+
FeedbackSentiment: '$mcp_feedback_sentiment',
|
|
32
|
+
FeedbackSuggestedImprovement: '$mcp_feedback_suggested_improvement',
|
|
33
|
+
FeedbackSummary: '$mcp_feedback_summary',
|
|
34
|
+
FeedbackTaskCompleted: '$mcp_feedback_task_completed',
|
|
35
|
+
FeedbackTool: '$mcp_feedback_tool',
|
|
36
|
+
FeedbackType: '$mcp_feedback_type',
|
|
28
37
|
IsError: '$mcp_is_error',
|
|
29
38
|
Intent: '$mcp_intent',
|
|
30
39
|
IntentSource: '$mcp_intent_source',
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
export declare const MCPAnalyticsEventType: {
|
|
9
9
|
readonly identify: "posthog:identify";
|
|
10
10
|
readonly custom: "posthog:custom";
|
|
11
|
+
readonly mcpFeedback: "mcp:feedback";
|
|
11
12
|
readonly mcpMissingCapability: "mcp:missing_capability";
|
|
12
13
|
readonly mcpInitialize: "mcp:initialize";
|
|
13
14
|
readonly mcpPromptsGet: "mcp:prompts/get";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../src/extensions/event-types.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../src/extensions/event-types.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;CAYxB,CAAA;AAEV,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAA"}
|
|
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
30
30
|
const MCPAnalyticsEventType = {
|
|
31
31
|
identify: 'posthog:identify',
|
|
32
32
|
custom: 'posthog:custom',
|
|
33
|
+
mcpFeedback: 'mcp:feedback',
|
|
33
34
|
mcpMissingCapability: 'mcp:missing_capability',
|
|
34
35
|
mcpInitialize: 'mcp:initialize',
|
|
35
36
|
mcpPromptsGet: 'mcp:prompts/get',
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { CollectFeedbackOptions, FeedbackReport, CollectFeedbackConfig, CompatibleTextToolResult, CompatibleToolsListLike, JsonRecord } from '../types';
|
|
2
|
+
import { type LoggerFn } from './logger';
|
|
3
|
+
export declare const SEND_FEEDBACK_TOOL_NAME: "send_feedback";
|
|
4
|
+
type FeedbackToolDescriptor = CompatibleToolsListLike['tools'][number];
|
|
5
|
+
/** `collectFeedback` normalized to its object form; `undefined` when the feature is off. */
|
|
6
|
+
export declare function resolveCollectFeedbackOptions(config: CollectFeedbackConfig | undefined): CollectFeedbackOptions | undefined;
|
|
7
|
+
/**
|
|
8
|
+
* The advertised descriptor: the core feedback schema plus the host's declared
|
|
9
|
+
* `extraProperties`. Throws on a config error (a reserved extra key, or an
|
|
10
|
+
* `extraRequired` entry that was never declared) so a bad setup fails at
|
|
11
|
+
* configuration time instead of silently corrupting the advertised schema.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getFeedbackToolDescriptor(options?: CollectFeedbackOptions): FeedbackToolDescriptor;
|
|
14
|
+
/**
|
|
15
|
+
* Parses the raw `send_feedback` arguments into a typed report. Never throws:
|
|
16
|
+
* an invalid `feedback_type` falls back to `other`, missing fields stay
|
|
17
|
+
* undefined, and only **declared** extras whose values match their declared
|
|
18
|
+
* `type`/`enum` are lifted into `extras` — mismatches and anything the agent
|
|
19
|
+
* invented reach the handler via `raw` only and are never captured.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseFeedbackReport(args: Record<string, unknown> | undefined, options?: CollectFeedbackOptions): FeedbackReport;
|
|
22
|
+
/** The report's free text, used as the event's `$mcp_intent`. */
|
|
23
|
+
export declare function buildFeedbackIntent(report: FeedbackReport): string;
|
|
24
|
+
/** The `$mcp_feedback_*` event properties for one report, declared extras included. */
|
|
25
|
+
export declare function buildFeedbackEventProperties(report: FeedbackReport): JsonRecord;
|
|
26
|
+
/**
|
|
27
|
+
* The default acknowledgement returned to the agent after it calls
|
|
28
|
+
* `send_feedback`. Reply with this from your dispatcher (custom dispatcher
|
|
29
|
+
* path); the `instrument()` path returns it automatically, or the string your
|
|
30
|
+
* `onFeedback` handler returned instead.
|
|
31
|
+
*/
|
|
32
|
+
export declare function sendFeedbackResult(): CompatibleTextToolResult;
|
|
33
|
+
/**
|
|
34
|
+
* Runs the host's `onFeedback` handler (when configured) and builds the reply.
|
|
35
|
+
* A returned non-blank string replaces the default acknowledgement; a thrown
|
|
36
|
+
* handler is logged and falls back to it — feedback capture must never break
|
|
37
|
+
* the agent's turn.
|
|
38
|
+
*/
|
|
39
|
+
export declare function handleFeedback(report: FeedbackReport, options?: CollectFeedbackOptions, logger?: LoggerFn): Promise<CompatibleTextToolResult>;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/extensions/feedback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EAEtB,cAAc,EAGd,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,EACX,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAA;AAG7C,eAAO,MAAM,uBAAuB,EAAG,eAAwB,CAAA;AAsF/D,KAAK,sBAAsB,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtE,4FAA4F;AAC5F,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,qBAAqB,GAAG,SAAS,GACxC,sBAAsB,GAAG,SAAS,CAKpC;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,sBAA2B,GAAG,sBAAsB,CA6CtG;AA4BD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,OAAO,GAAE,sBAA2B,GACnC,cAAc,CAoBhB;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAElE;AAuCD,uFAAuF;AACvF,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAqC/E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,wBAAwB,CAS7D;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,OAAO,GAAE,sBAA2B,EACpC,MAAM,GAAE,QAAc,GACrB,OAAO,CAAC,wBAAwB,CAAC,CAenC"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
SEND_FEEDBACK_TOOL_NAME: ()=>SEND_FEEDBACK_TOOL_NAME,
|
|
32
|
+
buildFeedbackEventProperties: ()=>buildFeedbackEventProperties,
|
|
33
|
+
buildFeedbackIntent: ()=>buildFeedbackIntent,
|
|
34
|
+
getFeedbackToolDescriptor: ()=>getFeedbackToolDescriptor,
|
|
35
|
+
handleFeedback: ()=>handleFeedback,
|
|
36
|
+
parseFeedbackReport: ()=>parseFeedbackReport,
|
|
37
|
+
resolveCollectFeedbackOptions: ()=>resolveCollectFeedbackOptions,
|
|
38
|
+
sendFeedbackResult: ()=>sendFeedbackResult
|
|
39
|
+
});
|
|
40
|
+
const external_constants_js_namespaceObject = require("./constants.js");
|
|
41
|
+
const external_logger_js_namespaceObject = require("./logger.js");
|
|
42
|
+
const external_mcp_payloads_js_namespaceObject = require("./mcp-payloads.js");
|
|
43
|
+
const SEND_FEEDBACK_TOOL_NAME = 'send_feedback';
|
|
44
|
+
const FEEDBACK_TYPES = [
|
|
45
|
+
'missing_capability',
|
|
46
|
+
'issue',
|
|
47
|
+
'praise',
|
|
48
|
+
'other'
|
|
49
|
+
];
|
|
50
|
+
const SENTIMENTS = [
|
|
51
|
+
'positive',
|
|
52
|
+
'neutral',
|
|
53
|
+
'negative',
|
|
54
|
+
'mixed'
|
|
55
|
+
];
|
|
56
|
+
const MAX_FEEDBACK_TEXT_LENGTH = 2048;
|
|
57
|
+
const MAX_FEEDBACK_TOOL_NAME_LENGTH = 256;
|
|
58
|
+
const TRUNCATION_SUFFIX = '...';
|
|
59
|
+
const DEFAULT_FEEDBACK_DESCRIPTION = 'Send feedback about this server to its developers. Most important: report a missing capability whenever no available tool fits your task, even if you can work around it (feedback_type "missing_capability"). Also welcome: a tool that failed or confused you, an unhelpful error, or something that worked well. This records the feedback; it does not add or change tools. Do not include user PII or sensitive content.';
|
|
60
|
+
const CORE_FEEDBACK_SCHEMA_PROPERTIES = {
|
|
61
|
+
feedback_type: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
enum: [
|
|
64
|
+
...FEEDBACK_TYPES
|
|
65
|
+
],
|
|
66
|
+
description: "What kind of feedback this is. Use 'missing_capability' when the tool you needed does not exist in the tool list - nothing failed, the capability is absent (this is the most valuable report; send it even if you found a workaround). Use 'issue' when an existing tool behaved badly: it failed, returned a confusing error, or its description or schema misled you. Use 'praise' when something worked notably well. Use 'other' for anything else."
|
|
67
|
+
},
|
|
68
|
+
summary: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: "One self-contained sentence. For 'missing_capability': the capability you needed, e.g. 'No tool to delete multiple cohorts in one call.' For 'issue': the tool and the problem, e.g. 'query-trends rejects relative date ranges with an unclear error.'"
|
|
71
|
+
},
|
|
72
|
+
details: {
|
|
73
|
+
type: 'string',
|
|
74
|
+
description: "Optional longer context: what you tried, exact parameter values, the error text you saw, and any workaround you used. Omit when the summary says it all."
|
|
75
|
+
},
|
|
76
|
+
friction_points: {
|
|
77
|
+
type: 'string',
|
|
78
|
+
description: "Optional: the specific moments that slowed you down, as short bullet-like sentences, quoting exact tool names, parameters, or error text."
|
|
79
|
+
},
|
|
80
|
+
suggested_improvement: {
|
|
81
|
+
type: 'string',
|
|
82
|
+
description: "Optional: the concrete change that would have helped, e.g. the tool to add, the description to reword, or the error message to improve."
|
|
83
|
+
},
|
|
84
|
+
tool_name: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
description: "Optional: the existing tool this feedback is about (for 'issue' or 'praise'). Leave empty for 'missing_capability' - the point is that no tool fits."
|
|
87
|
+
},
|
|
88
|
+
sentiment: {
|
|
89
|
+
type: 'string',
|
|
90
|
+
enum: [
|
|
91
|
+
...SENTIMENTS
|
|
92
|
+
],
|
|
93
|
+
description: 'Optional: how the experience felt overall.'
|
|
94
|
+
},
|
|
95
|
+
task_completed: {
|
|
96
|
+
type: 'boolean',
|
|
97
|
+
description: "Optional: whether you still completed the user's task despite the problem."
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const RESERVED_EXTRA_PROPERTY_KEYS = new Set([
|
|
101
|
+
...Object.keys(CORE_FEEDBACK_SCHEMA_PROPERTIES),
|
|
102
|
+
'type',
|
|
103
|
+
'tool',
|
|
104
|
+
'context',
|
|
105
|
+
'conversation_id',
|
|
106
|
+
'llm_model'
|
|
107
|
+
]);
|
|
108
|
+
function resolveCollectFeedbackOptions(config) {
|
|
109
|
+
if (!config) return;
|
|
110
|
+
return true === config ? {} : config;
|
|
111
|
+
}
|
|
112
|
+
function getFeedbackToolDescriptor(options = {}) {
|
|
113
|
+
const extraProperties = options.extraProperties ?? {};
|
|
114
|
+
const extraRequired = options.extraRequired ?? [];
|
|
115
|
+
for (const key of Object.keys(extraProperties))if (RESERVED_EXTRA_PROPERTY_KEYS.has(key)) throw new Error(`collectFeedback.extraProperties key "${key}" collides with a core or SDK-reserved send_feedback field. Rename it.`);
|
|
116
|
+
for (const key of extraRequired)if (!Object.prototype.hasOwnProperty.call(extraProperties, key)) throw new Error(`collectFeedback.extraRequired key "${key}" is not declared in extraProperties.`);
|
|
117
|
+
const copiedExtras = Object.keys(extraProperties).length > 0 ? JSON.parse(JSON.stringify(extraProperties)) : void 0;
|
|
118
|
+
return {
|
|
119
|
+
name: options.toolName ?? SEND_FEEDBACK_TOOL_NAME,
|
|
120
|
+
description: options.description ?? DEFAULT_FEEDBACK_DESCRIPTION,
|
|
121
|
+
inputSchema: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
...JSON.parse(JSON.stringify(CORE_FEEDBACK_SCHEMA_PROPERTIES)),
|
|
125
|
+
...copiedExtras
|
|
126
|
+
},
|
|
127
|
+
required: [
|
|
128
|
+
'feedback_type',
|
|
129
|
+
'summary',
|
|
130
|
+
...extraRequired
|
|
131
|
+
]
|
|
132
|
+
},
|
|
133
|
+
annotations: {
|
|
134
|
+
title: 'Send feedback',
|
|
135
|
+
readOnlyHint: true,
|
|
136
|
+
openWorldHint: true,
|
|
137
|
+
idempotentHint: true,
|
|
138
|
+
destructiveHint: false
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function readString(value) {
|
|
143
|
+
return 'string' == typeof value && value.trim() ? value : void 0;
|
|
144
|
+
}
|
|
145
|
+
function parseFeedbackType(value) {
|
|
146
|
+
return FEEDBACK_TYPES.includes(value) ? value : 'other';
|
|
147
|
+
}
|
|
148
|
+
function parseSentiment(value) {
|
|
149
|
+
return SENTIMENTS.includes(value) ? value : void 0;
|
|
150
|
+
}
|
|
151
|
+
function matchesExtraSchema(value, schema) {
|
|
152
|
+
const type = Array.isArray(value) ? 'array' : null === value ? 'null' : typeof value;
|
|
153
|
+
if (schema.type !== type && !('integer' === schema.type && 'number' == typeof value)) return false;
|
|
154
|
+
return !Array.isArray(schema.enum) || schema.enum.includes(value);
|
|
155
|
+
}
|
|
156
|
+
function parseFeedbackReport(args, options = {}) {
|
|
157
|
+
const raw = args ?? {};
|
|
158
|
+
const extras = {};
|
|
159
|
+
for (const [key, schema] of Object.entries(options.extraProperties ?? {}))if (void 0 !== raw[key] && matchesExtraSchema(raw[key], schema)) extras[key] = raw[key];
|
|
160
|
+
return {
|
|
161
|
+
feedbackType: parseFeedbackType(raw.feedback_type),
|
|
162
|
+
summary: readString(raw.summary) ?? '',
|
|
163
|
+
sentiment: parseSentiment(raw.sentiment),
|
|
164
|
+
frictionPoints: readString(raw.friction_points),
|
|
165
|
+
suggestedImprovement: readString(raw.suggested_improvement),
|
|
166
|
+
details: readString(raw.details),
|
|
167
|
+
toolName: readString(raw.tool_name),
|
|
168
|
+
taskCompleted: 'boolean' == typeof raw.task_completed ? raw.task_completed : void 0,
|
|
169
|
+
extras,
|
|
170
|
+
raw
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function buildFeedbackIntent(report) {
|
|
174
|
+
return [
|
|
175
|
+
report.summary,
|
|
176
|
+
report.details
|
|
177
|
+
].filter(Boolean).join('\n\n');
|
|
178
|
+
}
|
|
179
|
+
function truncateFeedbackText(value, maxLength) {
|
|
180
|
+
return value.length > maxLength ? value.slice(0, maxLength) + TRUNCATION_SUFFIX : value;
|
|
181
|
+
}
|
|
182
|
+
function captureFreeText(value) {
|
|
183
|
+
return truncateFeedbackText((0, external_mcp_payloads_js_namespaceObject.sanitizeFreeText)(value), MAX_FEEDBACK_TEXT_LENGTH);
|
|
184
|
+
}
|
|
185
|
+
function captureExtraValue(value) {
|
|
186
|
+
const sanitized = (0, external_mcp_payloads_js_namespaceObject.sanitizeFreeTextValue)(value);
|
|
187
|
+
if ('string' == typeof sanitized) return truncateFeedbackText(sanitized, MAX_FEEDBACK_TEXT_LENGTH);
|
|
188
|
+
if (null == sanitized || 'number' == typeof sanitized || 'boolean' == typeof sanitized) return sanitized;
|
|
189
|
+
try {
|
|
190
|
+
return truncateFeedbackText(JSON.stringify(sanitized), MAX_FEEDBACK_TEXT_LENGTH);
|
|
191
|
+
} catch {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function buildFeedbackEventProperties(report) {
|
|
196
|
+
const properties = {
|
|
197
|
+
[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackType]: report.feedbackType
|
|
198
|
+
};
|
|
199
|
+
if (report.summary) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackSummary] = captureFreeText(report.summary);
|
|
200
|
+
if (report.sentiment) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackSentiment] = report.sentiment;
|
|
201
|
+
if (report.frictionPoints) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackFrictionPoints] = captureFreeText(report.frictionPoints);
|
|
202
|
+
if (report.suggestedImprovement) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackSuggestedImprovement] = captureFreeText(report.suggestedImprovement);
|
|
203
|
+
if (report.details) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackDetails] = captureFreeText(report.details);
|
|
204
|
+
if (report.toolName) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackTool] = truncateFeedbackText((0, external_mcp_payloads_js_namespaceObject.sanitizeFreeText)(report.toolName), MAX_FEEDBACK_TOOL_NAME_LENGTH);
|
|
205
|
+
if (void 0 !== report.taskCompleted) properties[external_constants_js_namespaceObject.PostHogMCPAnalyticsProperty.FeedbackTaskCompleted] = report.taskCompleted;
|
|
206
|
+
for (const [key, value] of Object.entries(report.extras)){
|
|
207
|
+
const captured = captureExtraValue(value);
|
|
208
|
+
if (void 0 !== captured) properties[`$mcp_feedback_${key}`] = captured;
|
|
209
|
+
}
|
|
210
|
+
return properties;
|
|
211
|
+
}
|
|
212
|
+
function sendFeedbackResult() {
|
|
213
|
+
return {
|
|
214
|
+
content: [
|
|
215
|
+
{
|
|
216
|
+
type: 'text',
|
|
217
|
+
text: "Your feedback was recorded for the server's developers. No additional tools are available - continue with the tools already listed."
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
async function handleFeedback(report, options = {}, logger = external_logger_js_namespaceObject.log) {
|
|
223
|
+
logger(`Agent feedback reported (${report.feedbackType})`);
|
|
224
|
+
if (options.onFeedback) try {
|
|
225
|
+
const reply = await options.onFeedback(report);
|
|
226
|
+
if ('string' == typeof reply && reply.trim()) return {
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: 'text',
|
|
230
|
+
text: reply
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
};
|
|
234
|
+
} catch (error) {
|
|
235
|
+
logger(`Warning: onFeedback handler threw; returning the default acknowledgement - ${error}`);
|
|
236
|
+
}
|
|
237
|
+
return sendFeedbackResult();
|
|
238
|
+
}
|
|
239
|
+
exports.SEND_FEEDBACK_TOOL_NAME = __webpack_exports__.SEND_FEEDBACK_TOOL_NAME;
|
|
240
|
+
exports.buildFeedbackEventProperties = __webpack_exports__.buildFeedbackEventProperties;
|
|
241
|
+
exports.buildFeedbackIntent = __webpack_exports__.buildFeedbackIntent;
|
|
242
|
+
exports.getFeedbackToolDescriptor = __webpack_exports__.getFeedbackToolDescriptor;
|
|
243
|
+
exports.handleFeedback = __webpack_exports__.handleFeedback;
|
|
244
|
+
exports.parseFeedbackReport = __webpack_exports__.parseFeedbackReport;
|
|
245
|
+
exports.resolveCollectFeedbackOptions = __webpack_exports__.resolveCollectFeedbackOptions;
|
|
246
|
+
exports.sendFeedbackResult = __webpack_exports__.sendFeedbackResult;
|
|
247
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
248
|
+
"SEND_FEEDBACK_TOOL_NAME",
|
|
249
|
+
"buildFeedbackEventProperties",
|
|
250
|
+
"buildFeedbackIntent",
|
|
251
|
+
"getFeedbackToolDescriptor",
|
|
252
|
+
"handleFeedback",
|
|
253
|
+
"parseFeedbackReport",
|
|
254
|
+
"resolveCollectFeedbackOptions",
|
|
255
|
+
"sendFeedbackResult"
|
|
256
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
257
|
+
Object.defineProperty(exports, '__esModule', {
|
|
258
|
+
value: true
|
|
259
|
+
});
|