@openclaw/line 2026.8.1-beta.3 → 2026.8.2

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 (156) hide show
  1. package/dist/account-helpers-BSUyZwLm.js +12 -0
  2. package/dist/{accounts-BqEVsDoB.js → accounts-BBEFMYbY.js} +2 -1
  3. package/dist/api.js +2 -2
  4. package/dist/card-command-DS6A5V6o.js +252 -0
  5. package/dist/{channel-DmoKZXmG.js → channel-CLCy4jAa.js} +97 -357
  6. package/dist/channel-plugin-api.js +1 -1
  7. package/dist/channel.runtime-Ih7sq1GN.js +4 -0
  8. package/dist/contract-api.js +1 -1
  9. package/dist/doctor-contract-api.js +141 -0
  10. package/dist/index.js +5 -17
  11. package/dist/{markdown-to-line-rEaras_0.js → markdown-to-line--jytmFan.js} +36 -29
  12. package/dist/{monitor-BYXS_B6r.js → monitor-CSpwQCBI.js} +292 -194
  13. package/dist/monitor.runtime-CV8EjkIT.js +2 -0
  14. package/dist/outbound.runtime-DLqcz_BQ.js +3 -0
  15. package/dist/probe.runtime-DTxBWvKz.js +2 -0
  16. package/dist/rich-messages-CIP7xn5E.js +761 -0
  17. package/dist/runtime-api.js +12 -13
  18. package/dist/{send-receipt-DKZzgHMO.js → send-retry-CUvrarfE.js} +137 -413
  19. package/dist/{send-BJCeiiOB.js → send-wVUV00WS.js} +150 -109
  20. package/dist/setup-api.js +1 -1
  21. package/dist/{setup-surface-W0Dbgu58.js → setup-surface-CDlgkTKi.js} +47 -39
  22. package/dist/webhook-spool-contract-1rY8OJw8.js +59 -0
  23. package/node_modules/typebox/build/format/date.d.mts +1 -1
  24. package/node_modules/typebox/build/format/date.mjs +1 -1
  25. package/node_modules/typebox/build/format/date_time.d.mts +2 -2
  26. package/node_modules/typebox/build/format/date_time.mjs +3 -3
  27. package/node_modules/typebox/build/format/email.d.mts +1 -1
  28. package/node_modules/typebox/build/format/email.mjs +2 -2
  29. package/node_modules/typebox/build/format/hostname.mjs +2 -10
  30. package/node_modules/typebox/build/format/idn_email.d.mts +1 -1
  31. package/node_modules/typebox/build/format/idn_email.mjs +3 -3
  32. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -0
  33. package/node_modules/typebox/build/format/idn_hostname.mjs +3 -11
  34. package/node_modules/typebox/build/format/idna/format/bidi.d.mts +3 -0
  35. package/node_modules/typebox/build/format/idna/format/bidi.mjs +98 -0
  36. package/node_modules/typebox/build/format/idna/format/puny.d.mts +3 -0
  37. package/node_modules/typebox/build/format/idna/format/puny.mjs +144 -0
  38. package/node_modules/typebox/build/format/idna/hostname.d.mts +1 -0
  39. package/node_modules/typebox/build/format/idna/hostname.mjs +16 -0
  40. package/node_modules/typebox/build/format/idna/idn-hostname.d.mts +1 -0
  41. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +41 -0
  42. package/node_modules/typebox/build/format/idna/index.d.mts +2 -0
  43. package/node_modules/typebox/build/format/idna/index.mjs +2 -0
  44. package/node_modules/typebox/build/format/idna/label/ascii.d.mts +1 -0
  45. package/node_modules/typebox/build/format/idna/label/ascii.mjs +9 -0
  46. package/node_modules/typebox/build/format/idna/label/puny.d.mts +1 -0
  47. package/node_modules/typebox/build/format/idna/label/puny.mjs +28 -0
  48. package/node_modules/typebox/build/format/idna/label/unicode.d.mts +1 -0
  49. package/node_modules/typebox/build/format/idna/label/unicode.mjs +106 -0
  50. package/node_modules/typebox/build/format/idna/pattern/pattern.d.mts +30 -0
  51. package/node_modules/typebox/build/format/idna/pattern/pattern.mjs +70 -0
  52. package/node_modules/typebox/build/format/ipv4.d.mts +0 -1
  53. package/node_modules/typebox/build/format/ipv4.mjs +2 -32
  54. package/node_modules/typebox/build/format/ipv6.mjs +2 -61
  55. package/node_modules/typebox/build/format/iri.d.mts +2 -2
  56. package/node_modules/typebox/build/format/iri.mjs +26 -8
  57. package/node_modules/typebox/build/format/iri_reference.d.mts +2 -2
  58. package/node_modules/typebox/build/format/iri_reference.mjs +9 -55
  59. package/node_modules/typebox/build/format/regex.d.mts +1 -2
  60. package/node_modules/typebox/build/format/regex.mjs +2 -6
  61. package/node_modules/typebox/build/format/time.d.mts +2 -2
  62. package/node_modules/typebox/build/format/time.mjs +19 -14
  63. package/node_modules/typebox/build/format/uri.d.mts +1 -1
  64. package/node_modules/typebox/build/format/uri.mjs +3 -130
  65. package/node_modules/typebox/build/format/uri_reference.d.mts +1 -1
  66. package/node_modules/typebox/build/format/uri_reference.mjs +2 -3
  67. package/node_modules/typebox/build/format/uri_template.d.mts +2 -3
  68. package/node_modules/typebox/build/format/uri_template.mjs +4 -5
  69. package/node_modules/typebox/build/format/url.d.mts +3 -3
  70. package/node_modules/typebox/build/format/url.mjs +4 -5
  71. package/node_modules/typebox/build/guard/emit.d.mts +3 -1
  72. package/node_modules/typebox/build/guard/emit.mjs +12 -5
  73. package/node_modules/typebox/build/guard/guard.d.mts +8 -2
  74. package/node_modules/typebox/build/guard/guard.mjs +25 -4
  75. package/node_modules/typebox/build/guard/string.d.mts +2 -2
  76. package/node_modules/typebox/build/guard/string.mjs +7 -7
  77. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -3
  78. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -2
  79. package/node_modules/typebox/build/schema/engine/_regexp.d.mts +2 -0
  80. package/node_modules/typebox/build/schema/engine/_regexp.mjs +4 -0
  81. package/node_modules/typebox/build/schema/engine/_stack.mjs +12 -13
  82. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +17 -7
  83. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +4 -3
  84. package/node_modules/typebox/build/schema/engine/contains.mjs +18 -6
  85. package/node_modules/typebox/build/schema/engine/enum.mjs +1 -1
  86. package/node_modules/typebox/build/schema/engine/items.mjs +26 -6
  87. package/node_modules/typebox/build/schema/engine/maxContains.mjs +3 -3
  88. package/node_modules/typebox/build/schema/engine/minContains.mjs +14 -4
  89. package/node_modules/typebox/build/schema/engine/not.mjs +4 -2
  90. package/node_modules/typebox/build/schema/engine/oneOf.mjs +7 -6
  91. package/node_modules/typebox/build/schema/engine/pattern.mjs +3 -2
  92. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +4 -3
  93. package/node_modules/typebox/build/schema/engine/ref.mjs +1 -7
  94. package/node_modules/typebox/build/schema/engine/schema.mjs +13 -4
  95. package/node_modules/typebox/build/schema/engine/type.mjs +1 -1
  96. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +4 -1
  97. package/node_modules/typebox/build/schema/resolve/resolve.mjs +202 -1
  98. package/node_modules/typebox/build/schema/static/propertyNames.d.mts +5 -0
  99. package/node_modules/typebox/build/schema/static/propertyNames.mjs +3 -0
  100. package/node_modules/typebox/build/schema/static/schema.d.mts +3 -0
  101. package/node_modules/typebox/build/schema/types/index.d.mts +0 -2
  102. package/node_modules/typebox/build/schema/types/index.mjs +0 -2
  103. package/node_modules/typebox/build/system/memory/clone.mjs +14 -11
  104. package/node_modules/typebox/build/system/memory/discard.mjs +6 -5
  105. package/node_modules/typebox/build/system/settings/settings.d.mts +9 -0
  106. package/node_modules/typebox/build/system/settings/settings.mjs +2 -0
  107. package/node_modules/typebox/build/type/engine/call/distribute_arguments.d.mts +6 -1
  108. package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +16 -3
  109. package/node_modules/typebox/build/type/engine/call/instantiate.mjs +34 -4
  110. package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +5 -5
  111. package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +20 -26
  112. package/node_modules/typebox/build/type/engine/evaluate/compare.d.mts +6 -10
  113. package/node_modules/typebox/build/type/engine/evaluate/compare.mjs +9 -13
  114. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +7 -4
  115. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +12 -19
  116. package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +4 -20
  117. package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +8 -20
  118. package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +4 -4
  119. package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +11 -8
  120. package/node_modules/typebox/build/type/engine/evaluate/flatten.d.mts +1 -1
  121. package/node_modules/typebox/build/type/engine/evaluate/flatten.mjs +3 -4
  122. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +17 -2
  123. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +26 -6
  124. package/node_modules/typebox/build/type/engine/exclude/operation.mjs +3 -4
  125. package/node_modules/typebox/build/type/engine/extract/operation.d.mts +1 -1
  126. package/node_modules/typebox/build/type/engine/extract/operation.mjs +3 -4
  127. package/node_modules/typebox/build/type/engine/priority/priority.d.mts +2 -2
  128. package/node_modules/typebox/build/type/engine/priority/priority.mjs +3 -4
  129. package/node_modules/typebox/build/type/script/mapping.d.mts +32 -29
  130. package/node_modules/typebox/build/type/script/mapping.mjs +18 -25
  131. package/node_modules/typebox/build/type/script/parser.d.mts +19 -25
  132. package/node_modules/typebox/build/type/script/parser.mjs +27 -23
  133. package/node_modules/typebox/build/value/errors/errors.d.mts +2 -2
  134. package/node_modules/typebox/build/value/errors/errors.mjs +1 -1
  135. package/node_modules/typebox/package.json +27 -27
  136. package/node_modules/typebox/readme.md +79 -82
  137. package/openclaw.plugin.json +26 -2
  138. package/package.json +6 -6
  139. package/dist/card-command-CyDSm-OU.js +0 -224
  140. package/dist/channel.runtime-qrUV6wPE.js +0 -4
  141. package/dist/config-schema-Be3azjB_.js +0 -47
  142. package/dist/monitor.runtime-B2z_5ugU.js +0 -2
  143. package/dist/outbound.runtime-DDTeqaBW.js +0 -3
  144. package/dist/probe.runtime-D13ZtXsd.js +0 -2
  145. package/dist/quick-reply-fallback-D86FwAfr.js +0 -56
  146. package/node_modules/typebox/build/format/_idna.d.mts +0 -2
  147. package/node_modules/typebox/build/format/_idna.mjs +0 -246
  148. package/node_modules/typebox/build/format/_puny.d.mts +0 -1
  149. package/node_modules/typebox/build/format/_puny.mjs +0 -77
  150. package/node_modules/typebox/build/schema/resolve/ref.d.mts +0 -3
  151. package/node_modules/typebox/build/schema/resolve/ref.mjs +0 -146
  152. package/node_modules/typebox/build/schema/types/contentEncoding.d.mts +0 -9
  153. package/node_modules/typebox/build/schema/types/contentEncoding.mjs +0 -13
  154. package/node_modules/typebox/build/schema/types/contentMediaType.d.mts +0 -9
  155. package/node_modules/typebox/build/schema/types/contentMediaType.mjs +0 -13
  156. package/dist/{probe-CM03wo6r.js → probe-4gc_YQ2L.js} +1 -1
