@wix/himalaya-cli 0.1030.0 → 0.1032.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.
Files changed (124) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/app-config.d.ts +7 -0
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/wix-gateway.d.ts +32 -0
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/wix-gateway.rules.d.ts +2 -1
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +7 -0
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/genie-chat/src/index.d.ts +64 -0
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-genie-chat.mjs +41 -1
  7. package/dist/cli.mjs +386 -132
  8. package/dist/preview-assets.generated.bin +0 -0
  9. package/guides/mobile-ux.md +3 -2
  10. package/guides/qa-builds.md +22 -13
  11. package/guides/sdk-reference.json +50 -2
  12. package/package.json +2 -2
  13. package/templates/beauty-salon/tier5-src/_shared/owner-load-error.ts +7 -1
  14. package/templates/beauty-salon-owner/config.ts +1 -1
  15. package/templates/beauty-salon-owner/dev/index.ts +247 -9
  16. package/templates/beauty-salon-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  17. package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +405 -20
  18. package/templates/beauty-salon-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  19. package/templates/beauty-salon-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  20. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  21. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  22. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  23. package/templates/branded-lite/tier5-src/_shared/owner-load-error.ts +7 -1
  24. package/templates/community-club/tier5-src/_shared/owner-load-error.ts +7 -1
  25. package/templates/community-club-owner/config.ts +1 -1
  26. package/templates/community-club-owner/dev/index.ts +247 -9
  27. package/templates/community-club-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  28. package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +405 -20
  29. package/templates/community-club-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  30. package/templates/community-club-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  31. package/templates/community-club-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  32. package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  33. package/templates/community-club-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  34. package/templates/events-meetups/tier5-src/_shared/owner-load-error.ts +7 -1
  35. package/templates/events-meetups-owner/config.ts +1 -1
  36. package/templates/events-meetups-owner/dev/index.ts +247 -9
  37. package/templates/events-meetups-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  38. package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +405 -20
  39. package/templates/events-meetups-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  40. package/templates/events-meetups-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  41. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  42. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  43. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  44. package/templates/gym-fitness/tier5-src/_shared/owner-load-error.ts +7 -1
  45. package/templates/gym-fitness-owner/config.ts +1 -1
  46. package/templates/gym-fitness-owner/dev/index.ts +247 -9
  47. package/templates/gym-fitness-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  48. package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +405 -20
  49. package/templates/gym-fitness-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  50. package/templates/gym-fitness-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  51. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  52. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  53. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  54. package/templates/himi-chat/tier5-src/_shared/owner-load-error.ts +7 -1
  55. package/templates/nonprofit-cause/tier5-src/_shared/owner-load-error.ts +7 -1
  56. package/templates/nonprofit-cause-owner/config.ts +1 -1
  57. package/templates/nonprofit-cause-owner/dev/index.ts +247 -9
  58. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  59. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +405 -20
  60. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  61. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  62. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  63. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  64. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  65. package/templates/owner-lite/config.ts +1 -1
  66. package/templates/owner-lite/dev/index.ts +247 -9
  67. package/templates/owner-lite/tier5-src/_shared/aria-attachments.ts +179 -0
  68. package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +405 -20
  69. package/templates/owner-lite/tier5-src/_shared/owner-bookings.ts +20 -0
  70. package/templates/owner-lite/tier5-src/_shared/owner-load-error.ts +7 -1
  71. package/templates/owner-lite/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  72. package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +2 -12
  73. package/templates/owner-lite/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  74. package/templates/podcast-creator/tier5-src/_shared/owner-load-error.ts +7 -1
  75. package/templates/podcast-creator-owner/config.ts +1 -1
  76. package/templates/podcast-creator-owner/dev/index.ts +247 -9
  77. package/templates/podcast-creator-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  78. package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +405 -20
  79. package/templates/podcast-creator-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  80. package/templates/podcast-creator-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  81. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  82. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  83. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  84. package/templates/portfolio-creative/tier5-src/_shared/owner-load-error.ts +7 -1
  85. package/templates/portfolio-creative-owner/config.ts +1 -1
  86. package/templates/portfolio-creative-owner/dev/index.ts +247 -9
  87. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  88. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +405 -20
  89. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  90. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  91. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  92. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  93. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  94. package/templates/restaurant/tier5-src/_shared/owner-load-error.ts +7 -1
  95. package/templates/restaurant-owner/config.ts +1 -1
  96. package/templates/restaurant-owner/dev/index.ts +247 -9
  97. package/templates/restaurant-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  98. package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +405 -20
  99. package/templates/restaurant-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  100. package/templates/restaurant-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  101. package/templates/restaurant-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  102. package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  103. package/templates/restaurant-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  104. package/templates/retail-store/tier5-src/_shared/owner-load-error.ts +7 -1
  105. package/templates/retail-store-owner/config.ts +1 -1
  106. package/templates/retail-store-owner/dev/index.ts +247 -9
  107. package/templates/retail-store-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  108. package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +405 -20
  109. package/templates/retail-store-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  110. package/templates/retail-store-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  111. package/templates/retail-store-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  112. package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  113. package/templates/retail-store-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
  114. package/templates/surface-showcase/dev/index.ts +1 -1
  115. package/templates/yoga-studio/tier5-src/_shared/owner-load-error.ts +7 -1
  116. package/templates/yoga-studio-owner/config.ts +1 -1
  117. package/templates/yoga-studio-owner/dev/index.ts +247 -9
  118. package/templates/yoga-studio-owner/tier5-src/_shared/aria-attachments.ts +179 -0
  119. package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +405 -20
  120. package/templates/yoga-studio-owner/tier5-src/_shared/owner-bookings.ts +20 -0
  121. package/templates/yoga-studio-owner/tier5-src/_shared/owner-load-error.ts +7 -1
  122. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -1
  123. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +2 -12
  124. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-manage/index.ts +10 -4
