lua-cli 3.14.1 → 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.
- package/dist/api/agent.api.service.d.ts +12 -0
- package/dist/api/agent.api.service.d.ts.map +1 -1
- package/dist/api/agent.api.service.js +13 -0
- package/dist/api/agent.api.service.js.map +1 -1
- package/dist/api/http.client.d.ts.map +1 -1
- package/dist/api/http.client.js +31 -4
- package/dist/api/http.client.js.map +1 -1
- package/dist/api/persona.api.service.d.ts +3 -2
- package/dist/api/persona.api.service.d.ts.map +1 -1
- package/dist/api/persona.api.service.js +1 -1
- package/dist/api/persona.api.service.js.map +1 -1
- package/dist/api/postprocessor.api.service.d.ts +3 -0
- package/dist/api/postprocessor.api.service.d.ts.map +1 -1
- package/dist/api/postprocessor.api.service.js.map +1 -1
- package/dist/api/preprocessor.api.service.d.ts +4 -0
- package/dist/api/preprocessor.api.service.d.ts.map +1 -1
- package/dist/api/preprocessor.api.service.js +1 -0
- package/dist/api/preprocessor.api.service.js.map +1 -1
- package/dist/api-exports.d.ts +2 -1
- package/dist/api-exports.d.ts.map +1 -1
- package/dist/api-exports.js.map +1 -1
- package/dist/cli/command-definitions.d.ts.map +1 -1
- package/dist/cli/command-definitions.js +56 -0
- package/dist/cli/command-definitions.js.map +1 -1
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +325 -85
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/persona.d.ts.map +1 -1
- package/dist/commands/persona.js +3 -2
- package/dist/commands/persona.js.map +1 -1
- package/dist/commands/production.d.ts.map +1 -1
- package/dist/commands/production.js +8 -2
- package/dist/commands/production.js.map +1 -1
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +94 -14
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/pushBackup.d.ts +58 -4
- package/dist/commands/pushBackup.d.ts.map +1 -1
- package/dist/commands/pushBackup.js +202 -125
- package/dist/commands/pushBackup.js.map +1 -1
- package/dist/commands/source.d.ts +72 -0
- package/dist/commands/source.d.ts.map +1 -0
- package/dist/commands/source.js +124 -0
- package/dist/commands/source.js.map +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +3 -2
- package/dist/commands/sync.js.map +1 -1
- package/dist/compiler/plugins/agent.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/agent.plugin.js +10 -5
- package/dist/compiler/plugins/agent.plugin.js.map +1 -1
- package/dist/compiler/plugins/postprocessor.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/postprocessor.plugin.js +8 -2
- package/dist/compiler/plugins/postprocessor.plugin.js.map +1 -1
- package/dist/compiler/plugins/preprocessor.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/preprocessor.plugin.js +6 -3
- package/dist/compiler/plugins/preprocessor.plugin.js.map +1 -1
- package/dist/compiler/plugins/skill.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/skill.plugin.js +6 -2
- package/dist/compiler/plugins/skill.plugin.js.map +1 -1
- package/dist/compiler/source-writer.d.ts +13 -8
- package/dist/compiler/source-writer.d.ts.map +1 -1
- package/dist/compiler/source-writer.js +24 -12
- package/dist/compiler/source-writer.js.map +1 -1
- package/dist/compiler/types.d.ts +11 -5
- package/dist/compiler/types.d.ts.map +1 -1
- package/dist/compiler/types.js.map +1 -1
- package/dist/compiler/utils/ast-helpers.d.ts +11 -0
- package/dist/compiler/utils/ast-helpers.d.ts.map +1 -1
- package/dist/compiler/utils/ast-helpers.js +27 -0
- package/dist/compiler/utils/ast-helpers.js.map +1 -1
- package/dist/errors/auth.error.d.ts +19 -1
- package/dist/errors/auth.error.d.ts.map +1 -1
- package/dist/errors/auth.error.js +4 -1
- package/dist/errors/auth.error.js.map +1 -1
- package/dist/instances/user.instance.d.ts +2 -1
- package/dist/instances/user.instance.d.ts.map +1 -1
- package/dist/instances/user.instance.js.map +1 -1
- package/dist/interfaces/agent.d.ts +34 -4
- package/dist/interfaces/agent.d.ts.map +1 -1
- package/dist/interfaces/backup.d.ts +24 -0
- package/dist/interfaces/backup.d.ts.map +1 -1
- package/dist/interfaces/chat.d.ts +3 -22
- package/dist/interfaces/chat.d.ts.map +1 -1
- package/dist/interfaces/init.d.ts +3 -2
- package/dist/interfaces/init.d.ts.map +1 -1
- package/dist/interfaces/persona.d.ts +2 -1
- package/dist/interfaces/persona.d.ts.map +1 -1
- package/dist/interfaces/skills.d.ts +4 -3
- package/dist/interfaces/skills.d.ts.map +1 -1
- package/dist/primitives/agent.handler.d.ts +3 -3
- package/dist/primitives/agent.handler.d.ts.map +1 -1
- package/dist/primitives/agent.handler.js +15 -1
- package/dist/primitives/agent.handler.js.map +1 -1
- package/dist/primitives/postprocessor.handler.d.ts +5 -0
- package/dist/primitives/postprocessor.handler.d.ts.map +1 -1
- package/dist/primitives/postprocessor.handler.js +13 -0
- package/dist/primitives/postprocessor.handler.js.map +1 -1
- package/dist/primitives/preprocessor.handler.d.ts +2 -2
- package/dist/primitives/preprocessor.handler.d.ts.map +1 -1
- package/dist/primitives/preprocessor.handler.js +3 -2
- package/dist/primitives/preprocessor.handler.js.map +1 -1
- package/dist/primitives/skill.handler.d.ts.map +1 -1
- package/dist/primitives/skill.handler.js +8 -2
- package/dist/primitives/skill.handler.js.map +1 -1
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +4 -1
- package/dist/services/auth.js.map +1 -1
- package/dist/services/sandbox.service.d.ts +2 -1
- package/dist/services/sandbox.service.d.ts.map +1 -1
- package/dist/services/sandbox.service.js.map +1 -1
- package/dist/types/api-contracts.d.ts +4 -3
- package/dist/types/api-contracts.d.ts.map +1 -1
- package/dist/types/skill.d.ts +12 -3
- package/dist/types/skill.d.ts.map +1 -1
- package/dist/types/skill.js +17 -0
- package/dist/types/skill.js.map +1 -1
- package/dist/types/yaml.types.d.ts +6 -0
- package/dist/types/yaml.types.d.ts.map +1 -1
- package/dist/utils/artifact-loader.d.ts +2 -1
- package/dist/utils/artifact-loader.d.ts.map +1 -1
- package/dist/utils/artifact-loader.js.map +1 -1
- package/dist/utils/backup-helpers.d.ts.map +1 -1
- package/dist/utils/backup-helpers.js +12 -2
- package/dist/utils/backup-helpers.js.map +1 -1
- package/dist/utils/build-manifest-from-disk.d.ts +17 -0
- package/dist/utils/build-manifest-from-disk.d.ts.map +1 -0
- package/dist/utils/build-manifest-from-disk.js +111 -0
- package/dist/utils/build-manifest-from-disk.js.map +1 -0
- package/dist/utils/cli.d.ts.map +1 -1
- package/dist/utils/cli.js +34 -1
- package/dist/utils/cli.js.map +1 -1
- package/dist/utils/init-agent.d.ts +2 -1
- package/dist/utils/init-agent.d.ts.map +1 -1
- package/dist/utils/init-agent.js.map +1 -1
- package/dist/utils/init-helpers.d.ts +2 -1
- package/dist/utils/init-helpers.d.ts.map +1 -1
- package/dist/utils/init-helpers.js +3 -1
- package/dist/utils/init-helpers.js.map +1 -1
- package/dist/utils/init-prompts.d.ts +20 -1
- package/dist/utils/init-prompts.d.ts.map +1 -1
- package/dist/utils/init-prompts.js +88 -0
- package/dist/utils/init-prompts.js.map +1 -1
- package/dist/utils/sync-display.d.ts +2 -1
- package/dist/utils/sync-display.d.ts.map +1 -1
- package/dist/utils/sync-display.js +5 -1
- package/dist/utils/sync-display.js.map +1 -1
- package/dist/utils/sync-fetch.d.ts +6 -4
- package/dist/utils/sync-fetch.d.ts.map +1 -1
- package/dist/utils/sync-fetch.js +31 -1
- package/dist/utils/sync-fetch.js.map +1 -1
- package/docs/api/LuaAgent.md +21 -3
- package/docs/api/LuaSkill.md +22 -4
- package/node_modules/@lua/shared-types/dist/index.d.mts +120 -1
- package/node_modules/@lua/shared-types/dist/index.d.ts +120 -1
- package/node_modules/@lua/shared-types/dist/index.js +137 -2
- package/node_modules/@lua/shared-types/dist/index.mjs +129 -1
- package/node_modules/@lua/shared-types/src/chat-history.types.ts +112 -0
- package/node_modules/@lua/shared-types/src/index.ts +2 -0
- package/node_modules/@lua/shared-types/src/persona-text.type.ts +92 -0
- package/package.json +1 -1
- package/template/package.json +1 -1
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
+
// src/persona-text.type.ts
|
|
5
|
+
function isPersonaTextObject(value) {
|
|
6
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
7
|
+
const obj = value;
|
|
8
|
+
for (const k of Object.keys(obj)) {
|
|
9
|
+
if (k !== "base" && k !== "voice" && k !== "text") return false;
|
|
10
|
+
if (obj[k] !== void 0 && typeof obj[k] !== "string") return false;
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
__name(isPersonaTextObject, "isPersonaTextObject");
|
|
15
|
+
function flattenPersonaText(input, isVoice = false) {
|
|
16
|
+
if (input == null) return "";
|
|
17
|
+
if (typeof input === "string") return input;
|
|
18
|
+
const parts = [];
|
|
19
|
+
if (input.base) parts.push(input.base);
|
|
20
|
+
const channelText = isVoice ? input.voice : input.text;
|
|
21
|
+
if (channelText) parts.push(channelText);
|
|
22
|
+
return parts.join("\n\n");
|
|
23
|
+
}
|
|
24
|
+
__name(flattenPersonaText, "flattenPersonaText");
|
|
25
|
+
function flattenPersonaTextAll(input) {
|
|
26
|
+
if (input == null) return "";
|
|
27
|
+
if (typeof input === "string") return input;
|
|
28
|
+
const parts = [];
|
|
29
|
+
if (input.base) parts.push(input.base);
|
|
30
|
+
if (input.voice) parts.push(input.voice);
|
|
31
|
+
if (input.text) parts.push(input.text);
|
|
32
|
+
return parts.join("\n\n");
|
|
33
|
+
}
|
|
34
|
+
__name(flattenPersonaTextAll, "flattenPersonaTextAll");
|
|
35
|
+
function hasPersonaTextContent(input) {
|
|
36
|
+
if (input == null) return false;
|
|
37
|
+
if (typeof input === "string") return input.trim().length > 0;
|
|
38
|
+
return Boolean(input.base?.trim() || input.voice?.trim() || input.text?.trim());
|
|
39
|
+
}
|
|
40
|
+
__name(hasPersonaTextContent, "hasPersonaTextContent");
|
|
41
|
+
function personaToLiteral(persona) {
|
|
42
|
+
const formatValue = /* @__PURE__ */ __name((v) => {
|
|
43
|
+
if (v.includes("\n")) {
|
|
44
|
+
return "`" + v.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$") + "`";
|
|
45
|
+
}
|
|
46
|
+
return '"' + v.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';
|
|
47
|
+
}, "formatValue");
|
|
48
|
+
if (typeof persona === "string") return formatValue(persona);
|
|
49
|
+
const parts = [];
|
|
50
|
+
if (persona.base !== void 0) parts.push(`base: ${formatValue(persona.base)}`);
|
|
51
|
+
if (persona.voice !== void 0) parts.push(`voice: ${formatValue(persona.voice)}`);
|
|
52
|
+
if (persona.text !== void 0) parts.push(`text: ${formatValue(persona.text)}`);
|
|
53
|
+
return `{ ${parts.join(", ")} }`;
|
|
54
|
+
}
|
|
55
|
+
__name(personaToLiteral, "personaToLiteral");
|
|
56
|
+
|
|
4
57
|
// src/unstructured-types.ts
|
|
5
58
|
var UNSTRUCTURED_SUPPORTED_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
6
59
|
// PDF
|
|
@@ -74,6 +127,74 @@ function aiGenerateInputFromSimplified(prompt, content) {
|
|
|
74
127
|
}
|
|
75
128
|
__name(aiGenerateInputFromSimplified, "aiGenerateInputFromSimplified");
|
|
76
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
|
+
|
|
77
198
|
// src/sandbox-contract.ts
|
|
78
199
|
var REQUIRED_PRIMITIVE_SHIMS = [
|
|
79
200
|
// Class-based
|
|
@@ -262,5 +383,12 @@ export {
|
|
|
262
383
|
REQUIRED_UTILITIES,
|
|
263
384
|
UNSTRUCTURED_SUPPORTED_MEDIA_TYPES,
|
|
264
385
|
aiGenerateInputFromSimplified,
|
|
265
|
-
buildDefaultPersona
|
|
386
|
+
buildDefaultPersona,
|
|
387
|
+
flattenPersonaText,
|
|
388
|
+
flattenPersonaTextAll,
|
|
389
|
+
hasPersonaTextContent,
|
|
390
|
+
isPersonaTextObject,
|
|
391
|
+
personaToLiteral,
|
|
392
|
+
removeNavigateBlock,
|
|
393
|
+
transformChatHistoryContentParts
|
|
266
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
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export * from './channel.type';
|
|
2
|
+
export * from './persona-text.type';
|
|
2
3
|
export * from './unstructured-types';
|
|
3
4
|
export * from './ai-generate.types';
|
|
4
5
|
export * from './ai-generate.utils';
|
|
5
6
|
export * from './agent-invocation.types';
|
|
7
|
+
export * from './chat-history.types';
|
|
6
8
|
export * from './sandbox-contract';
|
|
7
9
|
export * from './device.types';
|
|
8
10
|
export * from './client-tools.types';
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polymorphic shape used by `LuaAgent.persona`. String form is the legacy
|
|
3
|
+
* single-channel persona; object form lets the customer split prose per
|
|
4
|
+
* channel (`base` always rendered; `voice` appended on voice; `text`
|
|
5
|
+
* appended on text channels).
|
|
6
|
+
*/
|
|
7
|
+
export type PersonaText = string | { base?: string; voice?: string; text?: string };
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Same shape as `PersonaText`, exported separately because skill `context`
|
|
11
|
+
* and agent `persona` play different semantic roles. Sharing the structural
|
|
12
|
+
* shape today keeps the runtime lean; future divergence is a one-line change.
|
|
13
|
+
*/
|
|
14
|
+
export type SkillContextText = string | { base?: string; voice?: string; text?: string };
|
|
15
|
+
|
|
16
|
+
export function isPersonaTextObject(value: unknown): value is { base?: string; voice?: string; text?: string } {
|
|
17
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
18
|
+
const obj = value as Record<string, unknown>;
|
|
19
|
+
for (const k of Object.keys(obj)) {
|
|
20
|
+
if (k !== 'base' && k !== 'voice' && k !== 'text') return false;
|
|
21
|
+
if (obj[k] !== undefined && typeof obj[k] !== 'string') return false;
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Flatten `PersonaText` or `SkillContextText` to a plain string suitable for
|
|
28
|
+
* LLM prompt injection. `base` is always emitted; `voice` is appended on
|
|
29
|
+
* voice channels and `text` on text channels. Strict — missing channel keys
|
|
30
|
+
* render nothing (no cross-channel fallback).
|
|
31
|
+
*/
|
|
32
|
+
export function flattenPersonaText(input: PersonaText | SkillContextText | null | undefined, isVoice = false): string {
|
|
33
|
+
if (input == null) return '';
|
|
34
|
+
if (typeof input === 'string') return input;
|
|
35
|
+
const parts: string[] = [];
|
|
36
|
+
if (input.base) parts.push(input.base);
|
|
37
|
+
const channelText = isVoice ? input.voice : input.text;
|
|
38
|
+
if (channelText) parts.push(channelText);
|
|
39
|
+
return parts.join('\n\n');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Channel-agnostic flatten — concatenates every non-empty channel's content
|
|
44
|
+
* (base + voice + text) for paths that aren't a render-time prompt injection,
|
|
45
|
+
* e.g. AI persona enhancement (storytelling, instructions, website-derived).
|
|
46
|
+
* Use this whenever the call has no channel context but still wants the full
|
|
47
|
+
* persona content — `flattenPersonaText` would silently drop voice or text
|
|
48
|
+
* branches because it defaults to text-channel rendering.
|
|
49
|
+
*/
|
|
50
|
+
export function flattenPersonaTextAll(input: PersonaText | SkillContextText | null | undefined): string {
|
|
51
|
+
if (input == null) return '';
|
|
52
|
+
if (typeof input === 'string') return input;
|
|
53
|
+
const parts: string[] = [];
|
|
54
|
+
if (input.base) parts.push(input.base);
|
|
55
|
+
if (input.voice) parts.push(input.voice);
|
|
56
|
+
if (input.text) parts.push(input.text);
|
|
57
|
+
return parts.join('\n\n');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* True when the persona has ANY non-empty content on any channel. Used at
|
|
62
|
+
* push/skip boundaries where channel context is not yet known.
|
|
63
|
+
*/
|
|
64
|
+
export function hasPersonaTextContent(input: PersonaText | SkillContextText | null | undefined): boolean {
|
|
65
|
+
if (input == null) return false;
|
|
66
|
+
if (typeof input === 'string') return input.trim().length > 0;
|
|
67
|
+
return Boolean(input.base?.trim() || input.voice?.trim() || input.text?.trim());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Convert a PersonaText into a TypeScript source-code literal suitable
|
|
72
|
+
* for ts-morph setInitializer or template rendering.
|
|
73
|
+
*
|
|
74
|
+
* - String form → `"..."` (double-quoted) or template literal (when newlines present)
|
|
75
|
+
* - Object form → `{ base: ..., voice: ..., text: ... }` with same per-key rule
|
|
76
|
+
*/
|
|
77
|
+
export function personaToLiteral(persona: PersonaText): string {
|
|
78
|
+
const formatValue = (v: string): string => {
|
|
79
|
+
if (v.includes('\n')) {
|
|
80
|
+
return '`' + v.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\$/g, '\\$') + '`';
|
|
81
|
+
}
|
|
82
|
+
return '"' + v.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
if (typeof persona === 'string') return formatValue(persona);
|
|
86
|
+
|
|
87
|
+
const parts: string[] = [];
|
|
88
|
+
if (persona.base !== undefined) parts.push(`base: ${formatValue(persona.base)}`);
|
|
89
|
+
if (persona.voice !== undefined) parts.push(`voice: ${formatValue(persona.voice)}`);
|
|
90
|
+
if (persona.text !== undefined) parts.push(`text: ${formatValue(persona.text)}`);
|
|
91
|
+
return `{ ${parts.join(', ')} }`;
|
|
92
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lua-cli",
|
|
3
|
-
"version": "3.
|
|
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",
|