@@ -0,0 +1,141 @@
1
+ import { a as eventIdFor, i as errorText, o as laneKeyFor, r as LineWebhookPayloadError, s as legacyEventIdFor, t as LINE_WEBHOOK_SPOOL_INVALID_EVENT_REASON } from "./webhook-spool-contract-1rY8OJw8.js";
2
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ //#region extensions/line/src/webhook-spool-migration.ts
4
+ /** Pre-drain (#109655) rows stored the event object under `event` instead of the
5
+ * canonical serialized `rawEvent`; anything else is not a migratable row. */
6
+ function parseLegacySpoolPayload(payload) {
7
+ if (!isRecord(payload) || "rawEvent" in payload) return null;
8
+ if (typeof payload.destination !== "string") return null;
9
+ if (!isRecord(payload.event)) return null;
10
+ return {
11
+ destination: payload.destination,
12
+ event: payload.event
13
+ };
14
+ }
15
+ /** A dead-letter carries the pre-fix decoder's signature when the canonical spool
16
+ * rejected a pre-drain row before this migration existed. The identity fence and
17
+ * ordinary delivery failures write different reasons or messages, so neither is
18
+ * ever treated as recoverable. */
19
+ function isLegacyDecodeDeadLetter(row) {
20
+ return row.reason === "invalid-event" && row.message === "LINE webhook spool payload is invalid." && parseLegacySpoolPayload(row.payload) !== null;
21
+ }
22
+ /** Counts pre-drain rows (pending, still claimed, or decoder-dead-lettered)
23
+ * without mutating anything. */
24
+ async function countLegacySpoolRows(queue) {
25
+ const pending = await queue.listPending({ limit: "all" });
26
+ const claims = await queue.listClaims();
27
+ const failed = await queue.listFailed?.({ limit: "all" }) ?? [];
28
+ return pending.filter((record) => parseLegacySpoolPayload(record.payload) !== null).length + claims.filter((claim) => parseLegacySpoolPayload(claim.payload) !== null).length + failed.filter((row) => isLegacyDecodeDeadLetter(row)).length;
29
+ }
30
+ /** One-time upgrade migration: rewrite pre-drain (#109655) rows into the canonical
31
+ * payload and message:/event: keyspace before the spool drains, so the runtime
32
+ * reader keeps a single row contract. Idempotent — enqueue deduplicates by id, so
33
+ * a rerun after a crash only re-completes the leftover legacy rows. */
34
+ async function migrateLineLegacySpoolRows(queue) {
35
+ const result = {
36
+ migrated: 0,
37
+ reconciled: 0,
38
+ deadLettered: 0,
39
+ recovered: 0,
40
+ failures: []
41
+ };
42
+ await queue.recoverStaleClaims({
43
+ staleMs: 0,
44
+ shouldRecover: (claim) => parseLegacySpoolPayload(claim.payload) !== null
45
+ });
46
+ const failed = await queue.listFailed?.({ limit: "all" }) ?? [];
47
+ for (const row of failed) {
48
+ if (!isLegacyDecodeDeadLetter(row)) continue;
49
+ try {
50
+ if ((await queue.resubmit?.(row.id, { resubmittedAt: row.receivedAt }))?.kind === "resubmitted") result.recovered += 1;
51
+ } catch (error) {
52
+ result.failures.push(`row ${row.id}: ${errorText(error)}`);
53
+ }
54
+ }
55
+ const pending = await queue.listPending({
56
+ limit: "all",
57
+ orderBy: "received"
58
+ });
59
+ for (const record of pending) {
60
+ const legacy = parseLegacySpoolPayload(record.payload);
61
+ if (!legacy) continue;
62
+ let eventId;
63
+ try {
64
+ if (record.id !== legacyEventIdFor(legacy.event)) throw new LineWebhookPayloadError("LINE webhook event identity changed after durable admission.");
65
+ eventId = eventIdFor(legacy.event);
66
+ } catch (error) {
67
+ await queue.fail(record.id, {
68
+ reason: LINE_WEBHOOK_SPOOL_INVALID_EVENT_REASON,
69
+ message: errorText(error)
70
+ });
71
+ result.deadLettered += 1;
72
+ continue;
73
+ }
74
+ try {
75
+ const admitted = await queue.enqueue(eventId, {
76
+ version: 1,
77
+ rawEvent: JSON.stringify(legacy.event),
78
+ destination: legacy.destination
79
+ }, {
80
+ receivedAt: record.receivedAt,
81
+ laneKey: laneKeyFor(legacy.event, eventId)
82
+ });
83
+ await queue.complete(record.id);
84
+ if (admitted.kind === "completed" || admitted.kind === "failed") result.reconciled += 1;
85
+ else result.migrated += 1;
86
+ } catch (error) {
87
+ result.failures.push(`row ${record.id}: ${errorText(error)}`);
88
+ }
89
+ }
90
+ return result;
91
+ }
92
+ //#endregion
93
+ //#region extensions/line/doctor-contract-api.ts
94
+ const LINE_CHANNEL_ID = "line";
95
+ /** Pre-drain rows can outlive the account config that admitted them, so the sweep
96
+ * enumerates accounts from the host's queue lane instead of the config; a host
97
+ * without the lane fails visibly rather than silently skipping the migration. */
98
+ function lineSpoolQueueAccess(context) {
99
+ const access = context.channelIngressQueues?.find((entry) => entry.channelId === LINE_CHANNEL_ID);
100
+ if (!access) throw new Error("LINE pre-drain spool migration requires the doctor host's channel ingress queue access.");
101
+ return access;
102
+ }
103
+ /** Doctor-owned upgrade migration for pre-drain (#109655) webhook spool rows. */
104
+ const stateMigrations = [{
105
+ id: "line-pre-drain-spool-rows",
106
+ label: "LINE pre-drain webhook spool rows",
107
+ async detectLegacyState(params) {
108
+ const spool = lineSpoolQueueAccess(params.context);
109
+ const preview = [];
110
+ for (const accountId of await spool.listChannelIngressQueueAccountIds()) {
111
+ const count = await countLegacySpoolRows(spool.openChannelIngressQueueForInspection({ accountId }));
112
+ if (count > 0) preview.push(`- LINE pre-drain spool rows (account "${accountId}"): ${count} row(s) -> canonical ingress contract`);
113
+ }
114
+ return preview.length > 0 ? { preview } : null;
115
+ },
116
+ async migrateLegacyState(params) {
117
+ const spool = lineSpoolQueueAccess(params.context);
118
+ const lineConfig = params.config.channels?.line;
119
+ const configuredAccountIds = /* @__PURE__ */ new Set([...Object.keys(lineConfig?.accounts ?? {}), ...lineConfig ? ["default"] : []]);
120
+ const openForMigration = spool.openChannelIngressQueue;
121
+ if (!openForMigration) throw new Error("LINE pre-drain spool migration requires mutable ingress access from the doctor host's exclusive repair section.");
122
+ const changes = [];
123
+ const warnings = [];
124
+ for (const accountId of await spool.listChannelIngressQueueAccountIds()) {
125
+ const result = await migrateLineLegacySpoolRows(openForMigration({ accountId }));
126
+ if (result.migrated > 0 || result.reconciled > 0 || result.deadLettered > 0 || result.recovered > 0) {
127
+ const recovered = result.recovered > 0 ? ` (${result.recovered} recovered from the dead-letter table)` : "";
128
+ const reconciled = result.reconciled > 0 ? `, ${result.reconciled} already settled under the canonical id` : "";
129
+ const dispatchNote = configuredAccountIds.has(accountId) ? "" : ` (account not currently configured, so these stay queued until it is restored)`;
130
+ changes.push(`Migrated LINE pre-drain spool rows (account "${accountId}"): ${result.migrated} queued under the canonical contract, ${result.deadLettered} dead-lettered at the identity fence${reconciled}${recovered}${dispatchNote}`);
131
+ }
132
+ for (const failure of result.failures) warnings.push(`Failed migrating a LINE pre-drain spool row (account "${accountId}", ${failure}); the row stays pending and the migration retries on the next run`);
133
+ }
134
+ return {
135
+ changes,
136
+ warnings
137
+ };
138
+ }
139
+ }];
140
+ //#endregion
141
+ export { stateMigrations };
package/dist/index.js CHANGED
@@ -1,20 +1,7 @@
1
1
  import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
