@posthog/mcp 0.17.0 → 0.18.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/README.md CHANGED
@@ -179,7 +179,7 @@ enforces it, so servers keep working; strict-schema clients see the new field. S
179
179
  `conversation_id` argument and returns a handle in eligible tool results. Clients must echo that
180
180
  handle to group later calls; calls without it mint new handles. Set `enableConversationId: false`
181
181
  to retain transport-based session grouping and unchanged response content. Custom `PostHogMCP`
182
- dispatchers enable model capture by default, but continue to supply their own session IDs.
182
+ dispatchers also enable model capture and conversation correlation by default.
183
183
  The reasoning behind these defaults is in [ADR-0013](./docs/adr/0013-analytics-capture-is-on-by-default.md).
184
184
 
185
185
  ### What `$mcp_llm_model` records, and when it stays empty
@@ -213,29 +213,44 @@ As with `context`, what matters is instance lifetime rather than statelessness:
213
213
  server (`sessionIdGenerator: undefined`) that keeps one long-lived server object learns ownership
214
214
  from the first `tools/list` and keeps it.
215
215
 
216
- For a custom dispatcher, `PostHogMCP` enables the same option by default. Its `prepareToolList()` helper
217
- injects the field and records ownership by tool name; `prepareToolCall()` returns `llmModel` and
218
- `llmModelSource` while removing the SDK-owned argument before dispatch. Pass both fields to
219
- `captureToolCall()`. Pass the original tool descriptor on each call so this also works when
220
- `tools/list` and `tools/call` reach different server replicas:
216
+ For a custom dispatcher, `PostHogMCP` enables model capture and conversation correlation by default.
217
+ `prepareToolList()` injects the analytics fields and records ownership by tool name.
218
+ `prepareToolCall()` removes SDK-owned arguments and resolves the conversation and session.
219
+ `prepareToolResult()` returns the result to send and the final values to capture. Pass the original
220
+ tool descriptor on each call so this also works when `tools/list` and `tools/call` reach different
221
+ server replicas:
221
222
 
222
223
  ```ts
223
224
  const posthog = new PostHogMCP(process.env.POSTHOG_PROJECT_TOKEN)
224
225
 
225
226
  const tools = posthog.prepareToolList(serverTools)
226
227
  const originalTool = serverTools.find((tool) => tool.name === toolName)
227
- const { args, llmModel, llmModelSource } = posthog.prepareToolCall(toolName, rawArgs, {
228
+ const preparedCall = posthog.prepareToolCall(toolName, rawArgs, {
228
229
  originalTool,
229
230
  requestMeta: request.params?._meta,
231
+ sessionId: transportSessionId,
232
+ })
233
+ const toolResult = await dispatch(toolName, preparedCall.args)
234
+ const preparedResult = posthog.prepareToolResult(toolResult, preparedCall)
235
+
236
+ posthog.captureToolCall({
237
+ toolName,
238
+ llmModel: preparedCall.llmModel,
239
+ llmModelSource: preparedCall.llmModelSource,
240
+ sessionId: preparedResult.sessionId,
241
+ conversationId: preparedResult.conversationId,
242
+ isError: false,
230
243
  })
231
- const result = await dispatch(toolName, args)
232
244
 
233
- posthog.captureToolCall({ toolName, llmModel, llmModelSource, isError: false })
245
+ return preparedResult.result
234
246
  ```
235
247
 
236
248
  A persistent single-process dispatcher can omit `originalTool` after it has prepared its tool list.
237
249
  Pass `requestMeta` whenever the request supplies `_meta`; this enables recognized client metadata
238
- without changing the arguments sent to the tool.
250
+ without changing the arguments sent to the tool. Pass an existing transport or request session as
251
+ `sessionId`. A valid echoed conversation handle takes precedence. Otherwise, the existing session
252
+ prevents a new handle from being minted. Set `enableConversationId: false` on `PostHogMCP` to keep
253
+ the previous custom-dispatcher behavior.
239
254
 
240
255
  ### Collecting agent feedback (`send_feedback`)
241
256
 
@@ -288,11 +303,17 @@ return { tools: posthog.prepareToolList(myTools, { collectFeedback: true }) }
288
303
 
289
304
  // tools/call dispatcher
290
305
  const originalTool = myTools.find((tool) => tool.name === name)