@@ -174,6 +174,13 @@ export interface DevGatewayConfig {
174
174
  url: string;
175
175
  integrity: string;
176
176
  };
177
+ /** What the DEV-SERVER gateway does in `mock` mode with a call no rule matches:
178
+ * `passthrough` (default) forwards it to the real host; `fail` answers a deterministic
179
+ * `404 HIMI_HERMETIC_NO_FIXTURE` and sends nothing upstream (#3019). Honoured by the
180
+ * dev-server's `/v1/__webwix/call` bridge (web host) and `/__dev/{wix,net}/proxy`
181
+ * (native redirect). On-device `NetFake` does not read it yet — an unmatched call there
182
+ * still falls through to the real capability. */
183
+ unmatched?: "passthrough" | "fail";
177
184
  }
178
185
  /** Derive the OTA authConfig block from a defineApp auth block
179
186
  * ({ providerId, config }). `required` is read from `config.required === true`
@@ -1,9 +1,22 @@
1
1
  import type { IncomingMessage, ServerResponse } from "node:http";
2
2
  import type { WixGatewayMode, WixMockRule, WixTrafficEvent } from "./wix-gateway.rules.js";
3
3
  export * from "./wix-gateway.rules.js";
4
+ /** What `mock` mode does with a call NO rule matches.
5
+ *
6
+ * `passthrough` (the default, and the only behaviour before #3019) forwards it to the real
7
+ * host and records the answer — fine for a partial fixture over a live site. `fail` is a
8
+ * SEALED data plane: the call is answered with a deterministic `404`
9
+ * (`HIMI_HERMETIC_NO_FIXTURE`, see `hermeticRefusal`) and recorded, and nothing is sent
10
+ * upstream — not the call, not a visitor-token mint. A hermetic app scenario declares it
11
+ * (`devGateway.unmatched`), because "mock mode" alone never meant fail-closed on any
12
+ * surface, however many comments said so. Only meaningful in `mock` mode; `record` always
13
+ * forwards. */
14
+ export type WixGatewayUnmatched = "passthrough" | "fail";
4
15
  export interface WixGatewayState {
5
16
  mode: WixGatewayMode;
6
17
  rules: WixMockRule[];
18
+ /** See `WixGatewayUnmatched`. Absent ⇒ `passthrough`. */
19
+ unmatched?: WixGatewayUnmatched;
7
20
  /** An OPERATOR replaced the rules or the mode through `/__dev/{wix,net}/*`.
8
21
  *
9
22
  * Read by the date-rollover re-seed (net-mocks-rollover.ts), which must not
@@ -28,7 +41,25 @@ export declare function createWixGatewayState(): WixGatewayState;
28
41
  export interface NetMocksFile {
29
42
  mode?: WixGatewayMode;
30
43
  rules?: WixMockRule[];
44
+ /** See `WixGatewayUnmatched`. Absent ⇒ `passthrough`. */
45
+ unmatched?: WixGatewayUnmatched;
31
46
  }
