@admin-layout/ai-chat-ext-browser 12.2.4-alpha.77 → 12.2.4-alpha.78

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/lib/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { feature as default } from './module';
2
+ export { parseWidgetPost } from './utils/parseWidgetPost';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
package/lib/index.js CHANGED
@@ -1 +1 @@
1
- export{feature as default}from'./module.js';//# sourceMappingURL=index.js.map
1
+ export{feature as default}from'./module.js';export{parseWidgetPost}from'./utils/parseWidgetPost.js';//# sourceMappingURL=index.js.map
@@ -0,0 +1,14 @@
1
+ import { IPost } from 'common';
2
+ /**
3
+ * Promote an AI message that embeds a widget JSON block into a typed widget post.
4
+ *
5
+ * Our AI returns `{ propsComponent, propsConfiguration: { contents: { attachment } } }` as a
6
+ * fenced JSON block inside the message text. The messenger-box inbox selects a widget by
7
+ * `post.type` and reads data from `post.propsConfiguration.contents.attachment`, so we lift the
8
+ * block onto those fields and strip it from the visible text. Posts with no widget block (the
9
+ * common case) are returned unchanged.
10
+ *
11
+ * Apply at the inbox's post-list boundary, e.g. `userMessagesList={posts.map(parseWidgetPost)}`.
12
+ */
13
+ export declare function parseWidgetPost(post: IPost): IPost;
14
+ //# sourceMappingURL=parseWidgetPost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseWidgetPost.d.ts","sourceRoot":"","sources":["../../src/utils/parseWidgetPost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AA6C/B;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAgClD"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Fill names ai-chat-ext registers (see module.ts). A widget block's `propsComponent`
3
+ * must match one of these for the post to be promoted into a typed widget.
4
+ */
5
+ const KNOWN_FILL_NAMES = new Set(['media', 'travel', 'workflow', 'aiassistant', 'thinking', 'codeblock', 'tooluse', 'service']);
6
+ /** Matches a fenced code block, capturing its inner body. Language tag (```json) optional. */
7
+ const FENCED_BLOCK = /```(?:[a-zA-Z]+)?\s*([\s\S]*?)```/g;
8
+ /**
9
+ * Find the first fenced block whose JSON has a string `propsComponent`. Returns the parsed
10
+ * envelope and the exact matched block text (so the caller can strip it from the message).
11
+ */
12
+ function findWidgetBlock(message) {
13
+ FENCED_BLOCK.lastIndex = 0;
14
+ let match;
15
+ while ((match = FENCED_BLOCK.exec(message)) !== null) {
16
+ try {
17
+ const parsed = JSON.parse(match[1]);
18
+ if (parsed && typeof parsed.propsComponent === 'string') {
19
+ return {
20
+ envelope: parsed,
21
+ block: match[0]
22
+ };
23
+ }
24
+ } catch {
25
+ // not JSON — skip this block
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ /**
31
+ * Promote an AI message that embeds a widget JSON block into a typed widget post.
32
+ *
33
+ * Our AI returns `{ propsComponent, propsConfiguration: { contents: { attachment } } }` as a
34
+ * fenced JSON block inside the message text. The messenger-box inbox selects a widget by
35
+ * `post.type` and reads data from `post.propsConfiguration.contents.attachment`, so we lift the
36
+ * block onto those fields and strip it from the visible text. Posts with no widget block (the
37
+ * common case) are returned unchanged.
38
+ *
39
+ * Apply at the inbox's post-list boundary, e.g. `userMessagesList={posts.map(parseWidgetPost)}`.
40
+ */
41
+ function parseWidgetPost(post) {
42
+ const message = post?.message;
43
+ // Fast path: skip the regex for ordinary replies.
44
+ if (!message || message.indexOf('propsComponent') === -1) return post;
45
+ const found = findWidgetBlock(message);
46
+ if (!found) return post;
47
+ const {
48
+ envelope,
49
+ block
50
+ } = found;
51
+ if (!KNOWN_FILL_NAMES.has(envelope.propsComponent.toLowerCase())) return post;
52
+ const contents = envelope.propsConfiguration?.contents;
53
+ // Defensive: MessageMedia returns null without a top-level url — backfill from the first item.
54
+ const attachment = contents?.attachment;
55
+ if (attachment && !attachment.url && attachment.items?.[0]?.url) {
56
+ attachment.url = attachment.items[0].url;
57
+ }
58
+ const strippedMessage = message.replace(block, '').replace(/\n{3,}/g, '\n\n').trim();
59
+ return {
60
+ ...post,
61
+ type: envelope.propsComponent.toLowerCase(),
62
+ propsConfiguration: {
63
+ ...(post.propsConfiguration ?? {}),
64
+ contents
65
+ },
66
+ message: strippedMessage
67
+ };
68
+ }export{parseWidgetPost};//# sourceMappingURL=parseWidgetPost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseWidgetPost.js","sources":["../../src/utils/parseWidgetPost.ts"],"sourcesContent":[null],"names":[],"mappings":"AAEA;;;AAGG;AACH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,aAAA,EAAA,UAAA,EAAA,WAAA,EAAA,SAAA,EAAA,SAAA,CAAA,CAAA;;MAE7B,YAAQ,GAAA,oCAAA;;;;;SAKR,eAAS,CAAA,OAAA,EAAA;cACA,CAAA,SAAA,GAAA,CAAA;AACZ,EAAC,IAAC,KAAA;AAEH,EAAA,OAAA,CAAA,KAAA,GAAA,YAAA,CAAA,IAAA,CAAA,OAAA,CAAA,MAAA,IAAA,EAAA;AACA,IAAA,IAAM;AAON,MAAA,MAAA,MAAA,GAAA,IAAA,CAAA,KAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA;;;AAGG,UAAA,QAAA,EAAA,MAAA;AACH,UAAS,KAAA,EAAA,KAAA,CAAA,CAAe;AACpB,SAAA;AACA,MAAA;AACA,IAAA,CAAA,CAAA,MAAQ;AACJ;;;AAGQ,EAAA,OAAA,IAAA;;;AAEN;;;;AAIN;AACJ;AAEA;;;;;;;;;;AAUG,EAAA,MAAA;AACH,IAAA,QAAM;AACF,IAAA;MACA,KAAA;MACA,CAAA,gBAAgB,CAAA,GAAO,CAAC,QAAQ,CAAA,cAAA,CAAgB,WAAQ,EAAA,CAAA,EAAA,OAAA,IAAA;AAAE,EAAA,MAAA,WAAW,QAAC,CAAA,kBAAA,EAAA,QAAA;AAEtE;AACA,EAAA,MAAI,UAAM,GAAA,QAAA,EAAA,UAAA;AAAE,EAAA,IAAA,cAAY,CAAA,UAAA,CAAA,GAAA,IAAA,UAAA,CAAA,KAAA,GAAA,CAAA,CAAA,EAAA,GAAA,EAAA;AAExB,IAAA,UAAQ,CAAA,GAAA,GAAQ,UAAS,CAAG,KAAK,CAAC,CAAA,CAAA,CAAA,GAAA;;AACgC,EAAA,MAAA,eAAY,GAAA,OAAA,CAAA,OAAA,CAAA,KAAA,EAAA,EAAA,CAAA,CAAA,OAAA,CAAA,SAAA,EAAA,MAAA,CAAA,CAAA,IAAA,EAAA;AAE9E,EAAA,OAAA;IACA,GAAA,IAAA;AACA,IAAA,IAAA,EAAM,QAAA,CAAA,cAAuB,YAAW,EAAA;AACxC,IAAA,kBAAkB,EAAC;UACf,IAAA,CAAA,kBAAiB,IAAW,EAAA,CAAA;MAC/B;KAED;AACK,IAAA,OAAA,EAAA;AACA,GAAA;AACA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parseWidgetPost.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseWidgetPost.spec.d.ts","sourceRoot":"","sources":["../../src/utils/parseWidgetPost.spec.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@admin-layout/ai-chat-ext-browser",
3
- "version": "12.2.4-alpha.77",
3
+ "version": "12.2.4-alpha.78",
4
4
  "description": "AI Chat extension for Messenger - supports AI assistant, thinking, code blocks, tool use, and service messages",
5
5
  "license": "ISC",
6
6
  "author": "CDMBase LLC",
@@ -35,7 +35,7 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "e57817dab6f7e4ea222a95d5964be084ac02d00b",
38
+ "gitHead": "63fc669f10fb995189efe4b40d47c5a2e32acd01",
39
39
  "typescript": {
40
40
  "definition": "lib/index.d.ts"
41
41
  }