291
- const prepared = posthog.prepareToolCall(name, rawArgs, { originalTool })
292
- if (prepared.isFeedback) {
293
- posthog.captureFeedback({ report: prepared.feedbackReport!, ...identity })
294
- await myFeedbackBackend.record(prepared.feedbackReport!)
295
- return sendFeedbackResult() // or a custom text reply
306
+ const preparedCall = posthog.prepareToolCall(name, rawArgs, { originalTool })
307
+ if (preparedCall.isFeedback) {
308
+ await myFeedbackBackend.record(preparedCall.feedbackReport!)
309
+ const preparedResult = posthog.prepareToolResult(sendFeedbackResult(), preparedCall)
310
+ posthog.captureFeedback({
311
+ report: preparedCall.feedbackReport!,
312
+ sessionId: preparedResult.sessionId,
313
+ conversationId: preparedResult.conversationId,
314
+ ...identity,
315
+ })
316
+ return preparedResult.result
296
317
  }
297
318
  ```
298
319
 
@@ -5,54 +5,54 @@ export declare const DEFAULT_CONVERSATION_ID_DESCRIPTION = "Echo the conversatio
5
5
  export declare const POSTHOG_MCP_ANALYTICS_SOURCE = "posthog_mcp_analytics";
6
6
  export declare const POSTHOG_MCP_LIB_NAME = "posthog-node-mcp";
7
7
  export declare const PostHogMCPAnalyticsEvent: {
8
- readonly Custom: "$mcp_custom";
9
- readonly Exception: "$exception";
10
- readonly Feedback: "$mcp_feedback";
11
- readonly Identify: "$identify";
12
- readonly Initialize: "$mcp_initialize";
13
- readonly MissingCapability: "$mcp_missing_capability";
14
- readonly PromptGet: "$mcp_prompt_get";
15
- readonly PromptsList: "$mcp_prompts_list";
16
- readonly ResourceRead: "$mcp_resource_read";
17
- readonly ResourcesList: "$mcp_resources_list";
18
- readonly ToolCall: "$mcp_tool_call";
19
- readonly ToolsList: "$mcp_tools_list";
8
+ readonly Custom: '$mcp_custom';
9
+ readonly Exception: '$exception';
10
+ readonly Feedback: '$mcp_feedback';
11
+ readonly Identify: '$identify';
12
+ readonly Initialize: '$mcp_initialize';
13
+ readonly MissingCapability: '$mcp_missing_capability';
14
+ readonly PromptGet: '$mcp_prompt_get';
15
+ readonly PromptsList: '$mcp_prompts_list';
16
+ readonly ResourceRead: '$mcp_resource_read';
17
+ readonly ResourcesList: '$mcp_resources_list';
18
+ readonly ToolCall: '$mcp_tool_call';
19
+ readonly ToolsList: '$mcp_tools_list';
20
20
  };
21
21
  export type PostHogMCPAnalyticsEvent = (typeof PostHogMCPAnalyticsEvent)[keyof typeof PostHogMCPAnalyticsEvent];
22
22
  export declare const PostHogMCPAnalyticsProperty: {
23
- readonly ClientName: "$mcp_client_name";
24
- readonly ClientUserAgent: "$mcp_client_user_agent";
25
- readonly ClientVersion: "$mcp_client_version";
26
- readonly ConversationId: "$mcp_conversation_id";
27
- readonly DurationMs: "$mcp_duration_ms";
28
- readonly ErrorMessage: "$mcp_error_message";
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";
38
- readonly IsError: "$mcp_is_error";
39
- readonly Intent: "$mcp_intent";
40
- readonly IntentSource: "$mcp_intent_source";
41
- readonly ListedToolNames: "$mcp_listed_tool_names";
42
- readonly LlmModel: "$mcp_llm_model";
43
- readonly LlmModelSource: "$mcp_llm_model_source";
44
- readonly Parameters: "$mcp_parameters";
45
- readonly ProtocolVersion: "$mcp_protocol_version";
46
- readonly ResourceName: "$mcp_resource_name";
47
- readonly Response: "$mcp_response";
48
- readonly ServerName: "$mcp_server_name";
49
- readonly ServerVersion: "$mcp_server_version";
50
- readonly SessionId: "$session_id";
51
- readonly Source: "$mcp_source";
52
- readonly ToolCategory: "$mcp_tool_category";
53
- readonly ToolDescription: "$mcp_tool_description";
54
- readonly ToolName: "$mcp_tool_name";
55
- readonly VendorClient: "$mcp_vendor_client";
23
+ readonly ClientName: '$mcp_client_name';
24
+ readonly ClientUserAgent: '$mcp_client_user_agent';
25
+ readonly ClientVersion: '$mcp_client_version';
26
+ readonly ConversationId: '$mcp_conversation_id';
27
+ readonly DurationMs: '$mcp_duration_ms';
28
+ readonly ErrorMessage: '$mcp_error_message';
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';
38
+ readonly IsError: '$mcp_is_error';
39
+ readonly Intent: '$mcp_intent';
40
+ readonly IntentSource: '$mcp_intent_source';
41
+ readonly ListedToolNames: '$mcp_listed_tool_names';
42
+ readonly LlmModel: '$mcp_llm_model';
43
+ readonly LlmModelSource: '$mcp_llm_model_source';
44
+ readonly Parameters: '$mcp_parameters';
45
+ readonly ProtocolVersion: '$mcp_protocol_version';
46
+ readonly ResourceName: '$mcp_resource_name';
47
+ readonly Response: '$mcp_response';
48
+ readonly ServerName: '$mcp_server_name';
49
+ readonly ServerVersion: '$mcp_server_version';
50
+ readonly SessionId: '$session_id';
51
+ readonly Source: '$mcp_source';
52
+ readonly ToolCategory: '$mcp_tool_category';
53
+ readonly ToolDescription: '$mcp_tool_description';
54
+ readonly ToolName: '$mcp_tool_name';
55
+ readonly VendorClient: '$mcp_vendor_client';
56
56
  };
57
57
  export type PostHogMCPAnalyticsProperty = (typeof PostHogMCPAnalyticsProperty)[keyof typeof PostHogMCPAnalyticsProperty];
58
58
  //# sourceMappingURL=constants.d.ts.map
@@ -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;;;;;;;;;;;;;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"}
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;aACnC,MAAM,EAAE,aAAa;aACrB,SAAS,EAAE,YAAY;aACvB,QAAQ,EAAE,eAAe;aACzB,QAAQ,EAAE,WAAW;aACrB,UAAU,EAAE,iBAAiB;aAC7B,iBAAiB,EAAE,yBAAyB;aAC5C,SAAS,EAAE,iBAAiB;aAC5B,WAAW,EAAE,mBAAmB;aAChC,YAAY,EAAE,oBAAoB;aAClC,aAAa,EAAE,qBAAqB;aACpC,QAAQ,EAAE,gBAAgB;aAC1B,SAAS,EAAE,iBAAiB;CACpB,CAAA;AAEV,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAA;AAE/G,eAAO,MAAM,2BAA2B;aACtC,UAAU,EAAE,kBAAkB;aAC9B,eAAe,EAAE,wBAAwB;aACzC,aAAa,EAAE,qBAAqB;aACpC,cAAc,EAAE,sBAAsB;aACtC,UAAU,EAAE,kBAAkB;aAC9B,YAAY,EAAE,oBAAoB;aAClC,SAAS,EAAE,iBAAiB;aAC5B,eAAe,EAAE,uBAAuB;aACxC,sBAAsB,EAAE,+BAA+B;aACvD,iBAAiB,EAAE,yBAAyB;aAC5C,4BAA4B,EAAE,qCAAqC;aACnE,eAAe,EAAE,uBAAuB;aACxC,qBAAqB,EAAE,8BAA8B;aACrD,YAAY,EAAE,oBAAoB;aAClC,YAAY,EAAE,oBAAoB;aAClC,OAAO,EAAE,eAAe;aACxB,MAAM,EAAE,aAAa;aACrB,YAAY,EAAE,oBAAoB;aAClC,eAAe,EAAE,wBAAwB;aACzC,QAAQ,EAAE,gBAAgB;aAC1B,cAAc,EAAE,uBAAuB;aACvC,UAAU,EAAE,iBAAiB;aAC7B,eAAe,EAAE,uBAAuB;aACxC,YAAY,EAAE,oBAAoB;aAClC,QAAQ,EAAE,eAAe;aACzB,UAAU,EAAE,kBAAkB;aAC9B,aAAa,EAAE,qBAAqB;aACpC,SAAS,EAAE,aAAa;aACxB,MAAM,EAAE,aAAa;aACrB,YAAY,EAAE,oBAAoB;aAClC,eAAe,EAAE,uBAAuB;aACxC,QAAQ,EAAE,gBAAgB;aAC1B,YAAY,EAAE,oBAAoB;CAC1B,CAAA;AAEV,MAAM,MAAM,2BAA2B,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,OAAO,2BAA2B,CAAC,CAAA"}
@@ -6,17 +6,17 @@
6
6
  * event names.
7
7
  */
8
8
  export declare const MCPAnalyticsEventType: {
9
- readonly identify: "posthog:identify";
10
- readonly custom: "posthog:custom";
11
- readonly mcpFeedback: "mcp:feedback";
12
- readonly mcpMissingCapability: "mcp:missing_capability";
13
- readonly mcpInitialize: "mcp:initialize";
14
- readonly mcpPromptsGet: "mcp:prompts/get";
15
- readonly mcpPromptsList: "mcp:prompts/list";
16
- readonly mcpResourcesList: "mcp:resources/list";
17
- readonly mcpResourcesRead: "mcp:resources/read";
18
- readonly mcpToolsCall: "mcp:tools/call";
19
- readonly mcpToolsList: "mcp:tools/list";
9
+ readonly identify: 'posthog:identify';
10
+ readonly custom: 'posthog:custom';
11
+ readonly mcpFeedback: 'mcp:feedback';
12
+ readonly mcpMissingCapability: 'mcp:missing_capability';
13
+ readonly mcpInitialize: 'mcp:initialize';
14
+ readonly mcpPromptsGet: 'mcp:prompts/get';
15
+ readonly mcpPromptsList: 'mcp:prompts/list';
16
+ readonly mcpResourcesList: 'mcp:resources/list';
17
+ readonly mcpResourcesRead: 'mcp:resources/read';
18
+ readonly mcpToolsCall: 'mcp:tools/call';
19
+ readonly mcpToolsList: 'mcp:tools/list';
20
20
  };
21
21
  export type MCPAnalyticsEventType = (typeof MCPAnalyticsEventType)[keyof typeof MCPAnalyticsEventType];
22
22
  //# sourceMappingURL=event-types.d.ts.map
@@ -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;;;;;;;;;;;;CAYxB,CAAA;AAEV,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAA"}
1
+ {"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../src/extensions/event-types.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;aAChC,QAAQ,EAAE,kBAAkB;aAC5B,MAAM,EAAE,gBAAgB;aACxB,WAAW,EAAE,cAAc;aAC3B,oBAAoB,EAAE,wBAAwB;aAC9C,aAAa,EAAE,gBAAgB;aAC/B,aAAa,EAAE,iBAAiB;aAChC,cAAc,EAAE,kBAAkB;aAClC,gBAAgB,EAAE,oBAAoB;aACtC,gBAAgB,EAAE,oBAAoB;aACtC,YAAY,EAAE,gBAAgB;aAC9B,YAAY,EAAE,gBAAgB;CACtB,CAAA;AAEV,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import type { CollectFeedbackOptions, FeedbackReport, CollectFeedbackConfig, CompatibleTextToolResult, CompatibleToolsListLike, JsonRecord } from '../types';
2
2
  import { type LoggerFn } from './logger';
3
- export declare const SEND_FEEDBACK_TOOL_NAME: "send_feedback";
3
+ export declare const SEND_FEEDBACK_TOOL_NAME: 'send_feedback';
4
4
  type FeedbackToolDescriptor = CompatibleToolsListLike['tools'][number];
5
5
  /** `collectFeedback` normalized to its object form; `undefined` when the feature is off. */
6
6
  export declare function resolveCollectFeedbackOptions(config: CollectFeedbackConfig | undefined): CollectFeedbackOptions | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/extensions/internal.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,cAAc,EACd,aAAa,EAEb,WAAW,EACX,YAAY,EACb,MAAM,UAAU,CAAA;AAMjB;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;gBAErB,OAAO,SAAO;IAI1B,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAWhD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAapD,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B,IAAI,IAAI,MAAM;CAGf;AAID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,SAAS,CAEzF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEzF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CA4B5E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,CAapG;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,kBAAkB,EAAE,WAAW,EAC/B,KAAK,CAAC,EAAE,6BAA6B;AACrC;;;;;GAKG;AACH,uBAAuB,UAAQ,GAC9B,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuDnC;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,CAOtG;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAUzC"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/extensions/internal.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,6BAA6B,EAC7B,gBAAgB,EAChB,cAAc,EACd,aAAa,EAEb,WAAW,EACX,YAAY,EACb,MAAM,UAAU,CAAA;AAMjB;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IAEjC,YAAY,OAAO,SAAO,EAEzB;IAED,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAS/C;IAED,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAWnD;IAED,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9B;IAED,IAAI,IAAI,MAAM,CAEb;CACF;AAID,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,gBAAgB,GAAG,SAAS,CAEzF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAEzF;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,GAAG,OAAO,CA4B5E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,YAAY,GAAG,YAAY,CAapG;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,kBAAkB,EAAE,WAAW,EAC/B,KAAK,CAAC,EAAE,6BAA6B;AACrC;;;;;GAKG;AACH,uBAAuB,UAAQ,GAC9B,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAuDnC;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAG,SAAS,GAAG,WAAW,CAOtG;AAED;;;;GAIG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,CAAC,EAAE,6BAA6B,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAUzC"}
@@ -1,5 +1,5 @@
1
1
  import { PostHog, type PostHogOptions } from 'posthog-node';
2
- import type { FeedbackCaptureData, CollectFeedbackConfig, InitializeCaptureData, MCPAnalyticsOptions, MissingCapabilityCaptureData, PreparedToolCall, PrepareToolCallOptions, PrepareToolListOptions, ToolCallCaptureData, ToolsListCaptureData } from '../types';
2
+ import type { FeedbackCaptureData, CollectFeedbackConfig, InitializeCaptureData, MCPAnalyticsOptions, MissingCapabilityCaptureData, PreparedToolCall, PreparedToolResult, PrepareToolCallOptions, PrepareToolListOptions, ToolCallCaptureData, ToolsListCaptureData } from '../types';
3
3
  import { type ContextInjectableTool } from './context-parameters';
4
4
  /**
5
5
  * Options for {@link PostHogMCP}. A superset of `posthog-node`'s options, plus
@@ -29,6 +29,12 @@ export interface PostHogMCPOptions extends PostHogOptions {
29
29
  * `llm_model` argument as fallback. On by default; `false` disables it.
30
30
  */
31
31
  captureModel?: MCPAnalyticsOptions['captureModel'];
32
+ /**
33
+ * Correlate calls with an agent-carried `conversation_id` and a derived
34
+ * PostHog session id. On by default; `false` leaves schemas, arguments, tool
35
+ * results, and capture data unchanged.
36
+ */
37
+ enableConversationId?: boolean;
32
38
  }
33
39
  /**
34
40
  * A `posthog-node` client with first-class MCP analytics. Use this when there is
@@ -84,9 +90,10 @@ export declare class PostHogMCP extends PostHog {
84
90
  * Decorate your `tools/list` response with PostHog's analytics affordances:
85
91
  * injects the `context` argument into every tool (so agents state their intent,
86
92
  * captured as `$mcp_intent`), injects `llm_model` when the constructor's
87
- * `captureModel` option is enabled, appends `get_more_tools` when
88
- * `reportMissing` is on, and appends `send_feedback` when `collectFeedback` is
89
- * on. Returns a new array; your tools are untouched.
93
+ * `captureModel` option is enabled, and injects the optional `conversation_id`
94
+ * handle by default. It appends `get_more_tools` when `reportMissing` is on and
95
+ * `send_feedback` when `collectFeedback` is on. Returns a new array; your tools
96
+ * are untouched.
90
97
  *
91
98
  * The appended `get_more_tools` descriptor carries only the base MCP tool fields
92
99
  * (name, description, input schema) — not any framework-specific fields your
@@ -94,8 +101,9 @@ export declare class PostHogMCP extends PostHog {
94
101
  * {@link prepareToolCall}'s `isMissingCapability`, not dispatched through a handler.
95
102
  *
96
103
  * Call this when there is no `Server` to wrap — it does for a custom dispatcher
97
- * what `instrument()` does for a `Server`. Pair it with {@link prepareToolCall}
98
- * on the inbound side.
104
+ * what `instrument()` does for a `Server`. Pair it with
105
+ * {@link prepareToolCall} on the inbound side and {@link prepareToolResult} on
106
+ * the outbound side.
99
107
  *
100
108
  * @example
101
109
  * ```ts
@@ -109,8 +117,10 @@ export declare class PostHogMCP extends PostHog {
109
117
  * from SDK-owned arguments, strips those arguments before validation, and flags
110
118
  * whether the call targeted the `get_more_tools` virtual tool.
111
119
  *
112
- * Pass the returned intent and model fields to {@link captureToolCall}, and
113
- * dispatch the returned `args` to your tool.
120
+ * Dispatch the returned `args` to your tool. Then pass the tool result and
121
+ * this prepared call to {@link prepareToolResult}. Use its result as the MCP
122
+ * response and its session and conversation values with
123
+ * {@link captureToolCall}.
114
124
  *
115
125
  * On stateless or multi-replica servers, pass the original tool descriptor
116
126
  * so ownership does not depend on which process served `tools/list`.
@@ -124,24 +134,49 @@ export declare class PostHogMCP extends PostHog {
124
134
  * @example
125
135
  * ```ts
126
136
  * const originalTool = myTools.find((tool) => tool.name === name)
127
- * const { intent, intentSource, llmModel, llmModelSource, args, isMissingCapability } =
128
- * posthog.prepareToolCall(name, rawArgs, {
137
+ * const preparedCall = posthog.prepareToolCall(name, rawArgs, {
129
138
  * originalTool,
130
139
  * requestMeta: request.params?._meta,
131
140
  * })
132
- * if (isMissingCapability) {
133
- * posthog.captureMissingCapability({ context: intent, llmModel, llmModelSource, ...identity })
134
- * return getMoreToolsResult()
141
+ * if (preparedCall.isMissingCapability) {
142
+ * const preparedResult = posthog.prepareToolResult(getMoreToolsResult(), preparedCall)
143
+ * posthog.captureMissingCapability({
144
+ * context: preparedCall.intent,
145
+ * sessionId: preparedResult.sessionId,
146
+ * conversationId: preparedResult.conversationId,
147
+ * ...identity,
148
+ * })
149
+ * return preparedResult.result
135
150
  * }
136
- * const result = await runTool(name, args)
137
- * posthog.captureToolCall({ toolName: name, intent, intentSource, ...identity })
151
+ * const toolResult = await runTool(name, preparedCall.args)
152
+ * const preparedResult = posthog.prepareToolResult(toolResult, preparedCall)
153
+ * posthog.captureToolCall({
154
+ * toolName: name,
155
+ * intent: preparedCall.intent,
156
+ * sessionId: preparedResult.sessionId,
157
+ * conversationId: preparedResult.conversationId,
158
+ * ...identity,
159
+ * })
160
+ * return preparedResult.result
138
161
  * ```
139
162
  */
140
163
  prepareToolCall(name: string, args?: Record<string, unknown>, options?: PrepareToolCallOptions): PreparedToolCall;
164
+ /**
165
+ * Add the conversation handle to a tool result without changing the original
166
+ * value. A new handle is appended to text content once. When the advertised
167
+ * output schema supports it, the handle is also mirrored into
168
+ * `structuredContent`.
169
+ *
170
+ * Use the returned session and conversation values for capture. If a new
171
+ * handle could not reach the client, the conversation value is omitted while
172
+ * the derived session value is kept.
173
+ */
174
+ prepareToolResult<TResult>(result: TResult, preparedCall: PreparedToolCall): PreparedToolResult<TResult>;
141
175
  /**
142
176
  * Capture a `get_more_tools` call as a missing-capability report. Emits
143
177
  * `$mcp_missing_capability` with the agent's description as `$mcp_intent`. Reply
144
- * to the agent with `getMoreToolsResult()`.
178
+ * to the agent with `getMoreToolsResult()` after passing it through
179
+ * {@link prepareToolResult}.
145
180
  */
146
181
  captureMissingCapability(data: MissingCapabilityCaptureData): void;
147
182
  /**
@@ -149,7 +184,7 @@ export declare class PostHogMCP extends PostHog {
149
184
  * `$mcp_feedback` with the report's `$mcp_feedback_*` properties and its
150
185
  * summary/details as `$mcp_intent`. Reply to the agent with
151
186
  * `sendFeedbackResult()` (or a custom text) after routing the report to your
152
- * own feedback backend.
187
+ * own feedback backend and passing the reply through {@link prepareToolResult}.
153
188
  */
154
189
  captureFeedback(data: FeedbackCaptureData): void;
155
190
  }
@@ -1 +1 @@
1
- {"version":3,"file":"posthog-mcp.d.ts","sourceRoot":"","sources":["../../src/extensions/posthog-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAE3D,OAAO,KAAK,EACV,mBAAmB,EAEnB,qBAAqB,EACrB,qBAAqB,EAErB,mBAAmB,EAGnB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAUjB,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAA;AAgB7B;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,qBAAqB,CAAA;IACvC;;;OAGG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;CACnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,UAAW,SAAQ,OAAO;;gBAazB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB;IAoB3D,8FAA8F;IAC9F,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI;IAkBhD,iEAAiE;IACjE,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI;IAUpD;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAclD;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,eAAe,CAAC,KAAK,SAAS,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,GAAE,sBAA2B,GAAG,KAAK,EAAE;IAyCnH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,GAAE,sBAA2B,GACnC,gBAAgB;IAqCnB;;;;OAIG;IACH,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,IAAI;IASlE;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI;CAuBjD"}
1
+ {"version":3,"file":"posthog-mcp.d.ts","sourceRoot":"","sources":["../../src/extensions/posthog-mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAE3D,OAAO,KAAK,EACV,mBAAmB,EAGnB,qBAAqB,EACrB,qBAAqB,EAErB,mBAAmB,EAGnB,4BAA4B,EAC5B,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAgBjB,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,sBAAsB,CAAA;AAkB7B;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,qBAAqB,CAAA;IACvC;;;OAGG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;IAClD;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,UAAW,SAAQ,OAAO;;IAcrC,YAAY,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,EAe1D;IAMD,8FAA8F;IAC9F,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAgB/C;IAED,iEAAiE;IACjE,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,CAQnD;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAYjD;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,eAAe,CAAC,KAAK,SAAS,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,OAAO,GAAE,sBAA2B,GAAG,KAAK,EAAE,CAmDlH;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+CG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,GAAE,sBAA2B,GACnC,gBAAgB,CAiDlB;IAED;;;;;;;;;OASG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,gBAAgB,GAAG,kBAAkB,CAAC,OAAO,CAAC,CA2BvG;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,IAAI,EAAE,4BAA4B,GAAG,IAAI,CAOjE;IAED;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAW/C;CAYF"}
@@ -33,6 +33,7 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  const external_posthog_node_namespaceObject = require("posthog-node");
34
34
  const external_feedback_js_namespaceObject = require("./feedback.js");
35
35
  const external_analytics_parameters_js_namespaceObject = require("./analytics-parameters.js");
36
+ const external_conversation_id_js_namespaceObject = require("./conversation-id.js");
36
37
  const external_context_parameters_js_namespaceObject = require("./context-parameters.js");
37
38
  const external_event_types_js_namespaceObject = require("./event-types.js");
38
39
  const external_exceptions_js_namespaceObject = require("./exceptions.js");
@@ -41,20 +42,25 @@ const external_lib_identity_js_namespaceObject = require("./lib-identity.js");
41
42
  const external_logger_js_namespaceObject = require("./logger.js");
42
43
  const external_model_parameters_js_namespaceObject = require("./model-parameters.js");
43
44
  const external_sink_js_namespaceObject = require("./sink.js");
45
+ const external_output_instructions_js_namespaceObject = require("./output-instructions.js");
46
+ const external_session_js_namespaceObject = require("./session.js");
44
47
  const external_tools_js_namespaceObject = require("./tools.js");
48
+ const PREPARED_CONVERSATION_STATE_KEY = '__posthogMcpConversationState';
45
49
  class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
46
50
  #sink;
47
51
  #missingCapabilityToolName;
48
52
  #feedbackOptions;
49
53
  #captureModel;
50
- #modelParameterOwnership;
54
+ #enableConversationId;
55
+ #analyticsParameterOwnership;
51
56
  constructor(apiKey, options = {}){
52
- super(apiKey, options), this.#sink = new external_sink_js_namespaceObject.McpEventSink(this), this.#modelParameterOwnership = new Map();
57
+ super(apiKey, options), this.#sink = new external_sink_js_namespaceObject.McpEventSink(this), this.#analyticsParameterOwnership = new Map();
53
58
  this.#missingCapabilityToolName = options.missingCapabilityToolName ?? external_tools_js_namespaceObject.GET_MORE_TOOLS_NAME;
54
59
  this.#feedbackOptions = (0, external_feedback_js_namespaceObject.resolveCollectFeedbackOptions)(options.collectFeedback);
55
60
  (0, external_feedback_js_namespaceObject.getFeedbackToolDescriptor)(this.#feedbackOptions);
56
61
  if (this.#feedbackOptions?.onFeedback) (0, external_logger_js_namespaceObject.log)('Warning: collectFeedback.onFeedback is ignored on the PostHogMCP path - route reports from your dispatcher via prepareToolCall().feedbackReport instead.');
57
62
  this.#captureModel = options.captureModel;
63
+ this.#enableConversationId = options.enableConversationId ?? true;
58
64
  (0, external_lib_identity_js_namespaceObject.applyMcpLibIdentity)(this);
59
65
  }
60
66
  get #feedbackToolName() {
@@ -100,32 +106,47 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
100
106
  let prepared = (0, external_context_parameters_js_namespaceObject.isContextEnabled)(contextOption) ? (0, external_context_parameters_js_namespaceObject.addContextParameterToTools)(tools, (0, external_context_parameters_js_namespaceObject.getContextDescription)(contextOption)) : [
101
107
  ...tools
102
108
  ];
103
- if (options.reportMissing && !prepared.some((tool)=>tool?.name === this.#missingCapabilityToolName)) prepared = [
104
- ...prepared,
105
- (0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(this.#missingCapabilityToolName)
106
- ];
107
- if (options.collectFeedback && void 0 !== this.#feedbackOptions && !prepared.some((tool)=>tool?.name === this.#feedbackToolName)) prepared = [
108
- ...prepared,
109
- (0, external_feedback_js_namespaceObject.getFeedbackToolDescriptor)(this.#feedbackOptions)
109
+ const ownershipSources = [
110
+ ...tools
110
111
  ];
112
+ if (options.reportMissing && !prepared.some((tool)=>tool?.name === this.#missingCapabilityToolName)) {
113
+ const virtualTool = (0, external_tools_js_namespaceObject.getReportMissingToolDescriptor)(this.#missingCapabilityToolName);
114
+ prepared = [
115
+ ...prepared,
116
+ virtualTool
117
+ ];
118
+ ownershipSources.push(virtualTool);
119
+ }
120
+ if (options.collectFeedback && void 0 !== this.#feedbackOptions && !prepared.some((tool)=>tool?.name === this.#feedbackToolName)) {
121
+ const virtualTool = (0, external_feedback_js_namespaceObject.getFeedbackToolDescriptor)(this.#feedbackOptions);
122
+ prepared = [
123
+ ...prepared,
124
+ virtualTool
125
+ ];
126
+ ownershipSources.push(virtualTool);
127
+ }
128
+ this.#analyticsParameterOwnership.clear();
129
+ const ownershipByName = collectAnalyticsParameterOwnership(ownershipSources);
130
+ for (const [toolName, ownership] of ownershipByName)this.#analyticsParameterOwnership.set(toolName, ownership);
111
131
  if ((0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(this.#captureModel)) {
112
- this.#modelParameterOwnership.clear();
113
- const ownershipByName = new Map();
114
- for (const tool of prepared){
115
- if ('string' != typeof tool.name) continue;
116
- const ownsModel = (0, external_analytics_parameters_js_namespaceObject.analyticsOwnsParameter)(tool.inputSchema, 'llm_model');
117
- ownershipByName.set(tool.name, (ownershipByName.get(tool.name) ?? true) && ownsModel);
118
- }
119
- for (const [toolName, ownsModel] of ownershipByName)this.#modelParameterOwnership.set(toolName, ownsModel);
120
132
  const modelDescription = (0, external_model_parameters_js_namespaceObject.getModelDescription)(this.#captureModel);
121
- prepared = prepared.map((tool)=>'string' == typeof tool.name && false === ownershipByName.get(tool.name) ? tool : (0, external_model_parameters_js_namespaceObject.addModelParameterToTool)(tool, modelDescription));
133
+ prepared = prepared.map((tool)=>'string' == typeof tool.name && ownershipByName.get(tool.name)?.llmModel === false ? tool : (0, external_model_parameters_js_namespaceObject.addModelParameterToTool)(tool, modelDescription));
134
+ }
135
+ if (this.#enableConversationId) {
136
+ prepared = prepared.map((tool)=>'string' == typeof tool.name && ownershipByName.get(tool.name)?.conversationId === false ? tool : (0, external_conversation_id_js_namespaceObject.addConversationIdToTools)([
137
+ tool
138
+ ])[0]);
139
+ prepared = prepared.map((tool)=>'string' == typeof tool.name && ownershipByName.get(tool.name)?.outputInstructions === false ? tool : (0, external_output_instructions_js_namespaceObject.addInstructionsToOutputSchemas)([
140
+ tool
141
+ ])[0]);
122
142
  }
123
143
  return prepared;
124
144
  }
125
145
  prepareToolCall(name, args, options = {}) {
126
146
  const rawContext = args?.context;
127
147
  const intent = 'string' == typeof rawContext && rawContext.trim() ? rawContext.trim() : void 0;
128
- const ownsModel = (0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(this.#captureModel) && (options.originalTool ? (0, external_analytics_parameters_js_namespaceObject.analyticsOwnsParameter)(options.originalTool.inputSchema, 'llm_model') : true === this.#modelParameterOwnership.get(name));
148
+ const ownership = options.originalTool ? (0, external_analytics_parameters_js_namespaceObject.getAnalyticsParameterOwnership)(options.originalTool.inputSchema, options.originalTool.outputSchema) : this.#analyticsParameterOwnership.get(name);
149
+ const ownsModel = (0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(this.#captureModel) && ownership?.llmModel === true;
129
150
  const resolvedModel = (0, external_model_parameters_js_namespaceObject.isCaptureModelEnabled)(this.#captureModel) ? (0, external_model_parameters_js_namespaceObject.resolveModel)({
130
151
  params: {
131
152
  arguments: args,
@@ -133,20 +154,65 @@ class PostHogMCP extends external_posthog_node_namespaceObject.PostHog {
133
154
  }
134
155
  }, ownsModel) : void 0;
135
156
  const strippedArgs = stripContext(args);
157
+ const canReadConversationId = this.#enableConversationId && (ownership?.conversationId ?? true);
158
+ const resolvedConversation = (0, external_conversation_id_js_namespaceObject.resolveConversationId)(canReadConversationId, args);
159
+ const conversation = resolvedConversation.minted && options.sessionId ? {
160
+ minted: false,
161
+ conversationId: void 0
162
+ } : resolvedConversation;
163
+ const conversationId = conversation.conversationId;
164
+ const sessionId = conversationId ? (0, external_session_js_namespaceObject.deriveSessionIdFromConversation)(conversationId) : options.sessionId;
136
165
  const isFeedback = void 0 !== this.#feedbackOptions && name === this.#feedbackToolName && null == options.originalTool;
137
- return {
166
+ const preparedCall = {
138
167
  intent,
139
168
  intentSource: intent ? 'context_parameter' : void 0,
140
169
  llmModel: resolvedModel?.model,
141
170
  llmModelSource: resolvedModel?.source,
142
- args: ownsModel ? (0, external_analytics_parameters_js_namespaceObject.stripOwnedAnalyticsArguments)(strippedArgs, {
171
+ args: (0, external_analytics_parameters_js_namespaceObject.stripOwnedAnalyticsArguments)(strippedArgs, {
143
172
  context: false,
144
- conversationId: false,
145
- llmModel: true
146
- }) : strippedArgs,
173
+ conversationId: this.#enableConversationId && ownership?.conversationId === true,
174
+ llmModel: ownsModel
175
+ }),
176
+ sessionId,
177
+ conversationId,
147
178
  isMissingCapability: name === this.#missingCapabilityToolName,
148
179
  isFeedback,
149
- feedbackReport: isFeedback ? (0, external_feedback_js_namespaceObject.parseFeedbackReport)(args, this.#feedbackOptions) : void 0
180
+ feedbackReport: isFeedback ? (0, external_feedback_js_namespaceObject.parseFeedbackReport)(args, this.#feedbackOptions) : void 0,
181
+ [PREPARED_CONVERSATION_STATE_KEY]: {
182
+ minted: conversation.minted,
183
+ outputInstructions: this.#enableConversationId && ownership?.outputInstructions === true
184
+ }
185
+ };
186
+ return preparedCall;
187
+ }
188
+ prepareToolResult(result, preparedCall) {
189
+ const state = preparedCall[PREPARED_CONVERSATION_STATE_KEY];
190
+ const conversationId = preparedCall.conversationId;
191
+ if (!conversationId) return {
192
+ result,
193
+ sessionId: preparedCall.sessionId,
194
+ conversationId
195
+ };
196
+ if (!state) return {
197
+ result,
198
+ sessionId: preparedCall.sessionId,
199
+ conversationId: void 0
200
+ };
201
+ let preparedResult = result;
202
+ let delivered = false;
203
+ if (state.outputInstructions) {
204
+ const mirrored = (0, external_output_instructions_js_namespaceObject.mirrorInstructionsIntoStructuredContent)(preparedResult, conversationId);
205
+ delivered = mirrored !== preparedResult;
206
+ preparedResult = mirrored;
207
+ }
208
+ if (state.minted && (0, external_conversation_id_js_namespaceObject.canInjectConversationIdPromptBack)(preparedResult)) {
209
+ preparedResult = (0, external_conversation_id_js_namespaceObject.injectConversationIdPromptBack)(preparedResult, conversationId);
210
+ delivered = true;
211
+ }
212
+ return {
213
+ result: preparedResult,
214
+ sessionId: preparedCall.sessionId,
215
+ conversationId: state.minted && !delivered ? void 0 : conversationId
150
216
  };
151
217
  }
152
218
  captureMissingCapability(data) {
@@ -178,6 +244,7 @@ function baseEvent(eventType, common) {
178
244
  const event = {
179
245
  eventType,
180
246
  sessionId: common.sessionId,
247
+ conversationId: common.conversationId,
181
248
  protocolVersion: common.protocolVersion,
182
249
  clientUserAgent: (0, external_headers_js_namespaceObject.normalizeHeaderString)(common.clientUserAgent),
183
250
  vendorClient: (0, external_headers_js_namespaceObject.normalizeHeaderString)(common.vendorClient),
@@ -189,6 +256,21 @@ function baseEvent(eventType, common) {
189
256
  if (common.setProperties && Object.keys(common.setProperties).length > 0) event.identifyActorData = common.setProperties;
190
257
  return event;
191
258
  }
259
+ function collectAnalyticsParameterOwnership(tools) {
260
+ const ownershipByName = new Map();
261
+ for (const tool of tools){
262
+ if ('string' != typeof tool.name) continue;
263
+ const next = (0, external_analytics_parameters_js_namespaceObject.getAnalyticsParameterOwnership)(tool.inputSchema, tool.outputSchema);
264
+ const current = ownershipByName.get(tool.name);
265
+ ownershipByName.set(tool.name, current ? {
266
+ context: current.context && next.context,
267
+ conversationId: current.conversationId && next.conversationId,
268
+ llmModel: current.llmModel && next.llmModel,
269
+ outputInstructions: current.outputInstructions && next.outputInstructions
270
+ } : next);
271
+ }
272
+ return ownershipByName;
273
+ }
192
274
  function applyIntent(event, intent, source) {
193
275
  const trimmed = 'string' == typeof intent ? intent.trim() : '';
194
276
  if (!trimmed) return;