@wix/mcp 1.0.94 → 1.0.96

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.
Files changed (86) hide show
  1. package/README.md +2 -2
  2. package/build/bin-standalone.js +1457 -332
  3. package/build/cjs/index.cjs +3379 -1333
  4. package/build/cjs/toolkit.cjs +2158 -373
  5. package/build/dts/api-call/headless-release.d.ts +56 -0
  6. package/build/dts/api-call/headless-release.js +135 -0
  7. package/build/dts/api-call/index.d.ts +9 -1
  8. package/build/dts/api-call/index.js +36 -8
  9. package/build/dts/api-call/site-files.d.ts +14 -0
  10. package/build/dts/api-call/site-files.js +106 -10
  11. package/build/dts/api-call/upload-headless-website-files.d.ts +117 -5
  12. package/build/dts/api-call/upload-headless-website-files.js +565 -20
  13. package/build/dts/api-call/upload-image-tool.d.ts +2 -0
  14. package/build/dts/api-call/upload-image-tool.js +8 -4
  15. package/build/dts/bin.d.ts +1 -1
  16. package/build/dts/bin.js +3 -1
  17. package/build/dts/code-mode/attachments.d.ts +9 -6
  18. package/build/dts/code-mode/attachments.js +23 -16
  19. package/build/dts/code-mode/index.d.ts +6 -1
  20. package/build/dts/code-mode/index.js +32 -12
  21. package/build/dts/code-mode/truncate-response.js +5 -1
  22. package/build/dts/config/default-config.d.ts +35 -5
  23. package/build/dts/config/default-config.js +339 -182
  24. package/build/dts/config/file-params.d.ts +22 -0
  25. package/build/dts/config/file-params.js +24 -0
  26. package/build/dts/config/param-descriptions.d.ts +14 -2
  27. package/build/dts/config/param-descriptions.js +33 -14
  28. package/build/dts/constants.d.ts +1 -0
  29. package/build/dts/constants.js +1 -0
  30. package/build/dts/docs/docs.d.ts +12 -1
  31. package/build/dts/docs/docs.js +274 -43
  32. package/build/dts/docs/fetch-article.d.ts +21 -0
  33. package/build/dts/docs/fetch-article.js +66 -4
  34. package/build/dts/docs/get-to-know.d.ts +7 -2
  35. package/build/dts/docs/get-to-know.js +36 -14
  36. package/build/dts/docs/guessed-url.d.ts +41 -0
  37. package/build/dts/docs/guessed-url.js +185 -0
  38. package/build/dts/docs/mintlify-docs.d.ts +121 -0
  39. package/build/dts/docs/mintlify-docs.js +391 -0
  40. package/build/dts/docs/semanticSearch.d.ts +2 -1
  41. package/build/dts/docs/semanticSearch.js +14 -7
  42. package/build/dts/docs/start-deploy-website.d.ts +7 -6
  43. package/build/dts/docs/start-deploy-website.js +13 -8
  44. package/build/dts/docs/start-headless-build.d.ts +8 -10
  45. package/build/dts/docs/start-headless-build.js +14 -28
  46. package/build/dts/index.d.ts +2 -2
  47. package/build/dts/index.js +2 -2
  48. package/build/dts/infra/redact-personal-data.d.ts +4 -0
  49. package/build/dts/infra/redact-personal-data.js +148 -0
  50. package/build/dts/site-widget-tools/constants.d.ts +50 -2
  51. package/build/dts/site-widget-tools/constants.js +65 -8
  52. package/build/dts/site-widget-tools/index.d.ts +1 -0
  53. package/build/dts/site-widget-tools/index.js +1 -0
  54. package/build/dts/site-widget-tools/pick-images-tool/index.d.ts +14 -0
  55. package/build/dts/site-widget-tools/pick-images-tool/index.js +138 -0
  56. package/build/dts/site-widget-tools/pull-site-creation-job-tool/index.js +1 -1
  57. package/build/dts/site-widget-tools/search-site-templates-tool/index.js +25 -2
  58. package/build/dts/site-widget-tools/site-builder-tool/index.js +35 -3
  59. package/build/dts/site-widget-tools/site-creation-tool/index.d.ts +7 -1
  60. package/build/dts/site-widget-tools/site-creation-tool/index.js +22 -51
  61. package/build/dts/site-widget-tools/suggested-domain-tool/index.js +26 -12
  62. package/build/dts/support/index.d.ts +4 -0
  63. package/build/dts/support/index.js +13 -7
  64. package/build/dts/tool-utils.d.ts +8 -1
  65. package/build/dts/tool-utils.js +26 -2
  66. package/build/dts/toolkit-entry.d.cts +15 -10
  67. package/build/dts/toolkit-entry.d.ts +15 -10
  68. package/build/dts/toolkit.d.ts +2 -2
  69. package/build/dts/toolkit.js +21 -8
  70. package/build/dts/wix-mcp-server.d.ts +10 -1
  71. package/build/dts/wix-mcp-server.js +25 -7
  72. package/build/dts/wixel/constants.d.ts +8 -1
  73. package/build/dts/wixel/constants.js +8 -1
  74. package/build/dts/wixel/index.d.ts +1 -1
  75. package/build/dts/wixel/index.js +2 -2
  76. package/build/dts/wixel/wixel-a2a-client.d.ts +83 -0
  77. package/build/dts/wixel/wixel-a2a-client.js +166 -0
  78. package/build/dts/wixel/wixel-bi.d.ts +2 -1
  79. package/build/dts/wixel/wixel-bi.js +2 -1
  80. package/build/dts/wixel/{external-agent-api.d.ts → wixel-session-entries.d.ts} +11 -33
  81. package/build/dts/wixel/{external-agent-api.js → wixel-session-entries.js} +33 -54
  82. package/build/dts/wixel/wixel-session-tools.d.ts +21 -26
  83. package/build/dts/wixel/wixel-session-tools.js +494 -599
  84. package/build/esm/index.js +3422 -1388
  85. package/build/esm/toolkit.js +2158 -373
  86. package/package.json +4 -4
