lua-cli 3.15.0 → 3.15.1

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 (39) hide show
  1. package/dist/cli/command-definitions.d.ts.map +1 -1
  2. package/dist/cli/command-definitions.js +46 -0
  3. package/dist/cli/command-definitions.js.map +1 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +70 -83
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/push.d.ts.map +1 -1
  8. package/dist/commands/push.js +87 -11
  9. package/dist/commands/push.js.map +1 -1
  10. package/dist/commands/pushBackup.d.ts +58 -4
  11. package/dist/commands/pushBackup.d.ts.map +1 -1
  12. package/dist/commands/pushBackup.js +202 -125
  13. package/dist/commands/pushBackup.js.map +1 -1
  14. package/dist/commands/source.d.ts +72 -0
  15. package/dist/commands/source.d.ts.map +1 -0
  16. package/dist/commands/source.js +124 -0
  17. package/dist/commands/source.js.map +1 -0
  18. package/dist/instances/user.instance.d.ts +2 -1
  19. package/dist/instances/user.instance.d.ts.map +1 -1
  20. package/dist/instances/user.instance.js.map +1 -1
  21. package/dist/interfaces/backup.d.ts +24 -0
  22. package/dist/interfaces/backup.d.ts.map +1 -1
  23. package/dist/interfaces/chat.d.ts +1 -21
  24. package/dist/interfaces/chat.d.ts.map +1 -1
  25. package/dist/types/api-contracts.d.ts +4 -3
  26. package/dist/types/api-contracts.d.ts.map +1 -1
  27. package/dist/types/yaml.types.d.ts +6 -0
  28. package/dist/types/yaml.types.d.ts.map +1 -1
  29. package/dist/utils/build-manifest-from-disk.d.ts +17 -0
  30. package/dist/utils/build-manifest-from-disk.d.ts.map +1 -0
  31. package/dist/utils/build-manifest-from-disk.js +111 -0
  32. package/dist/utils/build-manifest-from-disk.js.map +1 -0
  33. package/node_modules/@lua/shared-types/dist/index.d.mts +64 -1
  34. package/node_modules/@lua/shared-types/dist/index.d.ts +64 -1
  35. package/node_modules/@lua/shared-types/dist/index.js +74 -2
  36. package/node_modules/@lua/shared-types/dist/index.mjs +71 -1
  37. package/node_modules/@lua/shared-types/src/chat-history.types.ts +112 -0
  38. package/node_modules/@lua/shared-types/src/index.ts +1 -0
  39. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-manifest-from-disk.js","sourceRoot":"","sources":["../../src/utils/build-manifest-from-disk.ts"],"names":[],"mappings":"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"}
@@ -216,6 +216,69 @@ interface AgentInvocationOutput {
216
216
  threadId?: string;
217
217
  }
218
218
 
