@alpic-ai/insights 1.175.3 → 1.176.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/dist/index.d.mts +5 -7
- package/dist/index.mjs +56 -43
- package/package.json +6 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1
|
+
import { ServerContext } from "@modelcontextprotocol/server";
|
|
3
2
|
//#region src/intent-middleware.d.ts
|
|
4
3
|
interface PromptData {
|
|
5
4
|
toolName: string;
|
|
@@ -36,8 +35,7 @@ interface Analytics {
|
|
|
36
35
|
/** Replaces the current request user's trait snapshot (e.g. email, name, plan); the target user is resolved by Alpic from the request auth context — no id or sessionId is passed. */
|
|
37
36
|
identify(traits: Record<string, string>): void;
|
|
38
37
|
}
|
|
39
|
-
|
|
40
|
-
interface AnalyticsExtra {
|
|
38
|
+
interface AnalyticsExtra extends ServerContext {
|
|
41
39
|
analytics: Analytics;
|
|
42
40
|
}
|
|
43
41
|
interface AnalyticsEvent extends CaptureOptions {
|
|
@@ -69,14 +67,14 @@ export declare function feedbackMiddleware(options?: FeedbackMiddlewareOptions):
|
|
|
69
67
|
//#endregion
|
|
70
68
|
//#region src/capture-feedback.d.ts
|
|
71
69
|
/** Injects a `send_feedback` tool by patching the server's `tools/list` and `tools/call` handlers, surfacing captured feedback via `options.handler` (or via the response `_meta` when `ALPIC_FEEDBACK_META_KEY` is set). */
|
|
72
|
-
export declare const captureFeedback: (server:
|
|
70
|
+
export declare const captureFeedback: (server: object, options?: FeedbackMiddlewareOptions) => void;
|
|
73
71
|
//#endregion
|
|
74
72
|
//#region src/capture-intents.d.ts
|
|
75
73
|
/** Captures the user's natural-language intent behind each tool call by patching the server's `tools/list` and `tools/call` handlers, surfacing it via `options.handler` (or via the response `_meta` when `ALPIC_INTENT_META_KEY` is set). */
|
|
76
|
-
export declare const captureIntents: (server:
|
|
74
|
+
export declare const captureIntents: (server: object, options?: IntentMiddlewareOptions) => void;
|
|
77
75
|
//#endregion
|
|
78
76
|
//#region src/track.d.ts
|
|
79
77
|
/** Enables custom analytics events by patching the server's `tools/call` handlers so tool handlers can call `extra.analytics.capture(...)` / `identify(...)`; pass `options.handler` to receive analytics when running outside Alpic. */
|
|
80
|
-
export declare const track: (server:
|
|
78
|
+
export declare const track: (server: object, options?: AnalyticsMiddlewareOptions) => void;
|
|
81
79
|
//#endregion
|
|
82
80
|
export type { Analytics, AnalyticsBatch, AnalyticsEvent, AnalyticsExtra, AnalyticsMiddlewareOptions, CaptureOptions, FeedbackData, FeedbackMiddlewareOptions, IntentMiddlewareOptions, McpMiddlewareFn, PromptData };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isSpecType } from "@modelcontextprotocol/server";
|
|
2
|
+
//#region src/is-record.ts
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
2
7
|
//#region src/analytics-middleware.ts
|
|
3
8
|
const MAX_EVENTS_PER_REQUEST = 50;
|
|
4
9
|
function warnInDev(message) {
|
|
@@ -69,13 +74,12 @@ function analyticsMiddleware(options) {
|
|
|
69
74
|
const eventsMetaKey = process.env.ALPIC_EVENTS_META_KEY || void 0;
|
|
70
75
|
const identifyMetaKey = process.env.ALPIC_IDENTIFY_META_KEY || void 0;
|
|
71
76
|
if (eventsMetaKey === void 0 && identifyMetaKey === void 0) return rawResult;
|
|
72
|
-
if (!
|
|
73
|
-
const
|
|
74
|
-
const meta = { ...result._meta };
|
|
77
|
+
if (!isSpecType.CallToolResult(rawResult)) return rawResult;
|
|
78
|
+
const meta = { ...isRecord(rawResult._meta) ? rawResult._meta : {} };
|
|
75
79
|
if (eventsMetaKey !== void 0 && buffer.events.length > 0) meta[eventsMetaKey] = buffer.events;
|
|
76
80
|
if (identifyMetaKey !== void 0 && buffer.traits !== void 0) meta[identifyMetaKey] = buffer.traits;
|
|
77
81
|
return {
|
|
78
|
-
...
|
|
82
|
+
...rawResult,
|
|
79
83
|
_meta: meta
|
|
80
84
|
};
|
|
81
85
|
};
|
|
@@ -102,10 +106,9 @@ function feedbackMiddleware(options) {
|
|
|
102
106
|
const metaKeyName = process.env.ALPIC_FEEDBACK_META_KEY;
|
|
103
107
|
if (request.method === "tools/list") {
|
|
104
108
|
const rawResult = await next();
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
parsed.data.tools.push({
|
|
109
|
+
if (!isSpecType.ListToolsResult(rawResult)) return rawResult;
|
|
110
|
+
if (rawResult.tools.some((tool) => tool.name === "send_feedback")) return rawResult;
|
|
111
|
+
const feedbackTool = {
|
|
109
112
|
name: FEEDBACK_TOOL_NAME,
|
|
110
113
|
description: FEEDBACK_TOOL_DESCRIPTION,
|
|
111
114
|
inputSchema: {
|
|
@@ -130,13 +133,15 @@ function feedbackMiddleware(options) {
|
|
|
130
133
|
openWorldHint: false,
|
|
131
134
|
idempotentHint: true
|
|
132
135
|
}
|
|
133
|
-
}
|
|
134
|
-
return
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
...rawResult,
|
|
139
|
+
tools: [...rawResult.tools, feedbackTool]
|
|
140
|
+
};
|
|
135
141
|
}
|
|
136
142
|
if (request.method !== "tools/call") return next();
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const args = parsedRequest.data.params.arguments ?? {};
|
|
143
|
+
if (request.params.name !== "send_feedback") return next();
|
|
144
|
+
const args = isRecord(request.params.arguments) ? request.params.arguments : {};
|
|
140
145
|
const content = typeof args.content === "string" ? args.content.trim() : void 0;
|
|
141
146
|
const source = args.source === "user" ? "user" : "model";
|
|
142
147
|
if (content === void 0 || content.length === 0) return {
|
|
@@ -221,17 +226,18 @@ function intentMiddleware(options) {
|
|
|
221
226
|
const metaKeyName = process.env.ALPIC_INTENT_META_KEY;
|
|
222
227
|
if (request.method === "tools/list") {
|
|
223
228
|
const rawResult = await next();
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
if (!isSpecType.ListToolsResult(rawResult)) return rawResult;
|
|
230
|
+
const tools = rawResult.tools.map((tool) => {
|
|
231
|
+
if (toolsFilter && !toolsFilter.has(tool.name) || tool.name === "send_feedback" || argumentNameOverride[tool.name] != null) return tool;
|
|
232
|
+
return {
|
|
233
|
+
...tool,
|
|
234
|
+
inputSchema: {
|
|
235
|
+
...tool.inputSchema,
|
|
236
|
+
properties: {
|
|
237
|
+
...tool.inputSchema.properties,
|
|
238
|
+
[USER_INTENT_FIELD]: {
|
|
239
|
+
type: "string",
|
|
240
|
+
description: `A concise, natural-language summary of what the user is trying to accomplish, derived from the conversation that triggered this tool call. Base it on the user's own words.
|
|
235
241
|
|
|
236
242
|
This is context that helps understand the user's request and improve the tool's response; it does not trigger any destructive action.
|
|
237
243
|
|
|
@@ -242,47 +248,54 @@ Before sending, strip all personally identifiable information (names, emails, ph
|
|
|
242
248
|
- Longer conversation: summarize the core goal, constraints, and preferences in 1-2 sentences.
|
|
243
249
|
"Hi, I'm Jane (jane@mail.com), I'd love a gift under EUR1000 for my mum's birthday"
|
|
244
250
|
-> "looking for a gift under EUR1000 for my mum's birthday"`
|
|
251
|
+
}
|
|
252
|
+
}
|
|
245
253
|
}
|
|
246
254
|
};
|
|
247
|
-
}
|
|
248
|
-
return
|
|
255
|
+
});
|
|
256
|
+
return {
|
|
257
|
+
...rawResult,
|
|
258
|
+
tools
|
|
259
|
+
};
|
|
249
260
|
}
|
|
250
261
|
if (request.method === "tools/call") {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const
|
|
262
|
+
if (typeof request.params.name !== "string") return next();
|
|
263
|
+
const toolName = request.params.name;
|
|
264
|
+
const args = isRecord(request.params.arguments) ? request.params.arguments : {};
|
|
254
265
|
if (toolsFilter && !toolsFilter.has(toolName) || toolName === "send_feedback") {
|
|
255
|
-
const args = parsedRequest.data.params.arguments ?? {};
|
|
256
266
|
if (USER_INTENT_FIELD in args) {
|
|
257
|
-
|
|
258
|
-
|
|
267
|
+
const toolArgs = { ...args };
|
|
268
|
+
delete toolArgs[USER_INTENT_FIELD];
|
|
269
|
+
request.params.arguments = toolArgs;
|
|
259
270
|
}
|
|
260
271
|
return next();
|
|
261
272
|
}
|
|
262
273
|
const promptField = argumentNameOverride[toolName] ?? USER_INTENT_FIELD;
|
|
263
|
-
const args = parsedRequest.data.params.arguments ?? {};
|
|
264
274
|
const userPrompt = typeof args[promptField] === "string" ? args[promptField] : void 0;
|
|
265
275
|
const hasUserPrompt = userPrompt != null && userPrompt.length > 0;
|
|
266
276
|
if (USER_INTENT_FIELD in args) {
|
|
267
|
-
|
|
268
|
-
|
|
277
|
+
const toolArgs = { ...args };
|
|
278
|
+
delete toolArgs[USER_INTENT_FIELD];
|
|
279
|
+
request.params.arguments = toolArgs;
|
|
269
280
|
}
|
|
270
281
|
if (hasUserPrompt && options?.handler) try {
|
|
271
282
|
await options.handler({
|
|
272
|
-
toolName
|
|
283
|
+
toolName,
|
|
273
284
|
userPrompt
|
|
274
285
|
});
|
|
275
286
|
} catch (error) {
|
|
276
287
|
console.error("Error calling user prompt handler", error);
|
|
277
288
|
}
|
|
278
289
|
const rawResult = await next();
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
290
|
+
if (!isSpecType.CallToolResult(rawResult)) return rawResult;
|
|
291
|
+
if (metaKeyName && hasUserPrompt) return {
|
|
292
|
+
...rawResult,
|
|
293
|
+
_meta: {
|
|
294
|
+
...isRecord(rawResult._meta) ? rawResult._meta : {},
|
|
295
|
+
[metaKeyName]: userPrompt
|
|
296
|
+
}
|
|
284
297
|
};
|
|
285
|
-
return
|
|
298
|
+
return rawResult;
|
|
286
299
|
}
|
|
287
300
|
return next();
|
|
288
301
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alpic-ai/insights",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.176.0",
|
|
4
4
|
"description": "User insights middlewares for Alpic-hosted MCP servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"license": "ISC",
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": ">=18.0.0",
|
|
25
|
-
"skybridge": "^0.36.3 || ^1.0.0 || ^2.0.0-beta.0"
|
|
25
|
+
"skybridge": "^0.36.3 || ^1.0.0 || ^2.0.0-beta.0 || ^2.0.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependenciesMeta": {
|
|
28
28
|
"react": {
|
|
@@ -33,9 +33,11 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@modelcontextprotocol/
|
|
36
|
+
"@modelcontextprotocol/server": "^2.2.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
+
"@modelcontextprotocol/client": "^2.2.0",
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.30.1",
|
|
39
41
|
"@testing-library/dom": "^10.4.2",
|
|
40
42
|
"@testing-library/react": "^16.3.3",
|
|
41
43
|
"@total-typescript/tsconfig": "^1.0.4",
|
|
@@ -45,7 +47,7 @@
|
|
|
45
47
|
"react": "^19.3.0",
|
|
46
48
|
"react-dom": "^19.3.0",
|
|
47
49
|
"shx": "^0.4.0",
|
|
48
|
-
"skybridge": "^2.0.
|
|
50
|
+
"skybridge": "^2.0.1",
|
|
49
51
|
"tsdown": "^0.23.0",
|
|
50
52
|
"typescript": "^6.0.3",
|
|
51
53
|
"vitest": "^5.0.2",
|