@@ -19,6 +19,7 @@ interface ToolBiParams {
19
19
  assetId?: string;
20
20
  returnedRows?: number;
21
21
  originalLength?: number;
22
+ upload?: object;
22
23
  }
23
24
  type WixRequestHandlerExtra = RequestHandlerExtra<any, any> & {
24
25
  logger: Logger;
@@ -48,13 +49,21 @@ export declare class WixMcpServer extends McpServer {
48
49
  private gptAppSchemesEnabled;
49
50
  private openAiMcpAppsEnabled;
50
51
  private mcpAppsInMcpEnabled;
52
+ private registeredTools;
51
53
  constructor(serverInfo: Implementation, options?: ServerOptions, context?: WixMcpServerContext | undefined);
52
54
  setUserIdGetter(getUserId: () => string | undefined): void;
53
55
  getSessionId(): string;
54
- /** The connected client's name: the host's getter (User-Agent fallback) first, then clientInfo. */
56
+ /** The connected client's name: the host's getter (initialize name, then User-Agent) first, then clientInfo. */
55
57
  clientName(): string | undefined;
56
58
  setClientNameGetter(getClientName: () => string | undefined): void;
57
59
  setUserAgentGetter(getUserAgent: () => string | undefined): void;
60
+ /** True when every named tool is registered and enabled in this session. */
61
+ hasTools(...names: string[]): boolean;
62
+ /**
63
+ * Sets the `instructions` the server returns at initialize. Call it before the transport
64
+ * connects. The SDK keeps them on the low-level server and has no setter for them.
65
+ */
66
+ setInstructions(instructions: string | undefined): void;
58
67
  setGptAppSchemesEnabled(enabled: boolean): void;
59
68
  isGptAppSchemesEnabled(): boolean;
60
69
  setOpenAiMcpAppsEnabled(enabled: boolean): void;
@@ -8,6 +8,7 @@ import { DEV_ENVIRONMENTS, getEnvironment } from './infra/environment.js';
8
8
  import { HttpClient } from '@wix/http-client';
9
9
  import { logger } from './infra/logger.js';
10
10
  import { createToolBiEvent, extractText, formatToolResultAdditionalFields } from './infra/tool-bi.js';
11
+ import { serializeToolParamsForBi } from './infra/redact-personal-data.js';
11
12
  export class WixMcpServer extends McpServer {
12
13
  serverInfo;
13
14
  context;
@@ -22,6 +23,7 @@ export class WixMcpServer extends McpServer {
22
23
  gptAppSchemesEnabled = false;
23
24
  openAiMcpAppsEnabled = false;
24
25
  mcpAppsInMcpEnabled = true;
26
+ registeredTools = new Map();
25
27
  constructor(serverInfo, options, context) {
26
28
  super(serverInfo, options);
27
29
  this.serverInfo = serverInfo;
@@ -39,7 +41,7 @@ export class WixMcpServer extends McpServer {
39
41
  getSessionId() {
40
42
  return this.sessionId;
41
43
  }
42
- /** The connected client's name: the host's getter (User-Agent fallback) first, then clientInfo. */
44
+ /** The connected client's name: the host's getter (initialize name, then User-Agent) first, then clientInfo. */
43
45
  clientName() {
44
46
  return this.getClientName?.() ?? this.server.getClientVersion()?.name;
45
47
  }
@@ -49,6 +51,18 @@ export class WixMcpServer extends McpServer {
49
51
  setUserAgentGetter(getUserAgent) {
50
52
  this.getUserAgent = getUserAgent;
51
53
  }
54
+ /** True when every named tool is registered and enabled in this session. */
55
+ hasTools(...names) {
56
+ return names.every((name) => this.registeredTools.get(name)?.enabled);
57
+ }
58
+ /**
59
+ * Sets the `instructions` the server returns at initialize. Call it before the transport
60
+ * connects. The SDK keeps them on the low-level server and has no setter for them.
61
+ */
62
+ setInstructions(instructions) {
63
+ this.server._instructions =
64
+ instructions;
65
+ }
52
66
  setGptAppSchemesEnabled(enabled) {
53
67
  this.gptAppSchemesEnabled = enabled;
54
68
  }
@@ -105,6 +119,7 @@ export class WixMcpServer extends McpServer {
105
119
  args[cbIndex] = this.wrapToolCallback(toolName, originalCb);
106
120
  }
107
121
  const registeredTool = super.tool.apply(this, args);
122
+ this.registeredTools.set(args[0], registeredTool);
108
123
  if (this.isGptAppSchemesEnabled() &&
109
124
  !registeredTool._meta?.securitySchemes) {
110
125
  registeredTool.update({
@@ -127,7 +142,9 @@ export class WixMcpServer extends McpServer {
127
142
  };
128
143
  }
129
144
  const wrappedCb = this.wrapToolCallback(name, cb);
130
- return super.registerTool(name, config, wrappedCb);
145
+ const registeredTool = super.registerTool(name, config, wrappedCb);
146
+ this.registeredTools.set(name, registeredTool);
147
+ return registeredTool;
131
148
  }
132
149
  wrapToolCallback(toolName, originalCb) {
133
150
  const isDevEnvironment = DEV_ENVIRONMENTS.includes(this.nodeEnv);
@@ -170,7 +187,7 @@ export class WixMcpServer extends McpServer {
170
187
  });
171
188
  panorama.transaction(toolName).start({
172
189
  toolInvocationId,
173
- params: JSON.stringify(argsBeforeExtra)
190
+ params: serializeToolParamsForBi(argsBeforeExtra)
174
191
  });
175
192
  }
176
193
  const startTime = performance.now();
@@ -186,7 +203,8 @@ export class WixMcpServer extends McpServer {
186
203
  else {
187
204
  additionalFields = formatToolResultAdditionalFields(cbResult, {
188
205
  returnedRows: toolBiParams.returnedRows,
189
- originalLength: toolBiParams.originalLength
206
+ originalLength: toolBiParams.originalLength,
207
+ upload: toolBiParams.upload
190
208
  }, {
191
209
  name: this.getClientName?.() || this.server.getClientVersion()?.name,
192
210
  userAgent: this.getUserAgent?.()
@@ -202,7 +220,7 @@ export class WixMcpServer extends McpServer {
202
220
  context: {
203
221
  toolName,
204
222
  toolInvocationId,
205
- params: JSON.stringify(argsBeforeExtra),
223
+ params: serializeToolParamsForBi(argsBeforeExtra),
206
224
  error: JSON.stringify(cbResult, null, 2)
207
225
  }
208
226
  });
@@ -217,7 +235,7 @@ export class WixMcpServer extends McpServer {
217
235
  context: {
218
236
  toolName,
219
237
  toolInvocationId,
220
- params: JSON.stringify(argsBeforeExtra),
238
+ params: serializeToolParamsForBi(argsBeforeExtra),
221
239
  error: errorBody
222
240
  }
223
241
  });
@@ -268,7 +286,7 @@ export class WixMcpServer extends McpServer {
268
286
  errorBody,
269
287
  toolInvocationId,
270
288
  toolName,
271
- params: JSON.stringify(argsBeforeExtra),
289
+ params: serializeToolParamsForBi(argsBeforeExtra),
272
290
  origin: this.nodeEnv,
273
291
  sessionId: this.sessionId,
274
292
  executionResult: toolSucceeded ? 'Success' : 'Error',
@@ -1,7 +1,14 @@
1
1
  export declare const WIXEL_ASSISTANT_V1_NO_ENTITY_API_BASE_URL = "https://manage.wix.com/";
2
2
  export declare const WWW_ASSET_V1_ASSET_API_BASE_URL = "https://manage.wix.com/";
3
3
  export { OPENAI_WIDGET_MIME_TYPE } from '../site-widget-tools/constants.js';
4
- export declare const WIXEL_AGENT_EXTERNAL_API_BASE_URL = "https://manage.wix.com/";
4
+ /** Base for the Wixel agent's A2aService ambassador package. Host only: on a
5
+ * Wix host the package's request paths already start with the service mount
6
+ * (`/_api/wixel-agent-server/v1/a2a/...`), so a base that repeated the mount
7
+ * would double it and every call would 404. manage.wix.com, not bo.wix.com:
8
+ * the MCP server runs outside the Wix network. */
9
+ export declare const WIXEL_AGENT_A2A_API_BASE_URL = "https://manage.wix.com/";
10
+ /** Base of the Wixel agent's internal sessions API (entries log, listing). */
11
+ export declare const WIXEL_AGENT_SESSIONS_API_BASE_URL = "https://manage.wix.com/";
5
12
  export declare const WIXEL_WIDGET_URI = "ui://widget/wixel-widget.html";
6
13
  /** PNG first: clients only have to support png/jpeg, and take the first icon
7
14
  * they can render. */
@@ -1,7 +1,14 @@
1
1
  export const WIXEL_ASSISTANT_V1_NO_ENTITY_API_BASE_URL = 'https://manage.wix.com/';
2
2
  export const WWW_ASSET_V1_ASSET_API_BASE_URL = 'https://manage.wix.com/';
3
3
  export { OPENAI_WIDGET_MIME_TYPE } from '../site-widget-tools/constants.js';
4
- export const WIXEL_AGENT_EXTERNAL_API_BASE_URL = 'https://manage.wix.com/';
4
+ /** Base for the Wixel agent's A2aService ambassador package. Host only: on a
5
+ * Wix host the package's request paths already start with the service mount
6
+ * (`/_api/wixel-agent-server/v1/a2a/...`), so a base that repeated the mount
7
+ * would double it and every call would 404. manage.wix.com, not bo.wix.com:
8
+ * the MCP server runs outside the Wix network. */
9
+ export const WIXEL_AGENT_A2A_API_BASE_URL = 'https://manage.wix.com/';
10
+ /** Base of the Wixel agent's internal sessions API (entries log, listing). */
11
+ export const WIXEL_AGENT_SESSIONS_API_BASE_URL = 'https://manage.wix.com/';
5
12
  export const WIXEL_WIDGET_URI = 'ui://widget/wixel-widget.html';
6
13
  /** PNG first: clients only have to support png/jpeg, and take the first icon
7
14
  * they can render. */
@@ -1,7 +1,7 @@
1
1
  import { McpAuthenticationStrategy } from '../auth/index.js';
2
2
  import { WixMcpServer } from '../wix-mcp-server.js';
3
3
  export { WIXEL_ICON_SVG_URL, WIXEL_ICON_PNG_URL } from './constants.js';
4
- export { addWixelSessionTools, addStartWixelSessionTool, addSendWixelMessageTool, addListWixelEventsTool } from './wixel-session-tools.js';
4
+ export { addWixelSessionTools, addSendWixelMessageTool, addGetWixelTaskTool } from './wixel-session-tools.js';
5
5
  export { addGetWixelJobStatusTool } from './get-wixel-job-status-tool.js';
6
6
  export { addMarkWixelJobAsFulfilledTool } from './mark-wixel-job-as-fulfilled-tool.js';
7
7
  export { addGetWixelAssetTool } from './get-wixel-asset-tool.js';
@@ -4,7 +4,7 @@ import { addGetWixelAssetTool } from './get-wixel-asset-tool.js';
4
4
  import { addGetWixelProjectAssetsTool } from './get-wixel-project-assets-tool.js';
5
5
  import { addWixelSessionTools } from './wixel-session-tools.js';
6
6
  export { WIXEL_ICON_SVG_URL, WIXEL_ICON_PNG_URL } from './constants.js';
7
- export { addWixelSessionTools, addStartWixelSessionTool, addSendWixelMessageTool, addListWixelEventsTool } from './wixel-session-tools.js';
7
+ export { addWixelSessionTools, addSendWixelMessageTool, addGetWixelTaskTool } from './wixel-session-tools.js';
8
8
  export { addGetWixelJobStatusTool } from './get-wixel-job-status-tool.js';
9
9
  export { addMarkWixelJobAsFulfilledTool } from './mark-wixel-job-as-fulfilled-tool.js';
10
10
  export { addGetWixelAssetTool } from './get-wixel-asset-tool.js';
@@ -14,7 +14,7 @@ export function addWixelTools(server, authStrategy, options = {}) {
14
14
  addMarkWixelJobAsFulfilledTool(server, authStrategy, options);
15
15
  addGetWixelAssetTool(server, authStrategy, options);
16
16
  addGetWixelProjectAssetsTool(server, authStrategy, options);
17
- // Agent-to-agent session API (wixel-agent-service ExternalAgentService)
17
+ // Conversation tools over the Wixel agent's A2A endpoint
18
18
  addWixelSessionTools(server, authStrategy, options);
19
19
  }
20
20
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,83 @@
1
+ import { TaskState, type Task } from '@wix/ambassador-www-wixel-agent-v1-agent-to-agent/types';
2
+ /** The agent rejects longer message text. */
3
+ export declare const WIXEL_MESSAGE_MAX_LENGTH = 32000;
4
+ /** The media type of the artifact part that lists the generated asset ids. */
5
+ export declare const WIXEL_ASSETS_MEDIA_TYPE = "application/vnd.wixel.assets+json";
6
+ export { TaskState };
7
+ /** A task as the service always returns it: with its id and contextId. */
8
+ export type WixelTask = Task & {
9
+ id: string;
10
+ contextId: string;
11
+ };
12
+ /** A failed A2aService call: the HTTP status and the service's message. */
13
+ export declare class WixelA2AError extends Error {
14
+ readonly status: number | null;
15
+ constructor(status: number | null, message: string);
16
+ }
17
+ interface BaseOptions {
18
+ authHeaders: Record<string, string>;
19
+ conductorOverride?: string;
20
+ /** Override for tests and local runs. Host only — see
21
+ * WIXEL_AGENT_A2A_API_BASE_URL. */
22
+ apiBaseURL?: string;
23
+ }
24
+ export interface SendWixelMessageOptions extends BaseOptions {
25
+ text: string;
26
+ /** The conversation to add a turn to; omit to start a new one. */
27
+ contextId?: string;
28
+ /** Reuse this site's Wixel project when starting a conversation. */
29
+ metaSiteId?: string;
30
+ /** Stable identifier of the caller's conversation (diagnostics only). */
31
+ externalId?: string;
32
+ /** Doubles as the turn's transaction id, so a retry with the same id is
33
+ * one turn. Defaults to a fresh uuid per call. */
34
+ messageId?: string;
35
+ }
36
+ /**
37
+ * A2A SendMessage. Without a contextId the agent provisions a project (or
38
+ * reuses `metaSiteId`'s) and starts a session; with one it adds a turn. When a
39
+ * turn is still running the message steers it instead, and the running task
40
+ * comes back WORKING with `metadata.steered`.
41
+ */
42
+ export declare function sendWixelMessage({ text, contextId, metaSiteId, externalId, messageId, ...base }: SendWixelMessageOptions): Promise<WixelTask>;
43
+ export interface GetWixelTaskOptions extends BaseOptions {
44
+ taskId: string;
45
+ }
46
+ /** A2A GetTask: the turn's current state, reply and artifacts. */
47
+ export declare function getWixelTask({ taskId, ...base }: GetWixelTaskOptions): Promise<WixelTask>;
48
+ export declare function isTerminalTaskState(state: string | undefined): boolean;
49
+ export declare function extractMediaUrls(text: string): string[];
50
+ /**
51
+ * A text that ends by asking the user something (a plan to approve, a choice
52
+ * to make) is not a delivery even when it links media — an animation plan
53
+ * links the source image it will animate. Asset ids only come with real
54
+ * deliveries; media URLs alone need this check.
55
+ */
56
+ export declare function isQuestionReply(text: string): boolean;
57
+ export interface WixelTaskSummary {
58
+ state: TaskState;
59
+ /** The turn has ended (completed, failed, canceled or rejected). */
60
+ done: boolean;
61
+ /** The agent's reply (completed) or failure reason, as text. */
62
+ replyText: string | null;
63
+ /** Generated asset ids, from the artifacts' wixel-assets parts. */
64
+ assetIds: string[];
65
+ /** Wix media URLs named in the artifacts' text — not counting an artifact
66
+ * that asks the user something (see isQuestionReply). */
67
+ mediaUrls: string[];
68
+ contextId: string;
69
+ taskId: string;
70
+ sessionId: string | null;
71
+ metaSiteId: string | null;
72
+ turnId: string | null;
73
+ /** The message was steered into a turn that was already running. */
74
+ steered: boolean;
75
+ }
76
+ /**
77
+ * What a task means to the tools. Asset ids are read from the artifacts'
78
+ * `wixel-assets` data parts (one artifact per mid-turn deliverable plus the
79
+ * final `response`); media URLs still come from the text. A turn delivered
80
+ * something when either list is non-empty.
81
+ */
82
+ export declare function summarizeTask(task: WixelTask): WixelTaskSummary;
83
+ //# sourceMappingURL=wixel-a2a-client.d.ts.map
@@ -0,0 +1,166 @@
1
+ import { createHttpClient, HttpError } from '@wix/http-client';
2
+ import { getTask, sendMessage } from '@wix/ambassador-www-wixel-agent-v1-agent-to-agent/http';
3
+ import { Role, TaskState } from '@wix/ambassador-www-wixel-agent-v1-agent-to-agent/types';
4
+ import { WIXEL_AGENT_A2A_API_BASE_URL } from './constants.js';
5
+ // Client for the Wixel agent's A2aService (wixel-agent-service), through its
6
+ // ambassador package. SendMessage starts a session or adds a turn to one, and
7
+ // returns the turn as a task; GetTask reads that task back. Both ids it hands
8
+ // out — contextId (the conversation) and taskId (one turn) — are opaque:
9
+ // never decode them. The session, site and turn come from task.metadata.
10
+ const CONDUCTOR_OVERRIDE_HEADERS = {
11
+ Cookie: 'petri_ovr=specs.wixel-slides.enableInWixel#true|specs.wixel-assistant.sidePanelEnabled#true|creditTransactionsPremiumIntegration#A'
12
+ };
13
+ /** Shown to the agent as who is talking to it. */
14
+ const CALLER_NAME = 'Wix MCP';
15
+ /** The agent rejects longer message text. */
16
+ export const WIXEL_MESSAGE_MAX_LENGTH = 32000;
17
+ /** The media type of the artifact part that lists the generated asset ids. */
18
+ export const WIXEL_ASSETS_MEDIA_TYPE = 'application/vnd.wixel.assets+json';
19
+ export { TaskState };
20
+ const TERMINAL_STATES = new Set([
21
+ TaskState.TASK_STATE_COMPLETED,
22
+ TaskState.TASK_STATE_FAILED,
23
+ TaskState.TASK_STATE_CANCELED,
24
+ TaskState.TASK_STATE_REJECTED
25
+ ]);
26
+ /** A failed A2aService call: the HTTP status and the service's message. */
27
+ export class WixelA2AError extends Error {
28
+ status;
29
+ constructor(status, message) {
30
+ super(message);
31
+ this.status = status;
32
+ this.name = 'WixelA2AError';
33
+ }
34
+ }
35
+ function httpClientFor({ authHeaders, conductorOverride, apiBaseURL = WIXEL_AGENT_A2A_API_BASE_URL }) {
36
+ return createHttpClient({
37
+ headers: {
38
+ ...authHeaders,
39
+ ...(conductorOverride ? { ...CONDUCTOR_OVERRIDE_HEADERS } : {})
40
+ },
41
+ baseURL: apiBaseURL
42
+ });
43
+ }
44
+ function requireTask(task, what) {
45
+ if (!task?.id || !task.contextId) {
46
+ throw new WixelA2AError(null, `Wixel returned no task ${what}`);
47
+ }
48
+ return { ...task, id: task.id, contextId: task.contextId };
49
+ }
50
+ function toWixelA2AError(error) {
51
+ if (!(error instanceof HttpError))
52
+ return error;
53
+ const data = error.response?.data;
54
+ const message = typeof data?.message === 'string' && data.message
55
+ ? data.message
56
+ : error.message;
57
+ return new WixelA2AError(error.response?.status ?? null, message);
58
+ }
59
+ /**
60
+ * A2A SendMessage. Without a contextId the agent provisions a project (or
61
+ * reuses `metaSiteId`'s) and starts a session; with one it adds a turn. When a
62
+ * turn is still running the message steers it instead, and the running task
63
+ * comes back WORKING with `metadata.steered`.
64
+ */
65
+ export async function sendWixelMessage({ text, contextId, metaSiteId, externalId, messageId = crypto.randomUUID(), ...base }) {
66
+ try {
67
+ const { data } = await httpClientFor(base).request(sendMessage({
68
+ message: {
69
+ messageId,
70
+ role: Role.ROLE_USER,
71
+ parts: [{ text }],
72
+ ...(contextId ? { contextId } : {})
73
+ },
74
+ metadata: {
75
+ callerName: CALLER_NAME,
76
+ ...(externalId ? { externalId } : {}),
77
+ // A conversation is already bound to its site; the hint only
78
+ // matters when one is being started.
79
+ ...(metaSiteId && !contextId ? { metaSiteId } : {})
80
+ }
81
+ }));
82
+ return requireTask(data.task, 'for the message');
83
+ }
84
+ catch (error) {
85
+ throw toWixelA2AError(error);
86
+ }
87
+ }
88
+ /** A2A GetTask: the turn's current state, reply and artifacts. */
89
+ export async function getWixelTask({ taskId, ...base }) {
90
+ try {
91
+ const { data } = await httpClientFor(base).request(getTask({ id: taskId }));
92
+ return requireTask(data.task, `for ${taskId}`);
93
+ }
94
+ catch (error) {
95
+ throw toWixelA2AError(error);
96
+ }
97
+ }
98
+ export function isTerminalTaskState(state) {
99
+ return !!state && TERMINAL_STATES.has(state);
100
+ }
101
+ // Image/video replies often carry no asset id — just the media URL in the
102
+ // text: a wixstatic file, a wixmp render (img-wixmp-*/wixmp-* hosts), or a
103
+ // links.wixel.com short link that redirects to one. Those links are the
104
+ // deliverable too. Keep the hosts in step with the result resolver's
105
+ // allowlist, or a URL it would accept never gets extracted in the first place.
106
+ export function extractMediaUrls(text) {
107
+ const matches = text.match(/https:\/\/(?:(?:static|video)\.wixstatic\.com|[a-z0-9-]+\.wixmp\.com|links\.wixel\.com\/link)\/[^\s)\]"'<>]+/g);
108
+ return matches ? Array.from(new Set(matches)) : [];
109
+ }
110
+ /**
111
+ * A text that ends by asking the user something (a plan to approve, a choice
112
+ * to make) is not a delivery even when it links media — an animation plan
113
+ * links the source image it will animate. Asset ids only come with real
114
+ * deliveries; media URLs alone need this check.
115
+ */
116
+ export function isQuestionReply(text) {
117
+ return /\?\s*$/.test(text.trim());
118
+ }
119
+ function partsText(parts) {
120
+ return (parts ?? [])
121
+ .map((part) => (typeof part.text === 'string' ? part.text : ''))
122
+ .filter(Boolean)
123
+ .join('\n');
124
+ }
125
+ function partsAssetIds(parts) {
126
+ return (parts ?? []).flatMap((part) => {
127
+ if (part.mediaType !== WIXEL_ASSETS_MEDIA_TYPE)
128
+ return [];
129
+ const ids = part.data?.assetIds;
130
+ return Array.isArray(ids)
131
+ ? ids.filter((id) => typeof id === 'string' && !!id)
132
+ : [];
133
+ });
134
+ }
135
+ /**
136
+ * What a task means to the tools. Asset ids are read from the artifacts'
137
+ * `wixel-assets` data parts (one artifact per mid-turn deliverable plus the
138
+ * final `response`); media URLs still come from the text. A turn delivered
139
+ * something when either list is non-empty.
140
+ */
141
+ export function summarizeTask(task) {
142
+ const artifacts = task.artifacts ?? [];
143
+ const artifactText = artifacts
144
+ .map((artifact) => partsText(artifact.parts))
145
+ .filter(Boolean);
146
+ const statusText = partsText(task.status?.message?.parts);
147
+ const replyText = statusText || artifactText.at(-1) || null;
148
+ const metadata = task.metadata ?? {};
149
+ const state = task.status?.state ?? TaskState.TASK_STATE_UNSPECIFIED;
150
+ return {
151
+ state,
152
+ done: isTerminalTaskState(state),
153
+ replyText,
154
+ assetIds: Array.from(new Set(artifacts.flatMap((artifact) => partsAssetIds(artifact.parts)))),
155
+ mediaUrls: Array.from(new Set(artifactText
156
+ .filter((text) => !isQuestionReply(text))
157
+ .flatMap(extractMediaUrls))),
158
+ contextId: task.contextId,
159
+ taskId: task.id,
160
+ sessionId: typeof metadata.sessionId === 'string' ? metadata.sessionId : null,
161
+ metaSiteId: typeof metadata.metaSiteId === 'string' ? metadata.metaSiteId : null,
162
+ turnId: typeof metadata.turnId === 'string' ? metadata.turnId : null,
163
+ steered: metadata.steered === true
164
+ };
165
+ }
166
+ //# sourceMappingURL=wixel-a2a-client.js.map
@@ -12,7 +12,8 @@ export interface WixelToolBiParams {
12
12
  * registerAppTool types its extra as the bare SDK one; wrapToolCallback
13
13
  * injects both of these at runtime, hence the cast and the no-ops in tests.
14
14
  *
15
- * The handle goes on as a logger default because wrapToolCallback doesn't pass
15
+ * The Wixel session id (from the A2A task's metadata — never the opaque
16
+ * contextId) goes on as a logger default because wrapToolCallback doesn't pass
16
17
  * ai_conversation_id — the wrapper merges defaults into the event it reports
17
18
  * for this same invocation. The field is typed as a GUID.
18
19
  */
@@ -5,7 +5,8 @@ import { isValidUuid } from './utils.js';
5
5
  * registerAppTool types its extra as the bare SDK one; wrapToolCallback
6
6
  * injects both of these at runtime, hence the cast and the no-ops in tests.
7
7
  *
8
- * The handle goes on as a logger default because wrapToolCallback doesn't pass
8
+ * The Wixel session id (from the A2A task's metadata — never the opaque
9
+ * contextId) goes on as a logger default because wrapToolCallback doesn't pass
9
10
  * ai_conversation_id — the wrapper merges defaults into the event it reports
10
11
  * for this same invocation. The field is typed as a GUID.
11
12
  */
@@ -1,35 +1,8 @@
1
- import { InboxHistoryMode, ProjectWorkspace, type ListEventsResponse, type SendMessageResponse, type StartSessionResponse } from '@wix/ambassador-www-wixel-agent-v1-external-agent/types';
2
- export { InboxHistoryMode, ProjectWorkspace };
3
- export type { ListEventsResponse, SendMessageResponse, StartSessionResponse };
4
1
  interface BaseOptions {
5
2
  authHeaders: Record<string, string>;
6
3
  apiBaseURL?: string;
7
4
  conductorOverride?: string;
8
5
  }
9
- export interface StartWixelSessionOptions extends BaseOptions {
10
- sessionId?: string;
11
- metaSiteId?: string;
12
- callerName?: string;
13
- externalId?: string;
14
- workspace?: ProjectWorkspace;
15
- callbackUrl?: string;
16
- callbackToken?: string;
17
- }
18
- export declare function startWixelSession({ sessionId, metaSiteId, callerName, externalId, workspace, callbackUrl, callbackToken, ...base }: StartWixelSessionOptions): Promise<StartSessionResponse>;
19
- export interface SendWixelSessionMessageOptions extends BaseOptions {
20
- handle: string;
21
- metaSiteId: string;
22
- text: string;
23
- transactionId?: string;
24
- }
25
- export declare function sendWixelSessionMessage({ handle, metaSiteId, text, transactionId, ...base }: SendWixelSessionMessageOptions): Promise<SendMessageResponse>;
26
- export interface ListWixelSessionEventsOptions extends BaseOptions {
27
- handle: string;
28
- metaSiteId: string;
29
- since?: string;
30
- historyMode?: InboxHistoryMode;
31
- }
32
- export declare function listWixelSessionEvents({ handle, metaSiteId, since, historyMode, ...base }: ListWixelSessionEventsOptions): Promise<ListEventsResponse>;
33
6
  export interface GetSessionEntriesOptions extends BaseOptions {
34
7
  sessionId: string;
35
8
  }
@@ -82,18 +55,23 @@ export interface WixelSessionActivity {
82
55
  /** Unanswered ask_user the turn is suspended on (nothing will generate
83
56
  * until the user answers). */
84
57
  parkedQuestion: WixelPendingQuestion | null;
85
- /** A turn is actively generating — a reply/failed event will arrive. */
58
+ /** A turn is actively generating — its task will reach a terminal state. */
86
59
  turnInProgress: boolean;
87
60
  }
88
61
  /**
89
62
  * Classify the session's current state from the durable entries log with a
90
63
  * single read: parked on an ask_user question, actively generating, or idle.
91
- * Empty inbox polls use this to tell callers whether to keep waiting (turn
92
- * running) or to turn to the user (parked question) — an empty inbox alone
93
- * cannot distinguish the two.
64
+ * A task still WORKING uses this to tell callers whether to keep waiting
65
+ * (turn running) or to turn to the user (parked question) — the task state
66
+ * alone cannot distinguish the two.
94
67
  */
95
68
  export declare function getWixelSessionActivity({ sessionId, ...base }: GetSessionEntriesOptions): Promise<WixelSessionActivity>;
96
- export declare function getWixelPendingQuestion({ sessionId, requireParked, ...base }: GetSessionEntriesOptions & {
69
+ export declare function getWixelPendingQuestion({ sessionId, requireParked, turnId, ...base }: GetSessionEntriesOptions & {
97
70
  requireParked?: boolean;
71
+ /** The asking task's turn. A question another turn of the session asked —
72
+ * a newer task's — is not this task's to show. Applied only when the turn
73
+ * is in the log: a task spanning background turns carries a minted key. */
74
+ turnId?: string | null;
98
75
  }): Promise<WixelPendingQuestion | null>;
99
- //# sourceMappingURL=external-agent-api.d.ts.map
76
+ export {};
77
+ //# sourceMappingURL=wixel-session-entries.d.ts.map