219
+ /**
220
+ * Wire-format types for `GET /chat/history/:agentId` and the VM-sandbox
221
+ * `User.getChatHistory()` API. Both paths return the same shape.
222
+ *
223
+ * Shared between lua-core (HTTP controller + VM devtools) and lua-cli
224
+ * (HTTP client typing for `lua test`). Also shared with lua-api's
225
+ * `thread.service.ts` (admin org-thread listing) so the parser never
226
+ * diverges across services.
227
+ */
228
+ /**
229
+ * One content part of a chat-history message.
230
+ *
231
+ * `text` parts carry plain text. Media parts (`image` / `video` / `audio`
232
+ * / `file`) carry a URL or base64 payload in `data` (or `image` / `video`
233
+ * for legacy reasons) plus a `mediaType` MIME string.
234
+ */
235
+ interface ChatHistoryContent {
236
+ type: 'text' | 'image' | 'video' | 'audio' | 'file';
237
+ text?: string;
238
+ image?: string;
239
+ video?: string;
240
+ data?: string;
241
+ mediaType?: string;
242
+ latitude?: number;
243
+ longitude?: number;
244
+ }
245
+ /**
246
+ * One message returned by chat-history endpoints.
247
+ *
248
+ * Only `user` and `assistant` roles surface — system / tool messages are
249
+ * filtered out before transport.
250
+ */
251
+ interface ChatHistoryMessage {
252
+ id: string;
253
+ role: 'user' | 'assistant';
254
+ /** ISO-8601 timestamp string. */
255
+ createdAt: string;
256
+ content: ChatHistoryContent[];
257
+ }
258
+ /**
259
+ * Strip `::: navigate …:::` blocks from a text string.
260
+ *
261
+ * Exposed because both lua-core's chat-history transform and any future
262
+ * external transform may need it independently.
263
+ */
264
+ declare function removeNavigateBlock(input: string): string;
265
+ /**
266
+ * Transform raw Mastra `MastraMessageContentV2.parts[]` into the
267
+ * `ChatHistoryContent[]` wire shape.
268
+ *
269
+ * Single source of truth for the conversion: used by lua-core's
270
+ * `toChatHistoryMessage` (HTTP + VM sandbox paths) and lua-api's
271
+ * `thread.service.ts` admin org-thread listing. Any future divergence
272
+ * starts here.
273
+ *
274
+ * Parts are deliberately typed `unknown` because callers may either pass
275
+ * Mastra v5 `MastraMessagePart` instances (lua-core, via `@mastra/core`)
276
+ * or raw JSON parsed from a SQL row (lua-api, reading `mastra_messages`
277
+ * directly). The function only inspects `.type`, `.text`, `.data`, and
278
+ * `.mimeType` via property access, so both shapes work.
279
+ */
280
+ declare function transformChatHistoryContentParts(parts: unknown[] | undefined | null): ChatHistoryContent[];
281
+
219
282
  /**
220
283
  * Sandbox contract: defines what every sandbox MUST expose.
221
284
  * Both lua-cli and lua-core test against this contract.
@@ -526,4 +589,4 @@ interface ChatErrorChunk {
526
589
  timestamp: number;
527
590
  }
528
591
 
529
- export { AGENT_LOG_SOURCES, type AgentInvocationInput, type AgentInvocationOutput, type AgentLogMetadata, type AgentLogSource, type AiGenerateInput, type AiGenerateOutput, type AiGenerateSource, type AiGenerateToolCall, type AiGenerateToolResult, type ApprovedModelDef, type BatchingConfig, CLIENT_TOOLS_MAX, CLIENT_TOOL_PREFIX, type CachedDeviceCommand, type CachedDeviceDefinition, type CachedDeviceTrigger, type CachedDeviceTriggerDefinition, type Channel, type ChatErrorChunk, type ClientToolDef, type CommandHashData, type CommandState, type CommandStreamEntry, type DeviceCommandDefinition, type DeviceCommandMessage, type DeviceInfo, type DeviceResponseMessage, type DeviceStatus, type DeviceTriggerAckMessage, type DeviceTriggerMessage, type GovernanceConfig, type PersonaText, REQUIRED_ENUMS, REQUIRED_NESTED_APIS, REQUIRED_PLATFORM_APIS, REQUIRED_PRIMITIVE_SHIMS, REQUIRED_UTILITIES, type ResponseStreamEntry, type SkillContextText, type TriggerStreamEntry, UNSTRUCTURED_SUPPORTED_MEDIA_TYPES, aiGenerateInputFromSimplified, buildDefaultPersona, flattenPersonaText, flattenPersonaTextAll, hasPersonaTextContent, isPersonaTextObject, personaToLiteral };
592
+ export { AGENT_LOG_SOURCES, type AgentInvocationInput, type AgentInvocationOutput, type AgentLogMetadata, type AgentLogSource, type AiGenerateInput, type AiGenerateOutput, type AiGenerateSource, type AiGenerateToolCall, type AiGenerateToolResult, type ApprovedModelDef, type BatchingConfig, CLIENT_TOOLS_MAX, CLIENT_TOOL_PREFIX, type CachedDeviceCommand, type CachedDeviceDefinition, type CachedDeviceTrigger, type CachedDeviceTriggerDefinition, type Channel, type ChatErrorChunk, type ChatHistoryContent, type ChatHistoryMessage, type ClientToolDef, type CommandHashData, type CommandState, type CommandStreamEntry, type DeviceCommandDefinition, type DeviceCommandMessage, type DeviceInfo, type DeviceResponseMessage, type DeviceStatus, type DeviceTriggerAckMessage, type DeviceTriggerMessage, type GovernanceConfig, type PersonaText, REQUIRED_ENUMS, REQUIRED_NESTED_APIS, REQUIRED_PLATFORM_APIS, REQUIRED_PRIMITIVE_SHIMS, REQUIRED_UTILITIES, type ResponseStreamEntry, type SkillContextText, type TriggerStreamEntry, UNSTRUCTURED_SUPPORTED_MEDIA_TYPES, aiGenerateInputFromSimplified, buildDefaultPersona, flattenPersonaText, flattenPersonaTextAll, hasPersonaTextContent, isPersonaTextObject, personaToLiteral, removeNavigateBlock, transformChatHistoryContentParts };
@@ -216,6 +216,69 @@ interface AgentInvocationOutput {
216
216
  threadId?: string;
217
217
  }
218
218
 
219
+ /**
220
+ * Wire-format types for `GET /chat/history/:agentId` and the VM-sandbox
221
+ * `User.getChatHistory()` API. Both paths return the same shape.
222
+ *
223
+ * Shared between lua-core (HTTP controller + VM devtools) and lua-cli
224
+ * (HTTP client typing for `lua test`). Also shared with lua-api's
225
+ * `thread.service.ts` (admin org-thread listing) so the parser never
226
+ * diverges across services.
227
+ */
228
+ /**
229
+ * One content part of a chat-history message.
230
+ *
231
+ * `text` parts carry plain text. Media parts (`image` / `video` / `audio`
232
+ * / `file`) carry a URL or base64 payload in `data` (or `image` / `video`
233
+ * for legacy reasons) plus a `mediaType` MIME string.
234
+ */
235
+ interface ChatHistoryContent {
236
+ type: 'text' | 'image' | 'video' | 'audio' | 'file';
237
+ text?: string;
238
+ image?: string;
239
+ video?: string;
240
+ data?: string;
241
+ mediaType?: string;
242
+ latitude?: number;
243
+ longitude?: number;
244
+ }
245
+ /**
246
+ * One message returned by chat-history endpoints.
247
+ *
248
+ * Only `user` and `assistant` roles surface — system / tool messages are
249
+ * filtered out before transport.
250
+ */
251
+ interface ChatHistoryMessage {
252
+ id: string;
253
+ role: 'user' | 'assistant';
254
+ /** ISO-8601 timestamp string. */
255
+ createdAt: string;
256
+ content: ChatHistoryContent[];
257
+ }
258
+ /**
259
+ * Strip `::: navigate …:::` blocks from a text string.
260
+ *
261
+ * Exposed because both lua-core's chat-history transform and any future
262
+ * external transform may need it independently.
263
+ */
264
+ declare function removeNavigateBlock(input: string): string;
265
+ /**
266
+ * Transform raw Mastra `MastraMessageContentV2.parts[]` into the
267
+ * `ChatHistoryContent[]` wire shape.
268
+ *
269
+ * Single source of truth for the conversion: used by lua-core's
270
+ * `toChatHistoryMessage` (HTTP + VM sandbox paths) and lua-api's
271
+ * `thread.service.ts` admin org-thread listing. Any future divergence
272
+ * starts here.
273
+ *
274
+ * Parts are deliberately typed `unknown` because callers may either pass
275
+ * Mastra v5 `MastraMessagePart` instances (lua-core, via `@mastra/core`)
276
+ * or raw JSON parsed from a SQL row (lua-api, reading `mastra_messages`
277
+ * directly). The function only inspects `.type`, `.text`, `.data`, and
278
+ * `.mimeType` via property access, so both shapes work.
279
+ */
280
+ declare function transformChatHistoryContentParts(parts: unknown[] | undefined | null): ChatHistoryContent[];
281
+
219
282
  /**
220
283
  * Sandbox contract: defines what every sandbox MUST expose.
221
284
  * Both lua-cli and lua-core test against this contract.
@@ -526,4 +589,4 @@ interface ChatErrorChunk {
526
589
  timestamp: number;
527
590
  }
528
591
 
529
- export { AGENT_LOG_SOURCES, type AgentInvocationInput, type AgentInvocationOutput, type AgentLogMetadata, type AgentLogSource, type AiGenerateInput, type AiGenerateOutput, type AiGenerateSource, type AiGenerateToolCall, type AiGenerateToolResult, type ApprovedModelDef, type BatchingConfig, CLIENT_TOOLS_MAX, CLIENT_TOOL_PREFIX, type CachedDeviceCommand, type CachedDeviceDefinition, type CachedDeviceTrigger, type CachedDeviceTriggerDefinition, type Channel, type ChatErrorChunk, type ClientToolDef, type CommandHashData, type CommandState, type CommandStreamEntry, type DeviceCommandDefinition, type DeviceCommandMessage, type DeviceInfo, type DeviceResponseMessage, type DeviceStatus, type DeviceTriggerAckMessage, type DeviceTriggerMessage, type GovernanceConfig, type PersonaText, REQUIRED_ENUMS, REQUIRED_NESTED_APIS, REQUIRED_PLATFORM_APIS, REQUIRED_PRIMITIVE_SHIMS, REQUIRED_UTILITIES, type ResponseStreamEntry, type SkillContextText, type TriggerStreamEntry, UNSTRUCTURED_SUPPORTED_MEDIA_TYPES, aiGenerateInputFromSimplified, buildDefaultPersona, flattenPersonaText, flattenPersonaTextAll, hasPersonaTextContent, isPersonaTextObject, personaToLiteral };
592
+ export { AGENT_LOG_SOURCES, type AgentInvocationInput, type AgentInvocationOutput, type AgentLogMetadata, type AgentLogSource, type AiGenerateInput, type AiGenerateOutput, type AiGenerateSource, type AiGenerateToolCall, type AiGenerateToolResult, type ApprovedModelDef, type BatchingConfig, CLIENT_TOOLS_MAX, CLIENT_TOOL_PREFIX, type CachedDeviceCommand, type CachedDeviceDefinition, type CachedDeviceTrigger, type CachedDeviceTriggerDefinition, type Channel, type ChatErrorChunk, type ChatHistoryContent, type ChatHistoryMessage, type ClientToolDef, type CommandHashData, type CommandState, type CommandStreamEntry, type DeviceCommandDefinition, type DeviceCommandMessage, type DeviceInfo, type DeviceResponseMessage, type DeviceStatus, type DeviceTriggerAckMessage, type DeviceTriggerMessage, type GovernanceConfig, type PersonaText, REQUIRED_ENUMS, REQUIRED_NESTED_APIS, REQUIRED_PLATFORM_APIS, REQUIRED_PRIMITIVE_SHIMS, REQUIRED_UTILITIES, type ResponseStreamEntry, type SkillContextText, type TriggerStreamEntry, UNSTRUCTURED_SUPPORTED_MEDIA_TYPES, aiGenerateInputFromSimplified, buildDefaultPersona, flattenPersonaText, flattenPersonaTextAll, hasPersonaTextContent, isPersonaTextObject, personaToLiteral, removeNavigateBlock, transformChatHistoryContentParts };
@@ -35,7 +35,9 @@ __export(index_exports, {
35
35
  flattenPersonaTextAll: () => flattenPersonaTextAll,
36
36
  hasPersonaTextContent: () => hasPersonaTextContent,
37
37
  isPersonaTextObject: () => isPersonaTextObject,
38
- personaToLiteral: () => personaToLiteral
38
+ personaToLiteral: () => personaToLiteral,
39
+ removeNavigateBlock: () => removeNavigateBlock,
40
+ transformChatHistoryContentParts: () => transformChatHistoryContentParts
39
41
  });
40
42
  module.exports = __toCommonJS(index_exports);
41
43
 
@@ -165,6 +167,74 @@ function aiGenerateInputFromSimplified(prompt, content) {
165
167
  }
166
168
  __name(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
167
169
 
170
+ // src/chat-history.types.ts
171
+ function removeNavigateBlock(input) {
172
+ return input.replace(/::: navigate[\s\S]*?:::/g, "").trim();
173
+ }
174
+ __name(removeNavigateBlock, "removeNavigateBlock");
175
+ function transformChatHistoryContentParts(parts) {
176
+ const content = [];
177
+ for (const rawPart of parts ?? []) {
178
+ const part = rawPart;
179
+ if (part?.type !== "text" && part?.type !== "file") continue;
180
+ if (part.type === "text" && typeof part.text === "string") {
181
+ const rawText = part.text || "";
182
+ if (rawText.includes("::: hide")) continue;
183
+ const audioMatch = rawText.match(/::: audio\s*!\[(.*?)\]\((.*?)\)\s*:::/);
184
+ const videoMatch = rawText.match(/::: video\s*!\[(.*?)\]\((.*?)\)\s*:::/);
185
+ if (audioMatch) {
186
+ content.push({
187
+ type: "audio",
188
+ data: audioMatch[2],
189
+ mediaType: audioMatch[1]
190
+ });
191
+ } else if (videoMatch) {
192
+ content.push({
193
+ type: "video",
194
+ video: videoMatch[2],
195
+ mediaType: videoMatch[1]
196
+ });
197
+ } else {
198
+ let text = rawText.replace(/\\\\\\n/g, "\n");
199
+ text = removeNavigateBlock(text);
200
+ content.push({
201
+ type: "text",
202
+ text
203
+ });
204
+ }
205
+ } else if (part.type === "file") {
206
+ const mediaType = part.mimeType || "";
207
+ if (mediaType.startsWith("image/")) {
208
+ content.push({
209
+ type: "image",
210
+ image: part.data,
211
+ mediaType
212
+ });
213
+ } else if (mediaType.startsWith("video/")) {
214
+ content.push({
215
+ type: "video",
216
+ video: part.data,
217
+ mediaType
218
+ });
219
+ } else if (mediaType.startsWith("audio/")) {
220
+ content.push({
221
+ type: "audio",
222
+ data: part.data,
223
+ mediaType
224
+ });
225
+ } else {
226
+ content.push({
227
+ type: "file",
228
+ data: part.data,
229
+ mediaType
230
+ });
231
+ }
232
+ }
233
+ }
234
+ return content;
235
+ }
236
+ __name(transformChatHistoryContentParts, "transformChatHistoryContentParts");
237
+
168
238
  // src/sandbox-contract.ts
169
239
  var REQUIRED_PRIMITIVE_SHIMS = [
170
240
  // Class-based
@@ -359,5 +429,7 @@ var AGENT_LOG_SOURCES = [
359
429
  flattenPersonaTextAll,
360
430
  hasPersonaTextContent,
361
431
  isPersonaTextObject,
362
- personaToLiteral
432
+ personaToLiteral,
433
+ removeNavigateBlock,
434
+ transformChatHistoryContentParts
363
435
  });
@@ -127,6 +127,74 @@ function aiGenerateInputFromSimplified(prompt, content) {
127
127
  }
128
128
  __name(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
129
129
 
130
+ // src/chat-history.types.ts
131
+ function removeNavigateBlock(input) {
132
+ return input.replace(/::: navigate[\s\S]*?:::/g, "").trim();
133
+ }
134
+ __name(removeNavigateBlock, "removeNavigateBlock");
135
+ function transformChatHistoryContentParts(parts) {
136
+ const content = [];
137
+ for (const rawPart of parts ?? []) {
138
+ const part = rawPart;
139
+ if (part?.type !== "text" && part?.type !== "file") continue;
140
+ if (part.type === "text" && typeof part.text === "string") {
141
+ const rawText = part.text || "";
142
+ if (rawText.includes("::: hide")) continue;
143
+ const audioMatch = rawText.match(/::: audio\s*!\[(.*?)\]\((.*?)\)\s*:::/);
144
+ const videoMatch = rawText.match(/::: video\s*!\[(.*?)\]\((.*?)\)\s*:::/);
145
+ if (audioMatch) {
146
+ content.push({
147
+ type: "audio",
148
+ data: audioMatch[2],
149
+ mediaType: audioMatch[1]
150
+ });
151
+ } else if (videoMatch) {
152
+ content.push({
153
+ type: "video",
154
+ video: videoMatch[2],
155
+ mediaType: videoMatch[1]
156
+ });
157
+ } else {
158
+ let text = rawText.replace(/\\\\\\n/g, "\n");
159
+ text = removeNavigateBlock(text);
160
+ content.push({
161
+ type: "text",
162
+ text
163
+ });
164
+ }
165
+ } else if (part.type === "file") {
166
+ const mediaType = part.mimeType || "";
167
+ if (mediaType.startsWith("image/")) {
168
+ content.push({
169
+ type: "image",
170
+ image: part.data,
171
+ mediaType
172
+ });
173
+ } else if (mediaType.startsWith("video/")) {
174
+ content.push({
175
+ type: "video",
176
+ video: part.data,
177
+ mediaType
178
+ });
179
+ } else if (mediaType.startsWith("audio/")) {
180
+ content.push({
181
+ type: "audio",
182
+ data: part.data,
183
+ mediaType
184
+ });
185
+ } else {
186
+ content.push({
187
+ type: "file",
188
+ data: part.data,
189
+ mediaType
190
+ });
191
+ }
192
+ }
193
+ }
194
+ return content;
195
+ }
196
+ __name(transformChatHistoryContentParts, "transformChatHistoryContentParts");
197
+
130
198
  // src/sandbox-contract.ts
131
199
  var REQUIRED_PRIMITIVE_SHIMS = [
132
200
  // Class-based
@@ -320,5 +388,7 @@ export {
320
388
  flattenPersonaTextAll,
321
389
  hasPersonaTextContent,
322
390
  isPersonaTextObject,
323
- personaToLiteral
391
+ personaToLiteral,
392
+ removeNavigateBlock,
393
+ transformChatHistoryContentParts
324
394
  };
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Wire-format types for `GET /chat/history/:agentId` and the VM-sandbox
3
+ * `User.getChatHistory()` API. Both paths return the same shape.
4
+ *
5
+ * Shared between lua-core (HTTP controller + VM devtools) and lua-cli
6
+ * (HTTP client typing for `lua test`). Also shared with lua-api's
7
+ * `thread.service.ts` (admin org-thread listing) so the parser never
8
+ * diverges across services.
9
+ */
10
+
11
+ /**
12
+ * One content part of a chat-history message.
13
+ *
14
+ * `text` parts carry plain text. Media parts (`image` / `video` / `audio`
15
+ * / `file`) carry a URL or base64 payload in `data` (or `image` / `video`
16
+ * for legacy reasons) plus a `mediaType` MIME string.
17
+ */
18
+ export interface ChatHistoryContent {
19
+ type: 'text' | 'image' | 'video' | 'audio' | 'file';
20
+ text?: string;
21
+ image?: string;
22
+ video?: string;
23
+ data?: string;
24
+ mediaType?: string;
25
+ latitude?: number;
26
+ longitude?: number;
27
+ }
28
+
29
+ /**
30
+ * One message returned by chat-history endpoints.
31
+ *
32
+ * Only `user` and `assistant` roles surface — system / tool messages are
33
+ * filtered out before transport.
34
+ */
35
+ export interface ChatHistoryMessage {
36
+ id: string;
37
+ role: 'user' | 'assistant';
38
+ /** ISO-8601 timestamp string. */
39
+ createdAt: string;
40
+ content: ChatHistoryContent[];
41
+ }
42
+
43
+ /**
44
+ * Strip `::: navigate …:::` blocks from a text string.
45
+ *
46
+ * Exposed because both lua-core's chat-history transform and any future
47
+ * external transform may need it independently.
48
+ */
49
+ export function removeNavigateBlock(input: string): string {
50
+ return input.replace(/::: navigate[\s\S]*?:::/g, '').trim();
51
+ }
52
+
53
+ /**
54
+ * Transform raw Mastra `MastraMessageContentV2.parts[]` into the
55
+ * `ChatHistoryContent[]` wire shape.
56
+ *
57
+ * Single source of truth for the conversion: used by lua-core's
58
+ * `toChatHistoryMessage` (HTTP + VM sandbox paths) and lua-api's
59
+ * `thread.service.ts` admin org-thread listing. Any future divergence
60
+ * starts here.
61
+ *
62
+ * Parts are deliberately typed `unknown` because callers may either pass
63
+ * Mastra v5 `MastraMessagePart` instances (lua-core, via `@mastra/core`)
64
+ * or raw JSON parsed from a SQL row (lua-api, reading `mastra_messages`
65
+ * directly). The function only inspects `.type`, `.text`, `.data`, and
66
+ * `.mimeType` via property access, so both shapes work.
67
+ */
68
+ export function transformChatHistoryContentParts(parts: unknown[] | undefined | null): ChatHistoryContent[] {
69
+ const content: ChatHistoryContent[] = [];
70
+
71
+ for (const rawPart of parts ?? []) {
72
+ const part = rawPart as { type?: string; text?: string; data?: string; mimeType?: string };
73
+ if (part?.type !== 'text' && part?.type !== 'file') continue;
74
+
75
+ if (part.type === 'text' && typeof part.text === 'string') {
76
+ const rawText = part.text || '';
77
+
78
+ // Filter out hidden text
79
+ if (rawText.includes('::: hide')) continue;
80
+
81
+ // Check for audio/video markdown patterns and surface as native
82
+ // audio/video parts (matches the ChatHistoryContent type contract).
83
+ const audioMatch = rawText.match(/::: audio\s*!\[(.*?)\]\((.*?)\)\s*:::/);
84
+ const videoMatch = rawText.match(/::: video\s*!\[(.*?)\]\((.*?)\)\s*:::/);
85
+
86
+ if (audioMatch) {
87
+ content.push({ type: 'audio', data: audioMatch[2], mediaType: audioMatch[1] });
88
+ } else if (videoMatch) {
89
+ content.push({ type: 'video', video: videoMatch[2], mediaType: videoMatch[1] });
90
+ } else {
91
+ // Cleanup text: de-escape \\\\\\n and strip navigate blocks
92
+ let text = rawText.replace(/\\\\\\n/g, '\n');
93
+ text = removeNavigateBlock(text);
94
+ content.push({ type: 'text', text });
95
+ }
96
+ } else if (part.type === 'file') {
97
+ const mediaType = part.mimeType || '';
98
+
99
+ if (mediaType.startsWith('image/')) {
100
+ content.push({ type: 'image', image: part.data, mediaType });
101
+ } else if (mediaType.startsWith('video/')) {
102
+ content.push({ type: 'video', video: part.data, mediaType });
103
+ } else if (mediaType.startsWith('audio/')) {
104
+ content.push({ type: 'audio', data: part.data, mediaType });
105
+ } else {
106
+ content.push({ type: 'file', data: part.data, mediaType });
107
+ }
108
+ }
109
+ }
110
+
111
+ return content;
112
+ }
@@ -4,6 +4,7 @@ export * from './unstructured-types';
4
4
  export * from './ai-generate.types';
5
5
  export * from './ai-generate.utils';
6
6
  export * from './agent-invocation.types';
7
+ export * from './chat-history.types';
7
8
  export * from './sandbox-contract';
8
9
  export * from './device.types';
9
10
  export * from './client-tools.types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lua-cli",
3
- "version": "3.15.0",
3
+ "version": "3.15.1",
4
4
  "description": "Build, test, and deploy AI agents with custom tools, webhooks, and scheduled jobs. Features LuaAgent unified configuration, streaming chat, and batch deployment.",
5
5
  "readmeFilename": "README.md",
6
6
  "main": "dist/api-exports.js",