@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.
- package/README.md +2 -2
- package/build/bin-standalone.js +1457 -332
- package/build/cjs/index.cjs +3379 -1333
- package/build/cjs/toolkit.cjs +2158 -373
- package/build/dts/api-call/headless-release.d.ts +56 -0
- package/build/dts/api-call/headless-release.js +135 -0
- package/build/dts/api-call/index.d.ts +9 -1
- package/build/dts/api-call/index.js +36 -8
- package/build/dts/api-call/site-files.d.ts +14 -0
- package/build/dts/api-call/site-files.js +106 -10
- package/build/dts/api-call/upload-headless-website-files.d.ts +117 -5
- package/build/dts/api-call/upload-headless-website-files.js +565 -20
- package/build/dts/api-call/upload-image-tool.d.ts +2 -0
- package/build/dts/api-call/upload-image-tool.js +8 -4
- package/build/dts/bin.d.ts +1 -1
- package/build/dts/bin.js +3 -1
- package/build/dts/code-mode/attachments.d.ts +9 -6
- package/build/dts/code-mode/attachments.js +23 -16
- package/build/dts/code-mode/index.d.ts +6 -1
- package/build/dts/code-mode/index.js +32 -12
- package/build/dts/code-mode/truncate-response.js +5 -1
- package/build/dts/config/default-config.d.ts +35 -5
- package/build/dts/config/default-config.js +339 -182
- package/build/dts/config/file-params.d.ts +22 -0
- package/build/dts/config/file-params.js +24 -0
- package/build/dts/config/param-descriptions.d.ts +14 -2
- package/build/dts/config/param-descriptions.js +33 -14
- package/build/dts/constants.d.ts +1 -0
- package/build/dts/constants.js +1 -0
- package/build/dts/docs/docs.d.ts +12 -1
- package/build/dts/docs/docs.js +274 -43
- package/build/dts/docs/fetch-article.d.ts +21 -0
- package/build/dts/docs/fetch-article.js +66 -4
- package/build/dts/docs/get-to-know.d.ts +7 -2
- package/build/dts/docs/get-to-know.js +36 -14
- package/build/dts/docs/guessed-url.d.ts +41 -0
- package/build/dts/docs/guessed-url.js +185 -0
- package/build/dts/docs/mintlify-docs.d.ts +121 -0
- package/build/dts/docs/mintlify-docs.js +391 -0
- package/build/dts/docs/semanticSearch.d.ts +2 -1
- package/build/dts/docs/semanticSearch.js +14 -7
- package/build/dts/docs/start-deploy-website.d.ts +7 -6
- package/build/dts/docs/start-deploy-website.js +13 -8
- package/build/dts/docs/start-headless-build.d.ts +8 -10
- package/build/dts/docs/start-headless-build.js +14 -28
- package/build/dts/index.d.ts +2 -2
- package/build/dts/index.js +2 -2
- package/build/dts/infra/redact-personal-data.d.ts +4 -0
- package/build/dts/infra/redact-personal-data.js +148 -0
- package/build/dts/site-widget-tools/constants.d.ts +50 -2
- package/build/dts/site-widget-tools/constants.js +65 -8
- package/build/dts/site-widget-tools/index.d.ts +1 -0
- package/build/dts/site-widget-tools/index.js +1 -0
- package/build/dts/site-widget-tools/pick-images-tool/index.d.ts +14 -0
- package/build/dts/site-widget-tools/pick-images-tool/index.js +138 -0
- package/build/dts/site-widget-tools/pull-site-creation-job-tool/index.js +1 -1
- package/build/dts/site-widget-tools/search-site-templates-tool/index.js +25 -2
- package/build/dts/site-widget-tools/site-builder-tool/index.js +35 -3
- package/build/dts/site-widget-tools/site-creation-tool/index.d.ts +7 -1
- package/build/dts/site-widget-tools/site-creation-tool/index.js +22 -51
- package/build/dts/site-widget-tools/suggested-domain-tool/index.js +26 -12
- package/build/dts/support/index.d.ts +4 -0
- package/build/dts/support/index.js +13 -7
- package/build/dts/tool-utils.d.ts +8 -1
- package/build/dts/tool-utils.js +26 -2
- package/build/dts/toolkit-entry.d.cts +15 -10
- package/build/dts/toolkit-entry.d.ts +15 -10
- package/build/dts/toolkit.d.ts +2 -2
- package/build/dts/toolkit.js +21 -8
- package/build/dts/wix-mcp-server.d.ts +10 -1
- package/build/dts/wix-mcp-server.js +25 -7
- package/build/dts/wixel/constants.d.ts +8 -1
- package/build/dts/wixel/constants.js +8 -1
- package/build/dts/wixel/index.d.ts +1 -1
- package/build/dts/wixel/index.js +2 -2
- package/build/dts/wixel/wixel-a2a-client.d.ts +83 -0
- package/build/dts/wixel/wixel-a2a-client.js +166 -0
- package/build/dts/wixel/wixel-bi.d.ts +2 -1
- package/build/dts/wixel/wixel-bi.js +2 -1
- package/build/dts/wixel/{external-agent-api.d.ts → wixel-session-entries.d.ts} +11 -33
- package/build/dts/wixel/{external-agent-api.js → wixel-session-entries.js} +33 -54
- package/build/dts/wixel/wixel-session-tools.d.ts +21 -26
- package/build/dts/wixel/wixel-session-tools.js +494 -599
- package/build/esm/index.js +3422 -1388
- package/build/esm/toolkit.js +2158 -373
- 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
|
|
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
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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';
|
package/build/dts/wixel/index.js
CHANGED
|
@@ -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,
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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 —
|
|
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
|
-
*
|
|
92
|
-
* running) or to turn to the user (parked question) —
|
|
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
|
-
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=wixel-session-entries.d.ts.map
|