47
+ /** The mock-rule id a fail-closed refusal is logged under, so `/__dev/net/log` tells a
48
+ * sealed miss apart from a fixture that answered 404 on purpose. */
49
+ export declare const UNMATCHED_FAIL_CLOSED_ID = "unmatched:fail-closed";
50
+ /** True when `mock` mode must refuse a call no rule matched instead of forwarding it. */
51
+ export declare function failsClosed(gw: Pick<WixGatewayState, "mode" | "unmatched">): boolean;
52
+ /** The deterministic answer to an unmatched call on a sealed gateway.
53
+ *
54
+ * 404, not 403/503: a 5xx reads as an outage the owner workers downgrade to labelled demo
55
+ * data (`isBridgeUnavailable` matches 405/501/502/503), which would put a THIRD data source
56
+ * on the screen — the mixing #3019 is about. The body is a Wix-shaped error envelope that
57
+ * names the call, so the developer who sees it knows which fixture to add. */
58
+ export declare function hermeticRefusal(method: string, path: string): {
59
+ status: number;
60
+ headers: Record<string, string>;
61
+ body: string;
62
+ };
32
63
  /** Apply a net-mocks fixture to the gateway state — assigns rule ids, installs
33
64
  * the rule set, and sets the mode (defaults to "mock" when the fixture has rules
34
65
  * and no explicit mode, so a checked-in file serves without extra setup). The
@@ -56,6 +87,7 @@ export declare function applyNetMocks(gw: WixGatewayState, mocks: NetMocksFile):
56
87
  export declare function resolveNetMocks(fileMocks: NetMocksFile | null, appDeclared?: {
57
88
  mode?: WixGatewayMode;
58
89
  rules?: unknown;
90
+ unmatched?: WixGatewayUnmatched;
59
91
  }): {
60
92
  mocks: NetMocksFile;
61
93
  source: "file" | "app";
@@ -20,7 +20,8 @@ export interface WixTrafficEvent {
20
20
  reqBody?: string;
21
21
  respHeaders?: Record<string, string>;
22
22
  respBody?: string;
23
- mockRuleId?: number;
23
+ /** The rule that answered. Rule ids are author-chosen strings or auto-assigned numbers. */
24
+ mockRuleId?: number | string;
24
25
  }
25
26
  /** A response transform (record-proxy then patch the REAL upstream response).
26
27
  * `mergeJson` deep-merges into a JSON body; `replaceBody` replaces it wholesale;
@@ -986,6 +986,13 @@ export interface DevGatewayConfig {
986
986
  url: string;
987
987
  integrity: string;
988
988
  };
989
+ /** What the DEV-SERVER gateway does in `mock` mode with a call no rule matches:
990
+ * `passthrough` (default) forwards it to the real host; `fail` answers a deterministic
991
+ * `404 HIMI_HERMETIC_NO_FIXTURE` and sends nothing upstream (#3019). Honoured by the
992
+ * dev-server's `/v1/__webwix/call` bridge (web host) and `/__dev/{wix,net}/proxy`
993
+ * (native redirect). On-device `NetFake` does not read it yet — an unmatched call there
994
+ * still falls through to the real capability. */
995
+ unmatched?: "passthrough" | "fail";
989
996
  }
990
997
  export declare function defineApp(config: AppConfig): AppConfig;
991
998
  export declare function defineApp(config: FunctionsAppConfig): FunctionsAppConfig;
@@ -51,9 +51,40 @@ export interface ConversationMessage {
51
51
  role?: MessageRole;
52
52
  createdDate?: string;
53
53
  status?: MessageStatus;
54
+ /** Files the owner attached to this turn, as the service stored them. */
55
+ attachments?: Attachment[];
54
56
  /** Client tools this assistant turn asks the CALLER to run — see `FunctionCall`. */
55
57
  functionCalls?: FunctionCall[];
56
58
  }
59
+ /** A file on a message — the service's `Attachment` entity.
60
+ *
61
+ * `url` is the service's own REFERENCE to an uploaded file
62
+ * (`genie-upload://<id>`, see `genieUploadRef`), not a fetchable address: no
63
+ * route that resolves it to a download url is published, so a client can name a
64
+ * sent attachment but not show it again from the server's copy. `viewUrl` is
65
+ * whatever preview the SENDING client chose to store, and is not trusted to
66
+ * resolve anywhere else. */
67
+ export interface Attachment {
68
+ /** Original file name including extension. The service caps it at 255. */
69
+ fileName: string;
70
+ /** e.g. `"image/jpeg"`. The service caps it at 100. */
71
+ mimeType: string;
72
+ url?: string;
73
+ viewUrl?: string;
74
+ }
75
+ /** The mint of an upload: where to send the bytes, and the record's id. */
76
+ export interface CreateFileUploadResponse {
77
+ upload?: {
78
+ uploadUrl?: string;
79
+ id?: string;
80
+ };
81
+ }
82
+ export interface CreateFileUploadOptions {
83
+ /** The same client-declared scoping flag every other chat-service request
84
+ * takes. Omitted unless given — the dashboard sends it only when its own
85
+ * account-scoping gate is on. */
86
+ enforceAccountScopedConversations?: boolean;
87
+ }
57
88
  /** A client-side tool the assistant wants the caller to run before it can go on
58
89
  * — asking the owner for consent, say. It arrives on the `/user-message`
59
90
  * response and the agent then WAITS: nothing more is written until the result
@@ -169,6 +200,9 @@ export interface SendMessageOptions {
169
200
  enforceAccountScopedConversations?: boolean;
170
201
  /** Tag the turn with the same origin the conversation was created under. */
