@f5-sales-demo/pi-ai 21.50.0 → 22.0.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5-sales-demo/pi-ai",
4
- "version": "21.50.0",
4
+ "version": "22.0.1",
5
5
  "description": "Unified LLM API with automatic model discovery and provider configuration",
6
6
  "homepage": "https://github.com/f5-sales-demo/xcsh",
7
7
  "author": "Can Boluk",
@@ -46,7 +46,7 @@
46
46
  "@anthropic-ai/sdk": "0.123.0",
47
47
  "@aws-sdk/client-bedrock-runtime": "3.1126.0",
48
48
  "@bufbuild/protobuf": "2.14.1",
49
- "@f5-sales-demo/pi-utils": "21.50.0",
49
+ "@f5-sales-demo/pi-utils": "22.0.1",
50
50
  "@google/genai": "2.21.0",
51
51
  "@sinclair/typebox": "0.34.52",
52
52
  "@smithy/node-http-handler": "4.12.1",
@@ -11,8 +11,8 @@ import type {
11
11
  Context,
12
12
  CursorExecHandlerResult,
13
13
  CursorExecHandlers,
14
- CursorMcpCall,
15
14
  CursorShellStreamCallbacks,
15
+ CursorToolCall,
16
16
  CursorToolResultHandler,
17
17
  ImageContent,
18
18
  Message,
@@ -225,7 +225,7 @@ function extractLogBytes(value: unknown): Uint8Array | null {
225
225
  return null;
226
226
  }
227
227
 
228
- function decodeMcpArgsForLog(args?: Record<string, unknown>): Record<string, unknown> | undefined {
228
+ function decodeToolArgsForLog(args?: Record<string, unknown>): Record<string, unknown> | undefined {
229
229
  if (!args) {
230
230
  return undefined;
231
231
  }
@@ -234,7 +234,7 @@ function decodeMcpArgsForLog(args?: Record<string, unknown>): Record<string, unk
234
234
  for (const [key, value] of Object.entries(args)) {
235
235
  const bytes = extractLogBytes(value);
236
236
  if (bytes) {
237
- decoded[key] = decodeMcpArgValue(bytes);
237
+ decoded[key] = decodeToolArgValue(bytes);
238
238
  mutated = true;
239
239
  continue;
240
240
  }
@@ -259,13 +259,13 @@ function decodeLogData(value: unknown): unknown {
259
259
  const stripTypeName = typeof typeName === "string" && typeName.startsWith("agent.v1.");
260
260
 
261
261
  if (typeName === "agent.v1.McpArgs") {
262
- const decodedArgs = decodeMcpArgsForLog(record.args as Record<string, unknown> | undefined);
262
+ const decodedArgs = decodeToolArgsForLog(record.args as Record<string, unknown> | undefined);
263
263
  const base = stripTypeName ? omitTypeName(record) : record;
264
264
  return decodedArgs ? { ...base, args: decodedArgs } : base;
265
265
  }
266
266
  if (typeName === "agent.v1.McpToolCall") {
267
267
  const argsRecord = record.args as Record<string, unknown> | undefined;
268
- const decodedArgs = decodeMcpArgsForLog(argsRecord?.args as Record<string, unknown> | undefined);
268
+ const decodedArgs = decodeToolArgsForLog(argsRecord?.args as Record<string, unknown> | undefined);
269
269
  const base = stripTypeName ? omitTypeName(record) : record;
270
270
  if (decodedArgs && argsRecord) {
271
271
  return { ...base, args: { ...argsRecord, args: decodedArgs } };
@@ -363,7 +363,7 @@ export const streamCursor: StreamFunction<"cursor-agent"> = (
363
363
  conversationState: cachedState,
364
364
  });
365
365
  conversationStateCache.set(conversationId, conversationState);
366
- const requestContextTools = buildMcpToolDefinitions(context.tools);
366
+ const requestContextTools = buildCursorToolDefinitions(context.tools);
367
367
 
368
368
  const baseUrl = model.baseUrl || CURSOR_API_URL;
369
369
  h2Client = http2.connect(baseUrl);
@@ -569,7 +569,7 @@ export const streamCursor: StreamFunction<"cursor-agent"> = (
569
569
  return stream;
570
570
  };
571
571
 
572
- type ToolCallState = ToolCall & { index: number; partialJson?: string; kind: "mcp" | "todo_write" };
572
+ type ToolCallState = ToolCall & { index: number; partialJson?: string; kind: "tool" | "todo_write" };
573
573
 
574
574
  interface BlockState {
575
575
  currentTextBlock: (TextContent & { index: number }) | null;
@@ -1042,14 +1042,14 @@ async function handleExecServerMessage(
1042
1042
  }
1043
1043
  case "mcpArgs": {
1044
1044
  const args = execMsg.message.value;
1045
- const mcpCall = decodeMcpCall(args);
1045
+ const toolCall = decodeCursorToolCall(args);
1046
1046
  const { execResult } = await resolveExecHandler(
1047
- mcpCall,
1048
- execHandlers?.mcp?.bind(execHandlers),
1047
+ toolCall,
1048
+ execHandlers?.tool?.bind(execHandlers),
1049
1049
  onToolResult,
1050
- toolResult => buildMcpResultFromToolResult(mcpCall, toolResult),
1051
- _reason => buildMcpToolNotFoundResult(mcpCall),
1052
- error => buildMcpErrorResult(error),
1050
+ toolResult => buildCursorToolResult(toolResult),
1051
+ _reason => buildCursorToolNotFoundResult(toolCall),
1052
+ error => buildCursorToolErrorResult(error),
1053
1053
  );
1054
1054
  sendExecClientMessage(h2Request, execMsg, "mcpResult", execResult);
1055
1055
  return;
@@ -1652,7 +1652,7 @@ function parseToolArgsJson(text: string): unknown {
1652
1652
  return text;
1653
1653
  }
1654
1654
 
1655
- function decodeMcpArgValue(value: Uint8Array): unknown {
1655
+ function decodeToolArgValue(value: Uint8Array): unknown {
1656
1656
  try {
1657
1657
  const parsedValue = fromBinary(ValueSchema, value);
1658
1658
  const jsonValue = toJson(ValueSchema, parsedValue) as JsonValue;
@@ -1665,27 +1665,27 @@ function decodeMcpArgValue(value: Uint8Array): unknown {
1665
1665
  return parseToolArgsJson(text);
1666
1666
  }
1667
1667
 
1668
- function decodeMcpArgsMap(args?: Record<string, Uint8Array>): Record<string, unknown> | undefined {
1668
+ function decodeToolArgsMap(args?: Record<string, Uint8Array>): Record<string, unknown> | undefined {
1669
1669
  if (!args) {
1670
1670
  return undefined;
1671
1671
  }
1672
1672
  const decoded: Record<string, unknown> = {};
1673
1673
  for (const [key, value] of Object.entries(args)) {
1674
- decoded[key] = decodeMcpArgValue(value);
1674
+ decoded[key] = decodeToolArgValue(value);
1675
1675
  }
1676
1676
  return decoded;
1677
1677
  }
1678
1678
 
1679
- function decodeMcpCall(args: {
1679
+ function decodeCursorToolCall(args: {
1680
1680
  name: string;
1681
1681
  args: Record<string, Uint8Array>;
1682
1682
  toolCallId: string;
1683
1683
  providerIdentifier: string;
1684
1684
  toolName: string;
1685
- }): CursorMcpCall {
1685
+ }): CursorToolCall {
1686
1686
  const decodedArgs: Record<string, unknown> = {};
1687
1687
  for (const [key, value] of Object.entries(args.args ?? {})) {
1688
- decodedArgs[key] = decodeMcpArgValue(value);
1688
+ decodedArgs[key] = decodeToolArgValue(value);
1689
1689
  }
1690
1690
  return {
1691
1691
  name: args.name,
@@ -1733,9 +1733,9 @@ function buildTodoWriteArgs(toolCall: CursorUpdateTodosToolCall): {
1733
1733
  };
1734
1734
  }
1735
1735
 
1736
- function buildMcpResultFromToolResult(_mcpCall: CursorMcpCall, toolResult: ToolResultMessage) {
1736
+ function buildCursorToolResult(toolResult: ToolResultMessage) {
1737
1737
  if (toolResult.isError) {
1738
- return buildMcpErrorResult(toolResultToText(toolResult) || "MCP tool failed");
1738
+ return buildCursorToolErrorResult(toolResultToText(toolResult) || "Tool failed");
1739
1739
  }
1740
1740
  const content = toolResult.content.map(item => {
1741
1741
  if (item.type === "image") {
@@ -1768,16 +1768,16 @@ function buildMcpResultFromToolResult(_mcpCall: CursorMcpCall, toolResult: ToolR
1768
1768
  });
1769
1769
  }
1770
1770
 
1771
- function buildMcpToolNotFoundResult(mcpCall: CursorMcpCall) {
1771
+ function buildCursorToolNotFoundResult(toolCall: CursorToolCall) {
1772
1772
  return create(McpResultSchema, {
1773
1773
  result: {
1774
1774
  case: "toolNotFound",
1775
- value: create(McpToolNotFoundSchema, { name: mcpCall.toolName, availableTools: [] }),
1775
+ value: create(McpToolNotFoundSchema, { name: toolCall.toolName, availableTools: [] }),
1776
1776
  },
1777
1777
  });
1778
1778
  }
1779
1779
 
1780
- function buildMcpErrorResult(error: string) {
1780
+ function buildCursorToolErrorResult(error: string) {
1781
1781
  return create(McpResultSchema, {
1782
1782
  result: {
1783
1783
  case: "error",
@@ -1854,7 +1854,7 @@ function processInteractionUpdate(
1854
1854
  arguments: {},
1855
1855
  index: output.content.length,
1856
1856
  partialJson: "",
1857
- kind: "mcp",
1857
+ kind: "tool",
1858
1858
  };
1859
1859
  output.content.push(block);
1860
1860
  state.setToolCall(block);
@@ -1879,7 +1879,7 @@ function processInteractionUpdate(
1879
1879
  }
1880
1880
  }
1881
1881
  } else if (updateCase === "toolCallDelta" || updateCase === "partialToolCall") {
1882
- if (state.currentToolCall?.kind === "mcp") {
1882
+ if (state.currentToolCall?.kind === "tool") {
1883
1883
  const delta = update.message.value.argsTextDelta || "";
1884
1884
  state.currentToolCall.partialJson = `${state.currentToolCall.partialJson ?? ""}${delta}`;
1885
1885
  state.currentToolCall.arguments = parseStreamingJson(state.currentToolCall.partialJson ?? "");
@@ -1889,8 +1889,8 @@ function processInteractionUpdate(
1889
1889
  } else if (updateCase === "toolCallCompleted") {
1890
1890
  if (state.currentToolCall) {
1891
1891
  const toolCall = update.message.value.toolCall;
1892
- if (state.currentToolCall.kind === "mcp") {
1893
- const decodedArgs = decodeMcpArgsMap(toolCall?.mcpToolCall?.args?.args);
1892
+ if (state.currentToolCall.kind === "tool") {
1893
+ const decodedArgs = decodeToolArgsMap(toolCall?.mcpToolCall?.args?.args);
1894
1894
  if (decodedArgs) {
1895
1895
  state.currentToolCall.arguments = decodedArgs;
1896
1896
  }
@@ -1943,7 +1943,7 @@ function createBlobId(data: Uint8Array): Uint8Array {
1943
1943
 
1944
1944
  const CURSOR_NATIVE_TOOL_NAMES = new Set(["bash", "read", "write", "delete", "ls", "grep", "lsp", "todo_write"]);
1945
1945
 
1946
- function buildMcpToolDefinitions(tools: Tool[] | undefined): McpToolDefinition[] {
1946
+ function buildCursorToolDefinitions(tools: Tool[] | undefined): McpToolDefinition[] {
1947
1947
  if (!tools || tools.length === 0) {
1948
1948
  return [];
1949
1949
  }
package/src/types.ts CHANGED
@@ -12,7 +12,6 @@ import type {
12
12
  GrepResult,
13
13
  LsArgs,
14
14
  LsResult,
15
- McpResult,
16
15
  ReadArgs,
17
16
  ReadResult,
18
17
  ShellArgs,
@@ -222,7 +221,7 @@ export interface StreamOptions {
222
221
  * Set to 0 to disable the first-event watchdog for this request.
223
222
  */
224
223
  streamFirstEventTimeoutMs?: number;
225
- /** Cursor exec/MCP tool handlers (cursor-agent only). */
224
+ /** Cursor generic execution handlers (cursor-agent only). */
226
225
  execHandlers?: CursorExecHandlers;
227
226
  }
228
227
 
@@ -428,7 +427,8 @@ export type CursorToolResultHandler = (
428
427
  result: ToolResultMessage,
429
428
  ) => ToolResultMessage | undefined | Promise<ToolResultMessage | undefined>;
430
429
 
431
- export interface CursorMcpCall {
430
+ /** A generic tool request transported by the Cursor agent protocol. */
431
+ export interface CursorToolCall {
432
432
  name: string;
433
433
  providerIdentifier: string;
434
434
  toolName: string;
@@ -454,7 +454,7 @@ export interface CursorExecHandlers {
454
454
  callbacks: CursorShellStreamCallbacks,
455
455
  ) => Promise<CursorExecHandlerResult<ShellResult>>;
456
456
  diagnostics?: (args: DiagnosticsArgs) => Promise<CursorExecHandlerResult<DiagnosticsResult>>;
457
- mcp?: (call: CursorMcpCall) => Promise<CursorExecHandlerResult<McpResult>>;
457
+ tool?: (call: CursorToolCall) => Promise<CursorExecHandlerResult<unknown>>;
458
458
  onToolResult?: CursorToolResultHandler;
459
459
  }
460
460
 
@@ -181,14 +181,14 @@ export function sanitizeSchemaForCCA(value: unknown): unknown {
181
181
  }
182
182
 
183
183
  /**
184
- * Fields stripped for MCP/AJV compatibility.
184
+ * Fields stripped for AJV compatibility.
185
185
  * Only `$schema` — AJV throws on unrecognised meta-schema URIs
186
186
  * (e.g. draft 2020-12 emitted by schemars 1.x / rmcp 0.15+).
187
187
  */
188
- const MCP_UNSUPPORTED_SCHEMA_FIELDS = new Set(["$schema"]);
188
+ const AJV_UNSUPPORTED_SCHEMA_FIELDS = new Set(["$schema"]);
189
189
 
190
190
  /**
191
- * Sanitize a JSON Schema for MCP tool parameter validation (AJV compatibility).
191
+ * Sanitize a JSON Schema for tool parameter validation (AJV compatibility).
192
192
  *
193
193
  * Strips only the minimal set of fields that cause AJV validation errors:
194
194
  * - `$schema`: AJV throws on unknown meta-schema URIs.
@@ -198,7 +198,7 @@ const MCP_UNSUPPORTED_SCHEMA_FIELDS = new Set(["$schema"]);
198
198
  * (`pattern`, `format`, `additionalProperties`, etc.) and `$ref`/`$defs`.
199
199
  */
200
200
  export function sanitizeSchemaForMCP(value: unknown): unknown {
201
- // Dereference $ref/$defs first — MCP servers emit standard JSON Schema
201
+ // Dereference $ref/$defs first because providers emit standard JSON Schema.
202
202
  // with $defs, but providers (Anthropic, Google) only forward `properties`
203
203
  // and `required`, dropping $defs and leaving dangling $ref pointers.
204
204
  const dereferenced = dereferenceJsonSchema(value);
@@ -206,7 +206,7 @@ export function sanitizeSchemaForMCP(value: unknown): unknown {
206
206
  insideProperties: false,
207
207
  normalizeTypeArrayToNullable: false,
208
208
  stripNullableKeyword: true,
209
- unsupportedFields: MCP_UNSUPPORTED_SCHEMA_FIELDS,
209
+ unsupportedFields: AJV_UNSUPPORTED_SCHEMA_FIELDS,
210
210
  seen: new WeakSet(),
211
211
  });
212
212
  }
@@ -513,7 +513,7 @@ function coerceArgsFromErrors(
513
513
  // Create a singleton AJV instance with formats (only if not in browser extension)
514
514
  // AJV requires 'unsafe-eval' CSP which is not allowed in Manifest V3
515
515
  //
516
- // Silent logger: MCP servers may declare non-standard format keywords (e.g. "uint")
516
+ // Silent logger: external tool schemas may declare non-standard format keywords (e.g. "uint").
517
517
  // which cause Ajv to emit console.warn() with strict:false — corrupting TUI output.
518
518
  const ajv = new Ajv({
519
519
  allErrors: false,