2
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
3
3
  //#region extensions/line/index.ts
4
- function createLineCardCommandLoader(api) {
5
- return createLazyRuntimeModule(async () => {
6
- let registered = null;
7
- const { registerLineCardCommand } = await import("./card-command-CyDSm-OU.js");
8
- registerLineCardCommand({
9
- ...api,
10
- registerCommand(command) {
11
- registered = command;
12
- }
13
- });
14
- if (!registered) throw new Error("LINE card command registration unavailable");
15
- return registered;
16
- });
17
- }
4
+ const loadLineCardCommand = createLazyRuntimeModule(() => import("./card-command-DS6A5V6o.js"));
18
5
  var line_default = defineBundledChannelEntry({
19
6
  id: "line",
20
7
  name: "LINE",
@@ -29,14 +16,15 @@ var line_default = defineBundledChannelEntry({
29
16
  exportName: "setLineRuntime"
30
17
  },
31
18
  registerFull(api) {
32
- const loadLineCardCommand = createLineCardCommandLoader(api);
33
19
  api.registerCommand({
34
20
  name: "card",
35
- description: "Send a rich card message (LINE).",
21
+ description: "Send a rich card message.",
22
+ channels: ["line"],
36
23
  acceptsArgs: true,
37
24
  requireAuth: false,
38
25
  async handler(ctx) {
39
- return await (await loadLineCardCommand()).handler(ctx);
26
+ const { handleLineCardCommand } = await loadLineCardCommand();
27
+ return await handleLineCardCommand(ctx.args);
40
28
  }
41
29
  });
42
30
  }
@@ -1,18 +1,6 @@
1
- import { _ as uriAction, g as postbackAction, m as normalizeLineAction, p as messageAction, s as createReceiptCard } from "./send-receipt-DKZzgHMO.js";
1
+ import { g as postbackAction, m as normalizeLineAction, p as messageAction, s as createReceiptCard, v as uriAction } from "./send-retry-CUvrarfE.js";
2
2
  import { markdownToIRWithMeta, stripMarkdown, stripMarkdown as stripMarkdown$1 } from "openclaw/plugin-sdk/text-chunking";
3
3
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
- //#region extensions/line/src/flex-templates/message.ts
5
- /**
6
- * Wrap a FlexContainer in a FlexMessage
7
- */
8
- function toFlexMessage(altText, contents) {
9
- return {
10
- type: "flex",
11
- altText,
12
- contents
13
- };
14
- }
15
- //#endregion
16
4
  //#region extensions/line/src/template-messages.ts
17
5
  const COMPACT_TEMPLATE_TEXT_LIMIT = 60;
18
6
  const TEMPLATE_ALT_TEXT_LIMIT = 1500;
@@ -157,6 +145,18 @@ function buildTemplateMessageFromPayload(payload) {
157
145
  }
158
146
  }
159
147
  //#endregion
148
+ //#region extensions/line/src/flex-templates/message.ts
149
+ /**
150
+ * Wrap a FlexContainer in a FlexMessage
151
+ */
152
+ function toFlexMessage(altText, contents) {
153
+ return {
154
+ type: "flex",
155
+ altText,
156
+ contents
157
+ };
158
+ }
159
+ //#endregion
160
160
  //#region extensions/line/src/markdown-to-line.ts
161
161
  const LINE_MARKDOWN_OPTIONS = {
162
162
  assistantTranscriptRoleHeaders: true,
@@ -169,6 +169,7 @@ const LINE_MARKDOWN_OPTIONS = {
169
169
  };
170
170
  const TRANSCRIPT_ROLE_PREFIX = "[assistant-authored transcript] ";
171
171
  const LINE_FLEX_BUBBLE_MAX_BYTES = 3e4;
172
+ const LINE_FLEX_CODE_CARD_MAX_CHARS = 2e3;
172
173
  function parseLineMarkdown(text, tableMode = "block") {
173
174
  return markdownToIRWithMeta(text, {
174
175
  ...LINE_MARKDOWN_OPTIONS,
@@ -212,10 +213,13 @@ function projectPlainText(ir, omitted = [], additionalInsertions = [], onSegment
212
213
  text: TRANSCRIPT_ROLE_PREFIX
213
214
  });
214
215
  const inlineCodeSpans = ir.styles.filter((span) => span.style === "code" && !omitted.some((range) => rangesOverlap(range, span)));
215
- for (const span of inlineCodeSpans) if (stripMarkdown(ir.text.slice(span.start, span.end), { assistantTranscriptRoleHeaders: true }).startsWith(TRANSCRIPT_ROLE_PREFIX)) insertions.push({
216
- position: span.start,
217
- text: TRANSCRIPT_ROLE_PREFIX
218
- });
216
+ for (const span of inlineCodeSpans) {
217
+ const code = ir.text.slice(span.start, span.end);
218
+ if (stripMarkdown(code, { assistantTranscriptRoleHeaders: true }).startsWith(TRANSCRIPT_ROLE_PREFIX)) insertions.push({
219
+ position: span.start,
220
+ text: TRANSCRIPT_ROLE_PREFIX
221
+ });
222
+ }
219
223
  insertions.sort((left, right) => left.position - right.position);
220
224
  const underlineTags = [...ir.text.matchAll(/<\/?u>/gi)].map((match) => ({
221
225
  start: match.index,
@@ -420,7 +424,7 @@ function convertTableToFlexBubble(table) {
420
424
  /** Convert a code block to a LINE Flex Message bubble. */
421
425
  function convertCodeBlockToFlexBubble(block) {
422
426
  const titleText = block.language ? `Code (${block.language})` : "Code";
423
- const displayCode = block.code.length > 2e3 ? truncateUtf16Safe(block.code, 2e3) + "\n..." : block.code;
427
+ const displayCode = block.code.length > LINE_FLEX_CODE_CARD_MAX_CHARS ? `${truncateUtf16Safe(block.code, LINE_FLEX_CODE_CARD_MAX_CHARS)}\n...` : block.code;
424
428
  return {
425
429
  type: "bubble",
426
430
  body: {
@@ -455,13 +459,10 @@ function convertCodeBlockToFlexBubble(block) {
455
459
  function processLineMessage(text) {
456
460
  const { ir, tables } = parseLineMarkdown(text);
457
461
  const codeSpans = codeBlockSpans(ir);
458
- const flexMessages = [];
459
462
  const plainTextInsertions = [];
460
- let hasOversizedTable = false;
461
463
  for (const table of tables) {
462
464
  const bubble = table.rowCells.length > 10 && (table.headers.length !== 2 || table.rowCells.length > 12 || [table.headerCells, ...table.rowCells].some((cells) => cells.some((cell) => renderTableCell(cell, "-").hasMarkup))) ? void 0 : convertTableToFlexBubble(toMarkdownTable(table));
463
465
  if (!bubble || Buffer.byteLength(JSON.stringify(bubble), "utf8") > LINE_FLEX_BUBBLE_MAX_BYTES) {
464
- hasOversizedTable = true;
465
466
  plainTextInsertions.push({
466
467
  position: table.placeholderOffset,
467
468
  text: `\n\n${formatOversizedTableAsBullets(table)}\n\n`
@@ -469,25 +470,31 @@ function processLineMessage(text) {
469
470
  continue;
470
471
  }
471
472
  const message = toFlexMessage("Table", bubble);
472
- flexMessages.push(message);
473
473
  plainTextInsertions.push({
474
474
  position: table.placeholderOffset,
475
475
  message
476
476
  });
477
477
  }
478
478
  for (const span of codeSpans) {
479
- const message = toFlexMessage("Code", convertCodeBlockToFlexBubble(toCodeBlock(ir, span)));
480
- flexMessages.push(message);
479
+ const block = toCodeBlock(ir, span);
480
+ if (!block.code.trim()) continue;
481
+ if (block.code.length > LINE_FLEX_CODE_CARD_MAX_CHARS) {
482
+ plainTextInsertions.push({
483
+ position: span.start,
484
+ text: `\n\n${block.code}\n\n`
485
+ });
486
+ continue;
487
+ }
481
488
  plainTextInsertions.push({
482
489
  position: span.start,
483
- message
490
+ message: toFlexMessage("Code", convertCodeBlockToFlexBubble(block))
484
491
  });
485
492
  }
486
493
  const segments = [];
487
494
  return {
488
- text: projectPlainText(ir, codeSpans, plainTextInsertions, hasOversizedTable ? (segment) => segments.push(segment) : void 0),
489
- flexMessages,
490
- ...hasOversizedTable ? { segments } : {}
495
+ text: projectPlainText(ir, codeSpans, plainTextInsertions, (segment) => segments.push(segment)),
496
+ flexMessages: segments.flatMap((segment) => segment.type === "flex" ? [segment.message] : []),
497
+ ...plainTextInsertions.length > 0 ? { segments } : {}
491
498
  };
492
499
  }
493
500
  /** Check if text contains markdown that needs conversion. */
@@ -496,4 +503,4 @@ function hasMarkdownToConvert(text) {
496
503
  return tables.length > 0 || ir.styles.length > 0 || ir.links.length > 0 || /<\/?u>/i.test(ir.text) || ir.text !== text.trimEnd();
497
504
  }
498
505
  //#endregion
499
- export { stripMarkdown$1 as a, createCarouselColumn as c, toFlexMessage as d, processLineMessage as i, createConfirmTemplate as l, convertTableToFlexBubble as n, buildTemplateMessageFromPayload as o, hasMarkdownToConvert as r, createButtonTemplate as s, convertCodeBlockToFlexBubble as t, createTemplateCarousel as u };
506
+ export { stripMarkdown$1 as a, createButtonTemplate as c, createTemplateCarousel as d, processLineMessage as i, createCarouselColumn as l, convertTableToFlexBubble as n, toFlexMessage as o, hasMarkdownToConvert as r, buildTemplateMessageFromPayload as s, convertCodeBlockToFlexBubble as t, createConfirmTemplate as u };