171
202
  origin?: string;
203
+ /** Files already UPLOADED (see `createFileUpload`) to store with the turn.
204
+ * Rides step 1 only — the trigger names the stored turn, which carries them. */
205
+ attachments?: Attachment[];
172
206
  }
173
207
  export interface ConversationUserMessageResponse {
174
208
  userMessage?: ConversationMessage;
@@ -232,6 +266,32 @@ export declare function sendFunctionCallResults(conversationId: string, results:
232
266
  * transcript. Rejecting means the turn is still running: treat it as "could
233
267
  * not stop", never as "stopped". */
234
268
  export declare function abortAssistantMessageGeneration(userMessageId: string): Promise<AbortAssistantMessageGenerationResponse>;
269
+ /** Mint an upload for one file: a pre-signed url to send its bytes to, and the
270
+ * id the message will reference it by (`genieUploadRef`).
271
+ *
272
+ * Only the MINT goes through the chat-service; the bytes go straight to
273
+ * `upload.uploadUrl` (see the file header). Resolving is not proof the file
274
+ * exists — nothing is stored until those bytes land, so a caller must not
275
+ * attach the reference before its upload has succeeded. */
276
+ export declare function createFileUpload(fileName: string, mimeType: string, opts?: CreateFileUploadOptions): Promise<CreateFileUploadResponse>;
277
+ /** The scheme every first-party creator uses to reference an uploaded file from
278
+ * a message attachment. */
279
+ export declare const GENIE_UPLOAD_SCHEME = "genie-upload://";
280
+ /** `genie-upload://<id>`, or "" for no id — never a reference to nothing. */
281
+ export declare function genieUploadRef(id: string | undefined): string;
282
+ /** Where the bytes actually go: `uploadUrl` with `path` and `acl=private` set.
283
+ *
284
+ * Mirrors the Media Platform browser uploader every first-party client relies
285
+ * on. The service rewrites the storage key itself, so `path` is advisory; it is
286
+ * sent anyway, for parity with the clients whose uploads are known to work.
287
+ *
288
+ * String surgery rather than `new URL`, because the worker runtimes (JSContext,
289
+ * Hermes, QuickJS) do not all ship the URL constructor — and MERGED rather than
290
+ * appended, because the signed url may already carry a query, and a second `?`
291
+ * would corrupt the signature it carries. An existing `path` / `acl` is
292
+ * replaced rather than duplicated; everything else, the fragment included, is
293
+ * kept byte for byte. */
294
+ export declare function uploadTargetUrl(uploadUrl: string, fileName: string): string;
235
295
  /** Fetch the messages of a conversation (poll after sendMessage). */
236
296
  export declare function getConversationMessages(conversationId: string): Promise<GetConversationMessagesResponse>;
237
297
  /** The transcript from a getConversationMessages response, under either key. */
@@ -253,6 +313,10 @@ export declare function conversationIdOf(res: CreateConversationResponse | null
253
313
  /** A message's text. `content` is normally a string, but can arrive as an object
254
314
  * carrying `text`; anything else is stringified rather than dropped. */
255
315
  export declare function messageText(m: ConversationMessage | null | undefined): string;
316
+ /** A message's attachments that name a file, in order. Anything that is not an
317
+ * object with a non-empty `fileName` is dropped rather than rendered as a blank
318
+ * entry — the list is display-only, so a malformed row has nothing to show. */
319
+ export declare function attachmentsOf(m: ConversationMessage | null | undefined): Attachment[];
256
320
  /** The last ASSISTANT message in a transcript, or undefined. The "has the reply
257
321
  * landed?" predicate every poller needs. */
258
322
  export declare function lastAssistantMessage(msgs: ConversationMessage[]): ConversationMessage | undefined;
@@ -36,7 +36,7 @@ function getConversations(origin) {
36
36
  function conversationUserMessage(conversationId, content, opts = {}) {
37
37
  if (!conversationId) throw new Error("conversationUserMessage: conversationId is required");
38
38
  return wixCall("POST", `${BASE}/conversation-user-message`, {
39
- attachments: [],
39
+ attachments: opts.attachments ?? [],
40
40
  messageReferences: [],
41
41
  userMessageContent: content,
42
42
  origin: opts.origin ?? ARIA_ORIGIN,
@@ -113,6 +113,36 @@ function abortAssistantMessageGeneration(userMessageId) {
113
113
  if (!userMessageId) throw new Error("abortAssistantMessageGeneration: userMessageId is required");
114
114
  return wixCall("POST", `${BASE}/abort-assistant-message-generation`, { userMessageId });
115
115
  }
116
+ function createFileUpload(fileName, mimeType, opts = {}) {
117
+ if (!fileName) throw new Error("createFileUpload: fileName is required");
118
+ return wixCall("POST", `${BASE}/files/create-upload`, {
119
+ fileName,
120
+ mimeType,
121
+ ...opts.enforceAccountScopedConversations === void 0 ? {} : { enforceAccountScopedConversations: opts.enforceAccountScopedConversations }
122
+ });
123
+ }
124
+ var GENIE_UPLOAD_SCHEME = "genie-upload://";
125
+ function genieUploadRef(id) {
126
+ const v = (id ?? "").trim();
127
+ return v ? `${GENIE_UPLOAD_SCHEME}${v}` : "";
128
+ }
129
+ function uploadTargetUrl(uploadUrl, fileName) {
130
+ const raw = (uploadUrl ?? "").trim();
131
+ if (!raw) return "";
132
+ const hashAt = raw.indexOf("#");
133
+ const fragment = hashAt >= 0 ? raw.slice(hashAt) : "";
134
+ const noFragment = hashAt >= 0 ? raw.slice(0, hashAt) : raw;
135
+ const qAt = noFragment.indexOf("?");
136
+ const base = qAt >= 0 ? noFragment.slice(0, qAt) : noFragment;
137
+ const kept = (qAt >= 0 ? noFragment.slice(qAt + 1) : "").split("&").filter((pair) => {
138
+ if (!pair) return false;
139
+ const key = pair.split("=")[0];
140
+ return key !== "path" && key !== "acl";
141
+ });
142
+ const path = `/${(fileName ?? "").replace(/^\/+/, "")}`;
143
+ kept.push(`path=${encodeURIComponent(path)}`, "acl=private");
144
+ return `${base}?${kept.join("&")}${fragment}`;
145
+ }
116
146
  function getConversationMessages(conversationId) {
117
147
  if (!conversationId) throw new Error("getConversationMessages: conversationId is required");
118
148
  return wixCall("GET", `${BASE}/conversation-messages?conversationId=${encodeURIComponent(conversationId)}`);
@@ -145,6 +175,11 @@ function messageText(m) {
145
175
  }
146
176
  return "";
147
177
  }
178
+ function attachmentsOf(m) {
179
+ const raw = m?.attachments;
180
+ if (!Array.isArray(raw)) return [];
181
+ return raw.filter((a) => !!a && typeof a === "object" && typeof a.fileName === "string" && !!a.fileName.trim());
182
+ }
148
183
  function lastAssistantMessage(msgs) {
149
184
  for (let i = msgs.length - 1; i >= 0; i--) {
150
185
  if (msgs[i]?.role === "ASSISTANT") return msgs[i];
@@ -154,13 +189,17 @@ function lastAssistantMessage(msgs) {
154
189
  export {
155
190
  ARIA_ORIGIN,
156
191
  ARIA_UNIFIED_ASSISTANT_ID,
192
+ GENIE_UPLOAD_SCHEME,
157
193
  abortAssistantMessageGeneration,
158
194
  ariaAssistantConfig,
195
+ attachmentsOf,
159
196
  conversationIdOf,
160
197
  conversationUserMessage,
161
198
  createConversation,
199
+ createFileUpload,
162
200
  functionCallsOf,
163
201
  genieChatError,
202
+ genieUploadRef,
164
203
  getConversationMessages,
165
204
  getConversations,
166
205
  isGenieChatError,
@@ -170,6 +209,7 @@ export {
170
209
  sendFunctionCallResults,
171
210
  sendMessage,
172
211
  triggerAssistantMessage,
212
+ uploadTargetUrl,
173
213
  userMessageIdOf,
174
214
  wixCall
175
215
  };