openmates 0.16.0-alpha.1 → 0.16.0-alpha.10
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.
|
@@ -21607,6 +21607,13 @@ var OpenMatesPlans = class {
|
|
|
21607
21607
|
return response.entries ?? [];
|
|
21608
21608
|
}
|
|
21609
21609
|
async getRawPlan(planId) {
|
|
21610
|
+
try {
|
|
21611
|
+
const response = await this.client.get(`/v1/user-plans/${encodeURIComponent(planId)}`);
|
|
21612
|
+
if (!response.plan) throw new OpenMatesApiError(500, { detail: "User plan response missing plan" });
|
|
21613
|
+
return response.plan;
|
|
21614
|
+
} catch (error) {
|
|
21615
|
+
if (!(error instanceof OpenMatesApiError) || error.status !== 404) throw error;
|
|
21616
|
+
}
|
|
21610
21617
|
const plans = await this.listRaw({ activeOnly: false });
|
|
21611
21618
|
const plan = plans.find((candidate) => candidate.plan_id === planId || candidate.plan_id?.startsWith(planId));
|
|
21612
21619
|
if (!plan) throw new OpenMatesApiError(404, { detail: "Plan not found" });
|
|
@@ -24640,6 +24647,7 @@ var CORE_WORKER_SERVICES = [
|
|
|
24640
24647
|
"task-worker",
|
|
24641
24648
|
"user-init-worker",
|
|
24642
24649
|
"core-worker",
|
|
24650
|
+
"reminder-worker",
|
|
24643
24651
|
"task-scheduler",
|
|
24644
24652
|
"app-ai-worker",
|
|
24645
24653
|
"app-images-worker",
|
|
@@ -24652,6 +24660,7 @@ var CORE_WORKER_SERVICES = [
|
|
|
24652
24660
|
];
|
|
24653
24661
|
var OPENMATESCLOUD_OVERLAY_DIR = "OpenMatesCloud";
|
|
24654
24662
|
var OPENMATESCLOUD_COMPOSE_FILE = "docker-compose.openmatescloud.yml";
|
|
24663
|
+
var OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE = "backend/core/docker-compose.no-webapp.yml";
|
|
24655
24664
|
var SOURCE_COMPOSE_FILES = {
|
|
24656
24665
|
core: "backend/core/docker-compose.yml",
|
|
24657
24666
|
upload: "backend/upload/docker-compose.yml",
|
|
@@ -24724,6 +24733,7 @@ var INTEGRATION_SECRET_PREFIXES = [
|
|
|
24724
24733
|
"SECRET__REVOLUT_BUSINESS__",
|
|
24725
24734
|
"SECRET__INVOICE_"
|
|
24726
24735
|
];
|
|
24736
|
+
var CELERY_PROBE_CHECK_TIMEOUT_SECONDS = 15;
|
|
24727
24737
|
var RUNTIME_CHECKS = {
|
|
24728
24738
|
core: [
|
|
24729
24739
|
{ id: "compose.required_services", required: true, timeoutSeconds: 15 },
|
|
@@ -24731,8 +24741,8 @@ var RUNTIME_CHECKS = {
|
|
|
24731
24741
|
{ id: "core.database", required: true, timeoutSeconds: 10 },
|
|
24732
24742
|
{ id: "core.cache", required: true, timeoutSeconds: 10 },
|
|
24733
24743
|
{ id: "core.vault", required: true, timeoutSeconds: 10 },
|
|
24734
|
-
{ id: "core.worker_queue", required: true, timeoutSeconds:
|
|
24735
|
-
{ id: "core.scheduler_freshness", required: true, timeoutSeconds:
|
|
24744
|
+
{ id: "core.worker_queue", required: true, timeoutSeconds: CELERY_PROBE_CHECK_TIMEOUT_SECONDS },
|
|
24745
|
+
{ id: "core.scheduler_freshness", required: true, timeoutSeconds: CELERY_PROBE_CHECK_TIMEOUT_SECONDS },
|
|
24736
24746
|
{ id: "core.chat_plumbing", required: true, timeoutSeconds: 20 }
|
|
24737
24747
|
],
|
|
24738
24748
|
upload: [
|
|
@@ -24867,7 +24877,7 @@ function planOpenMatesCloudOverlay(input) {
|
|
|
24867
24877
|
deploymentMode,
|
|
24868
24878
|
enabled: true,
|
|
24869
24879
|
overlayPath,
|
|
24870
|
-
composeFiles: [overlayComposeFile],
|
|
24880
|
+
composeFiles: [overlayComposeFile, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE],
|
|
24871
24881
|
env: {
|
|
24872
24882
|
OPENMATES_CLOUD_OVERLAY_ENABLED: "true",
|
|
24873
24883
|
OPENMATES_CLOUD_OVERLAY_PATH: overlayPath
|
|
@@ -24937,6 +24947,7 @@ function appendSelectedServices(args, selectedServices, filterRequested) {
|
|
|
24937
24947
|
function shouldCheckWebHealth(input) {
|
|
24938
24948
|
const role = parseServerRole(input.role);
|
|
24939
24949
|
if (role !== "core") return false;
|
|
24950
|
+
if (input.deploymentMode === "official_cloud") return false;
|
|
24940
24951
|
return input.filterRequested !== true || (input.selectedServices ?? []).includes("webapp");
|
|
24941
24952
|
}
|
|
24942
24953
|
function planUpdate(input) {
|
|
@@ -25475,6 +25486,7 @@ var ROLE_TEMPLATE_FILES = {
|
|
|
25475
25486
|
upload: join6("upload", "docker-compose.yml"),
|
|
25476
25487
|
preview: join6("preview", "docker-compose.preview.yml")
|
|
25477
25488
|
};
|
|
25489
|
+
var CORE_NO_WEBAPP_TEMPLATE_FILE = join6("core", "docker-compose.no-webapp.yml");
|
|
25478
25490
|
var CORE_PROMTAIL_CONFIG_FILE = join6("backend", "core", "monitoring", "promtail", "promtail-config.yaml");
|
|
25479
25491
|
var COMPOSE_OVERRIDE2 = join6("backend", "core", "docker-compose.override.yml");
|
|
25480
25492
|
var DEFAULT_INSTALL_PATH = join6(homedir6(), "openmates");
|
|
@@ -25726,6 +25738,12 @@ function getServerDeploymentMode(flags, config) {
|
|
|
25726
25738
|
if (typeof flags["deployment-mode"] === "string") return normalizeServerDeploymentMode(flags["deployment-mode"]);
|
|
25727
25739
|
return normalizeServerDeploymentMode(config?.deploymentMode);
|
|
25728
25740
|
}
|
|
25741
|
+
function getInstallDeploymentMode(installPath, config) {
|
|
25742
|
+
const env = readEnvMap(installPath);
|
|
25743
|
+
if (env.OPENMATES_CLOUD_OVERLAY_ENABLED === "true") return "official_cloud";
|
|
25744
|
+
if (env.OPENMATES_CLOUD_OVERLAY_ENABLED === "false") return "self_host";
|
|
25745
|
+
return normalizeServerDeploymentMode(config?.deploymentMode);
|
|
25746
|
+
}
|
|
25729
25747
|
function getOpenMatesCloudOverlayPath(flags, config) {
|
|
25730
25748
|
const explicit = flags["openmatescloud-path"] ?? flags["openmates-cloud-path"];
|
|
25731
25749
|
if (explicit === true) throw new Error("Provide an OpenMatesCloud path: --openmatescloud-path <dir>.");
|
|
@@ -25804,9 +25822,10 @@ function featureKind(featureId) {
|
|
|
25804
25822
|
return featureId.split(":", 1)[0] || "unknown";
|
|
25805
25823
|
}
|
|
25806
25824
|
function composeArgs(installPath, withOverrides, installMode = getInstallMode(installPath), role = "core") {
|
|
25807
|
-
const env = readEnvMap(installPath);
|
|
25808
25825
|
const config = loadConfigForInstallPath(installPath);
|
|
25809
|
-
const deploymentMode =
|
|
25826
|
+
const deploymentMode = getInstallDeploymentMode(installPath, config);
|
|
25827
|
+
ensureOfficialCloudNoWebappComposeFile(installPath, deploymentMode, role);
|
|
25828
|
+
const env = readEnvMap(installPath);
|
|
25810
25829
|
const overlayPath = env.OPENMATES_CLOUD_OVERLAY_PATH || config?.openMatesCloudOverlayPath || void 0;
|
|
25811
25830
|
const resolvedOverlayPath = overlayPath ?? defaultOpenMatesCloudOverlayPath(installPath);
|
|
25812
25831
|
const overlayComposeFile = defaultOpenMatesCloudComposeFile(resolvedOverlayPath);
|
|
@@ -25950,9 +25969,34 @@ async function fetchText(url) {
|
|
|
25950
25969
|
function packagedTemplatePath(role) {
|
|
25951
25970
|
return join6(dirname5(new URL(import.meta.url).pathname), "..", "templates", ROLE_TEMPLATE_FILES[role]);
|
|
25952
25971
|
}
|
|
25972
|
+
function packagedNoWebappTemplatePath() {
|
|
25973
|
+
return join6(dirname5(new URL(import.meta.url).pathname), "..", "templates", CORE_NO_WEBAPP_TEMPLATE_FILE);
|
|
25974
|
+
}
|
|
25953
25975
|
function packagedCaddyTemplatePath(role) {
|
|
25954
25976
|
return join6(dirname5(new URL(import.meta.url).pathname), "..", "templates", "caddy", role, "Caddyfile");
|
|
25955
25977
|
}
|
|
25978
|
+
function readOfficialCloudNoWebappComposeTemplate() {
|
|
25979
|
+
const packaged = packagedNoWebappTemplatePath();
|
|
25980
|
+
if (existsSync8(packaged)) return readFileSync6(packaged, "utf-8");
|
|
25981
|
+
return [
|
|
25982
|
+
"# backend/core/docker-compose.no-webapp.yml",
|
|
25983
|
+
"#",
|
|
25984
|
+
"# Keeps official OpenMatesCloud core runtimes backend-only while regular",
|
|
25985
|
+
"# self-host installs continue to start the webapp from the base compose file.",
|
|
25986
|
+
"",
|
|
25987
|
+
"services:",
|
|
25988
|
+
" webapp:",
|
|
25989
|
+
' profiles: ["webapp"]',
|
|
25990
|
+
""
|
|
25991
|
+
].join("\n");
|
|
25992
|
+
}
|
|
25993
|
+
function ensureOfficialCloudNoWebappComposeFile(installPath, deploymentMode, role) {
|
|
25994
|
+
if (deploymentMode !== "official_cloud" || role !== "core") return;
|
|
25995
|
+
const filePath = join6(installPath, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE);
|
|
25996
|
+
if (existsSync8(filePath)) return;
|
|
25997
|
+
mkdirSync5(dirname5(filePath), { recursive: true });
|
|
25998
|
+
writeFileSync4(filePath, readOfficialCloudNoWebappComposeTemplate());
|
|
25999
|
+
}
|
|
25956
26000
|
function fileHash(path2) {
|
|
25957
26001
|
if (!existsSync8(path2)) return null;
|
|
25958
26002
|
return createHash12("sha256").update(readFileSync6(path2)).digest("hex");
|
|
@@ -25976,6 +26020,9 @@ async function writeImageModeRuntimeFiles(installPath, imageTag, role) {
|
|
|
25976
26020
|
mkdirSync5(vaultConfigDir, { recursive: true });
|
|
25977
26021
|
mkdirSync5(join6(installPath, "config", "providers"), { recursive: true });
|
|
25978
26022
|
writeFileSync4(join6(installPath, ROLE_IMAGE_COMPOSE_FILES[role]), await loadSelfHostComposeTemplate(templateRefForImageTag(imageTag, getPackageVersion()), role));
|
|
26023
|
+
if (role === "core") {
|
|
26024
|
+
writeFileSync4(join6(installPath, OFFICIAL_CLOUD_NO_WEBAPP_COMPOSE_FILE), readOfficialCloudNoWebappComposeTemplate());
|
|
26025
|
+
}
|
|
25979
26026
|
if (role === "core") {
|
|
25980
26027
|
const promtailConfigPath = join6(installPath, CORE_PROMTAIL_CONFIG_FILE);
|
|
25981
26028
|
mkdirSync5(dirname5(promtailConfigPath), { recursive: true });
|
|
@@ -26711,6 +26758,7 @@ async function serverStart(flags) {
|
|
|
26711
26758
|
const config = loadConfigForInstallPath(installPath);
|
|
26712
26759
|
const role = getServerRole(flags, config);
|
|
26713
26760
|
const installMode = getInstallMode(installPath, config);
|
|
26761
|
+
const deploymentMode = getInstallDeploymentMode(installPath, config);
|
|
26714
26762
|
const pullArgs = [...composeArgs(installPath, withOverrides, installMode, role), "pull"];
|
|
26715
26763
|
const args = [...composeArgs(installPath, withOverrides, installMode, role), "up", "-d"];
|
|
26716
26764
|
if (hasServiceFilter(flags)) {
|
|
@@ -26733,8 +26781,12 @@ async function serverStart(flags) {
|
|
|
26733
26781
|
printJson({ command: "start", status: "success", path: installPath });
|
|
26734
26782
|
} else {
|
|
26735
26783
|
console.log("\nServer started.");
|
|
26736
|
-
console.log("Web app: http://localhost:5173");
|
|
26737
26784
|
console.log("API: http://localhost:8000");
|
|
26785
|
+
if (deploymentMode === "official_cloud") {
|
|
26786
|
+
console.log("Web app: deployed separately for official cloud");
|
|
26787
|
+
} else {
|
|
26788
|
+
console.log("Web app: http://localhost:5173");
|
|
26789
|
+
}
|
|
26738
26790
|
if (withOverrides) {
|
|
26739
26791
|
console.log("Directus CMS: http://localhost:8055");
|
|
26740
26792
|
console.log("Grafana: http://localhost:3000");
|
|
@@ -27160,6 +27212,7 @@ async function serverUpdate(rest, flags) {
|
|
|
27160
27212
|
const role = getServerRole(flags, config);
|
|
27161
27213
|
const withOverrides = config?.composeProfile === "full";
|
|
27162
27214
|
const installMode = getInstallMode(installPath, config);
|
|
27215
|
+
const deploymentMode = getInstallDeploymentMode(installPath, config);
|
|
27163
27216
|
const filterRequested = hasServiceFilter(flags);
|
|
27164
27217
|
const selectedServices = filterRequested ? selectedComposeServices(role, flags) : [];
|
|
27165
27218
|
const missingEnvKeys = missingRequiredEnvKeys(installPath, role);
|
|
@@ -27272,7 +27325,7 @@ async function serverUpdate(rest, flags) {
|
|
|
27272
27325
|
try {
|
|
27273
27326
|
writeUpdateStatus(installPath, role, { status: "in_progress", targetImageTag: target.tag, sourceLinks, providerKeyReminders: secretPreflight.emptySecretEnvKeys, step: "health-check" });
|
|
27274
27327
|
await waitForServerHealth(installPath, role, {
|
|
27275
|
-
checkWebApp: shouldCheckWebHealth({ role, selectedServices, filterRequested })
|
|
27328
|
+
checkWebApp: shouldCheckWebHealth({ role, deploymentMode, selectedServices, filterRequested })
|
|
27276
27329
|
});
|
|
27277
27330
|
const runtimeOutput = runRuntimeVerification(installPath, role, config);
|
|
27278
27331
|
await persistRuntimeResult(installPath, role, runtimeOutput);
|
|
@@ -27342,14 +27395,14 @@ async function serverUpdate(rest, flags) {
|
|
|
27342
27395
|
path: installPath,
|
|
27343
27396
|
mode: "source",
|
|
27344
27397
|
selectedServices: filterRequested ? selectedServices : "all",
|
|
27345
|
-
checkWebApp: shouldCheckWebHealth({ role, selectedServices, filterRequested }),
|
|
27398
|
+
checkWebApp: shouldCheckWebHealth({ role, deploymentMode, selectedServices, filterRequested }),
|
|
27346
27399
|
dryRun: true
|
|
27347
27400
|
});
|
|
27348
27401
|
} else {
|
|
27349
27402
|
console.log("Update plan:");
|
|
27350
27403
|
console.log(" Mode: source");
|
|
27351
27404
|
console.log(` Services: ${filterRequested ? selectedServices.join(", ") : "all"}`);
|
|
27352
|
-
console.log(` Web health: ${shouldCheckWebHealth({ role, selectedServices, filterRequested }) ? "enabled" : "skipped"}`);
|
|
27405
|
+
console.log(` Web health: ${shouldCheckWebHealth({ role, deploymentMode, selectedServices, filterRequested }) ? "enabled" : "skipped"}`);
|
|
27353
27406
|
console.log(" Commands: git pull --ff-only, docker compose build, docker compose up -d, health checks");
|
|
27354
27407
|
}
|
|
27355
27408
|
return;
|
|
@@ -27397,7 +27450,7 @@ async function serverUpdate(rest, flags) {
|
|
|
27397
27450
|
);
|
|
27398
27451
|
code = await runInteractive("docker", upArgs, installPath);
|
|
27399
27452
|
if (code !== 0) process.exit(code);
|
|
27400
|
-
const checkWebApp = shouldCheckWebHealth({ role, selectedServices, filterRequested });
|
|
27453
|
+
const checkWebApp = shouldCheckWebHealth({ role, deploymentMode, selectedServices, filterRequested });
|
|
27401
27454
|
console.error(checkWebApp ? "Waiting for API and web health checks..." : "Waiting for API health checks...");
|
|
27402
27455
|
let successfulRuntimeOutput = null;
|
|
27403
27456
|
try {
|
|
@@ -45168,6 +45221,172 @@ notebook:
|
|
|
45168
45221
|
}
|
|
45169
45222
|
};
|
|
45170
45223
|
|
|
45224
|
+
// ../ui/src/demo_chats/data/example_chats/audio-generate-product-success-chime.ts
|
|
45225
|
+
var audioGenerateProductSuccessChimeChat = {
|
|
45226
|
+
chat_id: "example-audio-generate-product-success-chime",
|
|
45227
|
+
slug: "audio-generate-product-success-chime",
|
|
45228
|
+
title: "example_chats.audio_generate_product_success_chime.title",
|
|
45229
|
+
summary: "example_chats.audio_generate_product_success_chime.summary",
|
|
45230
|
+
icon: "volume2",
|
|
45231
|
+
category: "design",
|
|
45232
|
+
keywords: ["audio generation", "sound effects", "ElevenLabs", "product sound", "OpenMates apps"],
|
|
45233
|
+
follow_up_suggestions: [],
|
|
45234
|
+
messages: [
|
|
45235
|
+
{
|
|
45236
|
+
id: "0fe80324-42f5-4b87-9e11-0b0d8f36c9d5",
|
|
45237
|
+
role: "user",
|
|
45238
|
+
content: "example_chats.audio_generate_product_success_chime.message_1",
|
|
45239
|
+
created_at: 1786382134
|
|
45240
|
+
},
|
|
45241
|
+
{
|
|
45242
|
+
id: "87bb2a45-d06b-4afa-8a4d-d2f4173647b8",
|
|
45243
|
+
role: "assistant",
|
|
45244
|
+
content: "example_chats.audio_generate_product_success_chime.message_2",
|
|
45245
|
+
created_at: 1786382154,
|
|
45246
|
+
user_message_id: "0fe80324-42f5-4b87-9e11-0b0d8f36c9d5",
|
|
45247
|
+
response_credits: 31,
|
|
45248
|
+
category: "general_knowledge",
|
|
45249
|
+
model_name: "Gemini 3.5 Flash-Lite"
|
|
45250
|
+
}
|
|
45251
|
+
],
|
|
45252
|
+
embeds: [
|
|
45253
|
+
{
|
|
45254
|
+
embed_id: "8d96310e-a05a-41e8-a687-08ce2ce1ce9a",
|
|
45255
|
+
type: "app_skill_use",
|
|
45256
|
+
content: 'app_id: audio\nskill_id: generate\ntype: audio\nstatus: finished\nprompt: "Create a short, friendly success chime for an OpenMates workflow finishing"\ngeneration_type: sound_effect\nprovider: ElevenLabs\nmodel: eleven_text_to_sound_v2\nmime_type: audio/mpeg\nduration_seconds: 0.679\nbyte_length: 3531\npreviewAudioUrl: /store-examples/audio-generate-product-success-chime.mp3\nfiles:\n original:\n size_bytes: 3531\n format: mp3\n mime_type: audio/mpeg\n duration_seconds: 0.679\ngenerated_at: "2026-08-11T02:30:00.000000+00:00"\nwatermarking: Static public fixture',
|
|
45257
|
+
parent_embed_id: null,
|
|
45258
|
+
embed_ids: null
|
|
45259
|
+
}
|
|
45260
|
+
],
|
|
45261
|
+
usage_entries: [
|
|
45262
|
+
{
|
|
45263
|
+
id: "example-audio-generate-product-success-chime-usage-1",
|
|
45264
|
+
type: "skill_execution",
|
|
45265
|
+
source: "chat",
|
|
45266
|
+
app_id: "ai",
|
|
45267
|
+
skill_id: "ask",
|
|
45268
|
+
model_used: "google/gemini-3.5-flash-lite",
|
|
45269
|
+
credits: 17,
|
|
45270
|
+
input_tokens: 18477,
|
|
45271
|
+
output_tokens: 107,
|
|
45272
|
+
user_input_tokens: 185,
|
|
45273
|
+
system_prompt_tokens: 8516,
|
|
45274
|
+
server_provider: "Google AI Studio",
|
|
45275
|
+
server_region: "US",
|
|
45276
|
+
chat_id: "example-audio-generate-product-success-chime",
|
|
45277
|
+
message_id: "0fe80324-42f5-4b87-9e11-0b0d8f36c9d5",
|
|
45278
|
+
created_at: 1786382147,
|
|
45279
|
+
updated_at: 1786382147,
|
|
45280
|
+
tool_inference_iterations: 1
|
|
45281
|
+
},
|
|
45282
|
+
{
|
|
45283
|
+
id: "example-audio-generate-product-success-chime-usage-2",
|
|
45284
|
+
type: "skill_execution",
|
|
45285
|
+
source: "chat",
|
|
45286
|
+
app_id: "audio",
|
|
45287
|
+
skill_id: "generate",
|
|
45288
|
+
model_used: "elevenlabs/eleven_text_to_sound_v2",
|
|
45289
|
+
credits: 14,
|
|
45290
|
+
server_provider: "ElevenLabs",
|
|
45291
|
+
server_region: "US",
|
|
45292
|
+
chat_id: "example-audio-generate-product-success-chime",
|
|
45293
|
+
message_id: "0fe80324-42f5-4b87-9e11-0b0d8f36c9d5",
|
|
45294
|
+
created_at: 1786382144,
|
|
45295
|
+
updated_at: 1786382144,
|
|
45296
|
+
tool_inference_iterations: 0,
|
|
45297
|
+
code_run_duration_seconds: 0.679
|
|
45298
|
+
}
|
|
45299
|
+
],
|
|
45300
|
+
metadata: {
|
|
45301
|
+
featured: true,
|
|
45302
|
+
order: 123,
|
|
45303
|
+
app_skill_examples: ["audio.generate"]
|
|
45304
|
+
}
|
|
45305
|
+
};
|
|
45306
|
+
|
|
45307
|
+
// ../ui/src/demo_chats/data/example_chats/audio-speak-friendly-welcome-message.ts
|
|
45308
|
+
var audioSpeakFriendlyWelcomeMessageChat = {
|
|
45309
|
+
chat_id: "example-audio-speak-friendly-welcome-message",
|
|
45310
|
+
slug: "audio-speak-friendly-welcome-message",
|
|
45311
|
+
title: "example_chats.audio_speak_friendly_welcome_message.title",
|
|
45312
|
+
summary: "example_chats.audio_speak_friendly_welcome_message.summary",
|
|
45313
|
+
icon: "volume2",
|
|
45314
|
+
category: "design",
|
|
45315
|
+
keywords: ["text to speech", "ElevenLabs", "speech generation", "voice narration", "OpenMates apps"],
|
|
45316
|
+
follow_up_suggestions: [],
|
|
45317
|
+
messages: [
|
|
45318
|
+
{
|
|
45319
|
+
id: "b39cb42f-ec3e-45ec-9339-801b54c7cb03",
|
|
45320
|
+
role: "user",
|
|
45321
|
+
content: "example_chats.audio_speak_friendly_welcome_message.message_1",
|
|
45322
|
+
created_at: 1786382241
|
|
45323
|
+
},
|
|
45324
|
+
{
|
|
45325
|
+
id: "892c94f0-2c44-4d72-9c92-f27db186a103",
|
|
45326
|
+
role: "assistant",
|
|
45327
|
+
content: "example_chats.audio_speak_friendly_welcome_message.message_2",
|
|
45328
|
+
created_at: 1786382255,
|
|
45329
|
+
user_message_id: "b39cb42f-ec3e-45ec-9339-801b54c7cb03",
|
|
45330
|
+
response_credits: 28,
|
|
45331
|
+
category: "onboarding_support",
|
|
45332
|
+
model_name: "Gemini 3.5 Flash-Lite"
|
|
45333
|
+
}
|
|
45334
|
+
],
|
|
45335
|
+
embeds: [
|
|
45336
|
+
{
|
|
45337
|
+
embed_id: "463ace0f-02f9-43c2-94ee-cf385162bb75",
|
|
45338
|
+
type: "app_skill_use",
|
|
45339
|
+
content: 'app_id: audio\nskill_id: speak\ntype: audio\nstatus: finished\nprompt: "Say this as a warm, natural welcome message: Welcome back to OpenMates. Your workspace is ready whenever you are."\ntext_preview: "Welcome back to OpenMates. Your workspace is ready whenever you are."\ntext: "Welcome back to OpenMates. Your workspace is ready whenever you are."\ngeneration_type: speech\nvoice: warm_neutral\nprovider: ElevenLabs\nmodel: eleven_flash_v2_5\nmime_type: audio/mpeg\nduration_seconds: 4.968\nbyte_length: 28413\npreviewAudioUrl: /store-examples/audio-speak-friendly-welcome-message.mp3\nfiles:\n original:\n size_bytes: 28413\n format: mp3\n mime_type: audio/mpeg\n duration_seconds: 4.968\ngenerated_at: "2026-08-11T02:30:00.000000+00:00"\nwatermarking: Static public fixture',
|
|
45340
|
+
parent_embed_id: null,
|
|
45341
|
+
embed_ids: null
|
|
45342
|
+
}
|
|
45343
|
+
],
|
|
45344
|
+
usage_entries: [
|
|
45345
|
+
{
|
|
45346
|
+
id: "example-audio-speak-friendly-welcome-message-usage-1",
|
|
45347
|
+
type: "skill_execution",
|
|
45348
|
+
source: "chat",
|
|
45349
|
+
app_id: "ai",
|
|
45350
|
+
skill_id: "ask",
|
|
45351
|
+
model_used: "google/gemini-3.5-flash-lite",
|
|
45352
|
+
credits: 18,
|
|
45353
|
+
input_tokens: 19599,
|
|
45354
|
+
output_tokens: 69,
|
|
45355
|
+
user_input_tokens: 181,
|
|
45356
|
+
system_prompt_tokens: 9066,
|
|
45357
|
+
server_provider: "Google AI Studio",
|
|
45358
|
+
server_region: "US",
|
|
45359
|
+
chat_id: "example-audio-speak-friendly-welcome-message",
|
|
45360
|
+
message_id: "b39cb42f-ec3e-45ec-9339-801b54c7cb03",
|
|
45361
|
+
created_at: 1786382249,
|
|
45362
|
+
updated_at: 1786382249,
|
|
45363
|
+
tool_inference_iterations: 1
|
|
45364
|
+
},
|
|
45365
|
+
{
|
|
45366
|
+
id: "example-audio-speak-friendly-welcome-message-usage-2",
|
|
45367
|
+
type: "skill_execution",
|
|
45368
|
+
source: "chat",
|
|
45369
|
+
app_id: "audio",
|
|
45370
|
+
skill_id: "speak",
|
|
45371
|
+
model_used: "elevenlabs/eleven_flash_v2_5",
|
|
45372
|
+
credits: 10,
|
|
45373
|
+
server_provider: "ElevenLabs",
|
|
45374
|
+
server_region: "US",
|
|
45375
|
+
chat_id: "example-audio-speak-friendly-welcome-message",
|
|
45376
|
+
message_id: "b39cb42f-ec3e-45ec-9339-801b54c7cb03",
|
|
45377
|
+
created_at: 1786382246,
|
|
45378
|
+
updated_at: 1786382246,
|
|
45379
|
+
tool_inference_iterations: 0,
|
|
45380
|
+
code_run_duration_seconds: 4.968
|
|
45381
|
+
}
|
|
45382
|
+
],
|
|
45383
|
+
metadata: {
|
|
45384
|
+
featured: true,
|
|
45385
|
+
order: 124,
|
|
45386
|
+
app_skill_examples: ["audio.speak"]
|
|
45387
|
+
}
|
|
45388
|
+
};
|
|
45389
|
+
|
|
45171
45390
|
// ../ui/src/demo_chats/exampleChatData.ts
|
|
45172
45391
|
var ALL_EXAMPLE_CHATS = [
|
|
45173
45392
|
giganticAirplanesChat,
|
|
@@ -45271,9 +45490,425 @@ var ALL_EXAMPLE_CHATS = [
|
|
|
45271
45490
|
berlinAiFounderMeetupsMapChat,
|
|
45272
45491
|
deutschlandticketTrainFareBreakdownChat,
|
|
45273
45492
|
berlinMitteWorkFriendlyRestaurantsChat,
|
|
45274
|
-
openMeteoWeatherNotebookChat
|
|
45493
|
+
openMeteoWeatherNotebookChat,
|
|
45494
|
+
audioGenerateProductSuccessChimeChat,
|
|
45495
|
+
audioSpeakFriendlyWelcomeMessageChat
|
|
45275
45496
|
].sort((a, b) => a.metadata.order - b.metadata.order);
|
|
45276
45497
|
|
|
45498
|
+
// ../ui/src/demo_chats/exampleChatFiles.ts
|
|
45499
|
+
var FILE_LIKE_TYPES = /* @__PURE__ */ new Set([
|
|
45500
|
+
"audio",
|
|
45501
|
+
"audio-recording",
|
|
45502
|
+
"code",
|
|
45503
|
+
"code-code",
|
|
45504
|
+
"design",
|
|
45505
|
+
"diagram",
|
|
45506
|
+
"docs",
|
|
45507
|
+
"docs-doc",
|
|
45508
|
+
"document",
|
|
45509
|
+
"image",
|
|
45510
|
+
"images-image",
|
|
45511
|
+
"mind-map",
|
|
45512
|
+
"mind_map",
|
|
45513
|
+
"model3d",
|
|
45514
|
+
"music",
|
|
45515
|
+
"notebook",
|
|
45516
|
+
"pcb_schematic",
|
|
45517
|
+
"pdf",
|
|
45518
|
+
"recording",
|
|
45519
|
+
"remotion-video",
|
|
45520
|
+
"sheet",
|
|
45521
|
+
"sheets",
|
|
45522
|
+
"sheets-sheet",
|
|
45523
|
+
"spreadsheet",
|
|
45524
|
+
"svg",
|
|
45525
|
+
"video"
|
|
45526
|
+
]);
|
|
45527
|
+
var URL_FIELDS = [
|
|
45528
|
+
"downloadUrl",
|
|
45529
|
+
"download_url",
|
|
45530
|
+
"file_url",
|
|
45531
|
+
"previewAudioUrl",
|
|
45532
|
+
"preview_audio_url",
|
|
45533
|
+
"previewImageUrl",
|
|
45534
|
+
"preview_image_url",
|
|
45535
|
+
"previewVideoUrl",
|
|
45536
|
+
"preview_video_url",
|
|
45537
|
+
"src",
|
|
45538
|
+
"url",
|
|
45539
|
+
"video_url"
|
|
45540
|
+
];
|
|
45541
|
+
var AUDIO_URL_FIELDS = [
|
|
45542
|
+
"downloadUrl",
|
|
45543
|
+
"download_url",
|
|
45544
|
+
"file_url",
|
|
45545
|
+
"previewAudioUrl",
|
|
45546
|
+
"preview_audio_url",
|
|
45547
|
+
"src",
|
|
45548
|
+
"url"
|
|
45549
|
+
];
|
|
45550
|
+
var VIDEO_URL_FIELDS = [
|
|
45551
|
+
"downloadUrl",
|
|
45552
|
+
"download_url",
|
|
45553
|
+
"file_url",
|
|
45554
|
+
"previewVideoUrl",
|
|
45555
|
+
"preview_video_url",
|
|
45556
|
+
"video_url",
|
|
45557
|
+
"src",
|
|
45558
|
+
"url",
|
|
45559
|
+
"previewImageUrl",
|
|
45560
|
+
"preview_image_url"
|
|
45561
|
+
];
|
|
45562
|
+
var IMAGE_URL_FIELDS = [
|
|
45563
|
+
"downloadUrl",
|
|
45564
|
+
"download_url",
|
|
45565
|
+
"file_url",
|
|
45566
|
+
"previewImageUrl",
|
|
45567
|
+
"preview_image_url",
|
|
45568
|
+
"src",
|
|
45569
|
+
"url"
|
|
45570
|
+
];
|
|
45571
|
+
var FILENAME_FIELDS = [
|
|
45572
|
+
"filename",
|
|
45573
|
+
"file_name",
|
|
45574
|
+
"file_path",
|
|
45575
|
+
"original_filename"
|
|
45576
|
+
];
|
|
45577
|
+
var MIME_EXTENSION = {
|
|
45578
|
+
"application/pdf": "pdf",
|
|
45579
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "xlsx",
|
|
45580
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "docx",
|
|
45581
|
+
"audio/mpeg": "mp3",
|
|
45582
|
+
"audio/wav": "wav",
|
|
45583
|
+
"image/jpeg": "jpg",
|
|
45584
|
+
"image/png": "png",
|
|
45585
|
+
"image/svg+xml": "svg",
|
|
45586
|
+
"image/webp": "webp",
|
|
45587
|
+
"model/gltf-binary": "glb",
|
|
45588
|
+
"text/html": "html",
|
|
45589
|
+
"text/markdown": "md",
|
|
45590
|
+
"text/plain": "txt",
|
|
45591
|
+
"video/mp4": "mp4"
|
|
45592
|
+
};
|
|
45593
|
+
function isRecord2(value) {
|
|
45594
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45595
|
+
}
|
|
45596
|
+
function normalizeEmbedId(embedId) {
|
|
45597
|
+
return embedId.startsWith("embed:") ? embedId.slice("embed:".length) : embedId;
|
|
45598
|
+
}
|
|
45599
|
+
function cleanString(value) {
|
|
45600
|
+
if (typeof value !== "string") return "";
|
|
45601
|
+
const trimmed = stripQuotes(value.trim());
|
|
45602
|
+
if (!trimmed || trimmed === "null" || trimmed === "undefined") return "";
|
|
45603
|
+
return trimmed;
|
|
45604
|
+
}
|
|
45605
|
+
function stripQuotes(value) {
|
|
45606
|
+
const first = value[0];
|
|
45607
|
+
if ((first === '"' || first === "'") && value.endsWith(first)) {
|
|
45608
|
+
return value.slice(1, -1).replace(/\\n/g, "\n").replace(/\\"/g, '"').replace(/\\'/g, "'");
|
|
45609
|
+
}
|
|
45610
|
+
return value;
|
|
45611
|
+
}
|
|
45612
|
+
function numberValue2(value) {
|
|
45613
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
45614
|
+
if (typeof value !== "string" || value.trim() === "") return null;
|
|
45615
|
+
const parsed = Number(value);
|
|
45616
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
45617
|
+
}
|
|
45618
|
+
function parseFlatToonFields(content) {
|
|
45619
|
+
const fields = {};
|
|
45620
|
+
for (const line of content.split("\n")) {
|
|
45621
|
+
if (!line || /^\s/.test(line)) continue;
|
|
45622
|
+
const separatorIndex = line.indexOf(":");
|
|
45623
|
+
if (separatorIndex <= 0) continue;
|
|
45624
|
+
const key = line.slice(0, separatorIndex).trim();
|
|
45625
|
+
const value = line.slice(separatorIndex + 1).trim();
|
|
45626
|
+
if (!key || value === "") continue;
|
|
45627
|
+
fields[key] = stripQuotes(value);
|
|
45628
|
+
}
|
|
45629
|
+
return fields;
|
|
45630
|
+
}
|
|
45631
|
+
function decodeEmbedContent(content) {
|
|
45632
|
+
if (isRecord2(content)) return { ...content };
|
|
45633
|
+
if (typeof content !== "string" || !content.trim()) return {};
|
|
45634
|
+
const trimmed = content.trim();
|
|
45635
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
45636
|
+
try {
|
|
45637
|
+
const parsed = JSON.parse(trimmed);
|
|
45638
|
+
return isRecord2(parsed) ? parsed : {};
|
|
45639
|
+
} catch {
|
|
45640
|
+
return parseFlatToonFields(content);
|
|
45641
|
+
}
|
|
45642
|
+
}
|
|
45643
|
+
return parseFlatToonFields(content);
|
|
45644
|
+
}
|
|
45645
|
+
function stringField2(record, keys) {
|
|
45646
|
+
for (const key of keys) {
|
|
45647
|
+
const value = cleanString(record[key]);
|
|
45648
|
+
if (value) return value;
|
|
45649
|
+
}
|
|
45650
|
+
return "";
|
|
45651
|
+
}
|
|
45652
|
+
function basenameFromUrl(url) {
|
|
45653
|
+
if (url.startsWith("data:")) return "";
|
|
45654
|
+
const withoutQuery = url.split(/[?#]/)[0] || "";
|
|
45655
|
+
return withoutQuery.split("/").pop()?.replace(/[^a-zA-Z0-9._-]/g, "_") ?? "";
|
|
45656
|
+
}
|
|
45657
|
+
function extensionFromUrl(url) {
|
|
45658
|
+
const basename4 = basenameFromUrl(url);
|
|
45659
|
+
const dotIndex = basename4.lastIndexOf(".");
|
|
45660
|
+
return dotIndex > 0 ? basename4.slice(dotIndex + 1).toLowerCase() : "";
|
|
45661
|
+
}
|
|
45662
|
+
function extensionFromLanguage(language) {
|
|
45663
|
+
const normalized = language.toLowerCase();
|
|
45664
|
+
const map = {
|
|
45665
|
+
bash: "sh",
|
|
45666
|
+
css: "css",
|
|
45667
|
+
dockerfile: "Dockerfile",
|
|
45668
|
+
html: "html",
|
|
45669
|
+
javascript: "js",
|
|
45670
|
+
json: "json",
|
|
45671
|
+
markdown: "md",
|
|
45672
|
+
python: "py",
|
|
45673
|
+
rust: "rs",
|
|
45674
|
+
svelte: "svelte",
|
|
45675
|
+
text: "txt",
|
|
45676
|
+
typescript: "ts",
|
|
45677
|
+
yaml: "yml"
|
|
45678
|
+
};
|
|
45679
|
+
return (map[normalized] ?? normalized.replace(/[^a-z0-9]/g, "")) || "txt";
|
|
45680
|
+
}
|
|
45681
|
+
function nestedFormatFromToon(content) {
|
|
45682
|
+
if (typeof content !== "string") return "";
|
|
45683
|
+
const match = content.match(/\n\s+format:\s*([^\n]+)/);
|
|
45684
|
+
return cleanString(match?.[1]);
|
|
45685
|
+
}
|
|
45686
|
+
function urlForType(type, record) {
|
|
45687
|
+
if (type.includes("video") || type === "remotion-video") return stringField2(record, VIDEO_URL_FIELDS);
|
|
45688
|
+
if (type.includes("audio") || type === "music" || type === "recording") return stringField2(record, AUDIO_URL_FIELDS);
|
|
45689
|
+
if (type.includes("image") || type === "svg") return stringField2(record, IMAGE_URL_FIELDS);
|
|
45690
|
+
return stringField2(record, URL_FIELDS);
|
|
45691
|
+
}
|
|
45692
|
+
function inferFallbackExtension(type, record, content) {
|
|
45693
|
+
const mimeType = stringField2(record, ["mime_type", "file_type", "mimeType"]);
|
|
45694
|
+
if (mimeType && MIME_EXTENSION[mimeType]) return MIME_EXTENSION[mimeType];
|
|
45695
|
+
const urlExtension = extensionFromUrl(urlForType(type, record));
|
|
45696
|
+
if (urlExtension) return urlExtension;
|
|
45697
|
+
const nestedFormat = nestedFormatFromToon(content);
|
|
45698
|
+
if (nestedFormat) return nestedFormat;
|
|
45699
|
+
if (type.includes("video")) return "mp4";
|
|
45700
|
+
if (type.includes("audio") || type === "music" || type === "recording") return "mp3";
|
|
45701
|
+
if (type.includes("image")) return "png";
|
|
45702
|
+
if (type.includes("pdf")) return "pdf";
|
|
45703
|
+
if (type.includes("doc") || type === "document") return "docx";
|
|
45704
|
+
if (type.includes("sheet") || type === "spreadsheet") return "xlsx";
|
|
45705
|
+
if (type === "model3d") return "glb";
|
|
45706
|
+
if (type.includes("code") || type === "notebook" || type === "pcb_schematic") {
|
|
45707
|
+
return extensionFromLanguage(stringField2(record, ["language"]));
|
|
45708
|
+
}
|
|
45709
|
+
return "txt";
|
|
45710
|
+
}
|
|
45711
|
+
function inferTitle(embedId, type, record, content) {
|
|
45712
|
+
const url = urlForType(type, record);
|
|
45713
|
+
const urlBasename = basenameFromUrl(url);
|
|
45714
|
+
const filename = stringField2(record, FILENAME_FIELDS);
|
|
45715
|
+
if ((type.includes("video") || type === "music" || type === "audio") && urlBasename) {
|
|
45716
|
+
return urlBasename;
|
|
45717
|
+
}
|
|
45718
|
+
if (filename) return filename.replace(/[/\\]/g, "_");
|
|
45719
|
+
if (urlBasename) return urlBasename;
|
|
45720
|
+
const title = stringField2(record, ["title"]);
|
|
45721
|
+
if (title) {
|
|
45722
|
+
const extension2 = inferFallbackExtension(type, record, content);
|
|
45723
|
+
return `${title.replace(/[^a-zA-Z0-9._ -]/g, "_").trim()}.${extension2}`;
|
|
45724
|
+
}
|
|
45725
|
+
const extension = inferFallbackExtension(type, record, content);
|
|
45726
|
+
return `${type || "file"}-${embedId.slice(0, 8)}.${extension}`;
|
|
45727
|
+
}
|
|
45728
|
+
function inferNodeType(title, type) {
|
|
45729
|
+
const lowerTitle = title.toLowerCase();
|
|
45730
|
+
if (type.includes("pdf") || lowerTitle.endsWith(".pdf")) return "pdf";
|
|
45731
|
+
if (type.includes("image") || /\.(png|jpe?g|gif|webp|svg|avif|heic|heif)$/.test(lowerTitle)) return "image";
|
|
45732
|
+
if (type.includes("video") || /\.(mp4|mov|webm|m4v)$/.test(lowerTitle)) return "video";
|
|
45733
|
+
if (type.includes("audio") || type === "music" || type === "recording" || /\.(mp3|wav|m4a|ogg|webm)$/.test(lowerTitle)) return "recording";
|
|
45734
|
+
if (type.includes("sheet") || type === "spreadsheet" || /\.(csv|xlsx?|ods)$/.test(lowerTitle)) return "sheets-sheet";
|
|
45735
|
+
if (type.includes("doc") || type === "document" || /\.(docx?|odt|rtf)$/.test(lowerTitle)) return "docs-doc";
|
|
45736
|
+
if (type === "model3d" || /\.(glb|gltf|obj|stl)$/.test(lowerTitle)) return "model3d";
|
|
45737
|
+
if (type.includes("code") || type === "notebook" || type === "pcb_schematic") return "code-code";
|
|
45738
|
+
return "file";
|
|
45739
|
+
}
|
|
45740
|
+
function iconNameForNodeType(nodeType) {
|
|
45741
|
+
if (nodeType === "pdf") return "pdf";
|
|
45742
|
+
if (nodeType === "image") return "image";
|
|
45743
|
+
if (nodeType === "video") return "video";
|
|
45744
|
+
if (nodeType === "recording") return "audio";
|
|
45745
|
+
if (nodeType === "sheets-sheet") return "sheets";
|
|
45746
|
+
if (nodeType === "docs-doc") return "document";
|
|
45747
|
+
if (nodeType === "code-code") return "coding";
|
|
45748
|
+
if (nodeType === "model3d") return "3dmodels";
|
|
45749
|
+
return "files";
|
|
45750
|
+
}
|
|
45751
|
+
function labelForNodeType(nodeType, type) {
|
|
45752
|
+
if (nodeType === "pdf") return "PDF";
|
|
45753
|
+
if (nodeType === "image") return "Image";
|
|
45754
|
+
if (nodeType === "video") return "Video";
|
|
45755
|
+
if (nodeType === "recording") return type === "music" ? "Music" : "Audio";
|
|
45756
|
+
if (nodeType === "sheets-sheet") return "Sheet";
|
|
45757
|
+
if (nodeType === "docs-doc") return "Document";
|
|
45758
|
+
if (nodeType === "code-code") return type === "notebook" ? "Notebook" : "Code file";
|
|
45759
|
+
if (nodeType === "model3d") return "3D model";
|
|
45760
|
+
return "File";
|
|
45761
|
+
}
|
|
45762
|
+
function formatBytes(bytes) {
|
|
45763
|
+
if (!bytes || bytes <= 0) return "";
|
|
45764
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
45765
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(bytes < 10 * 1024 ? 1 : 0)} KB`;
|
|
45766
|
+
return `${(bytes / (1024 * 1024)).toFixed(bytes < 10 * 1024 * 1024 ? 1 : 0)} MB`;
|
|
45767
|
+
}
|
|
45768
|
+
function plural(value, singular, pluralLabel = `${singular}s`) {
|
|
45769
|
+
return `${value} ${value === 1 ? singular : pluralLabel}`;
|
|
45770
|
+
}
|
|
45771
|
+
function buildMetadata(nodeType, type, record) {
|
|
45772
|
+
const parts = [labelForNodeType(nodeType, type)];
|
|
45773
|
+
const lineCount = numberValue2(record.line_count ?? record.lineCount);
|
|
45774
|
+
const pageCount = numberValue2(record.page_count ?? record.pageCount);
|
|
45775
|
+
const wordCount = numberValue2(record.word_count ?? record.wordCount);
|
|
45776
|
+
const duration = numberValue2(record.duration_seconds ?? record.durationSeconds);
|
|
45777
|
+
const size = numberValue2(record.byte_length ?? record.size_bytes ?? record.sizeBytes);
|
|
45778
|
+
if (lineCount) parts.push(plural(lineCount, "line"));
|
|
45779
|
+
if (pageCount) parts.push(plural(pageCount, "page"));
|
|
45780
|
+
if (wordCount) parts.push(plural(wordCount, "word"));
|
|
45781
|
+
if (duration) parts.push(`${duration.toFixed(duration < 10 ? 1 : 0)}s`);
|
|
45782
|
+
const sizeLabel = formatBytes(size);
|
|
45783
|
+
if (sizeLabel) parts.push(sizeLabel);
|
|
45784
|
+
return parts.join(" | ");
|
|
45785
|
+
}
|
|
45786
|
+
function isSupportedPublicUrl(url) {
|
|
45787
|
+
return url.startsWith("/") || url.startsWith("data:") || /^https?:\/\//i.test(url);
|
|
45788
|
+
}
|
|
45789
|
+
function extractEmbedIdsFromContent(content) {
|
|
45790
|
+
const decoded = decodeEmbedContent(content);
|
|
45791
|
+
const rawIds = decoded.embed_ids ?? decoded.embedIds;
|
|
45792
|
+
const ids = typeof rawIds === "string" ? rawIds.split(/[|,]/) : rawIds;
|
|
45793
|
+
if (!Array.isArray(ids)) return [];
|
|
45794
|
+
return ids.map((id) => cleanString(id)).filter(Boolean).map(normalizeEmbedId);
|
|
45795
|
+
}
|
|
45796
|
+
function buildEmbedLookup(embeds) {
|
|
45797
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
45798
|
+
for (const embed of embeds) {
|
|
45799
|
+
if (!embed.embed_id) continue;
|
|
45800
|
+
lookup.set(normalizeEmbedId(embed.embed_id), embed);
|
|
45801
|
+
}
|
|
45802
|
+
return lookup;
|
|
45803
|
+
}
|
|
45804
|
+
function buildEmbedRefLookup(embeds) {
|
|
45805
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
45806
|
+
for (const embed of embeds) {
|
|
45807
|
+
const embedId = normalizeEmbedId(embed.embed_id);
|
|
45808
|
+
lookup.set(embedId, embedId);
|
|
45809
|
+
lookup.set(`embed:${embedId}`, embedId);
|
|
45810
|
+
const decoded = decodeEmbedContent(embed.content);
|
|
45811
|
+
const embedRef = stringField2(decoded, ["embed_ref", "embedRef"]);
|
|
45812
|
+
if (embedRef) {
|
|
45813
|
+
lookup.set(embedRef, embedId);
|
|
45814
|
+
lookup.set(`embed:${embedRef}`, embedId);
|
|
45815
|
+
}
|
|
45816
|
+
}
|
|
45817
|
+
return lookup;
|
|
45818
|
+
}
|
|
45819
|
+
function extractReferencedExampleEmbedIds(messages, embeds) {
|
|
45820
|
+
const refLookup = buildEmbedRefLookup(embeds);
|
|
45821
|
+
const ids = /* @__PURE__ */ new Set();
|
|
45822
|
+
const jsonBlockRe = /```(?:json_embed|json)\s*([\s\S]*?)\s*```/g;
|
|
45823
|
+
const inlineEmbedRe = /embed:([a-zA-Z0-9_.:-]+)/g;
|
|
45824
|
+
for (const message of messages) {
|
|
45825
|
+
const content = message.content ?? "";
|
|
45826
|
+
for (const match of Array.from(content.matchAll(jsonBlockRe))) {
|
|
45827
|
+
try {
|
|
45828
|
+
const parsed = JSON.parse(match[1].trim());
|
|
45829
|
+
const embedId = cleanString(parsed.embed_id ?? parsed.embedId);
|
|
45830
|
+
const resolved = refLookup.get(embedId) ?? refLookup.get(`embed:${embedId}`) ?? embedId;
|
|
45831
|
+
if (resolved) ids.add(normalizeEmbedId(resolved));
|
|
45832
|
+
} catch {
|
|
45833
|
+
}
|
|
45834
|
+
}
|
|
45835
|
+
for (const match of Array.from(content.matchAll(inlineEmbedRe))) {
|
|
45836
|
+
const rawRef = match[1];
|
|
45837
|
+
const resolved = refLookup.get(rawRef) ?? refLookup.get(`embed:${rawRef}`) ?? rawRef;
|
|
45838
|
+
if (resolved) ids.add(normalizeEmbedId(resolved));
|
|
45839
|
+
}
|
|
45840
|
+
}
|
|
45841
|
+
return Array.from(ids);
|
|
45842
|
+
}
|
|
45843
|
+
function expandEmbedIds(embedIds, embeds) {
|
|
45844
|
+
const lookup = buildEmbedLookup(embeds);
|
|
45845
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45846
|
+
const queue = [...embedIds.map(normalizeEmbedId)];
|
|
45847
|
+
while (queue.length > 0) {
|
|
45848
|
+
const embedId = queue.shift();
|
|
45849
|
+
if (!embedId || seen.has(embedId)) continue;
|
|
45850
|
+
seen.add(embedId);
|
|
45851
|
+
const embed = lookup.get(embedId);
|
|
45852
|
+
if (!embed) continue;
|
|
45853
|
+
const childIds = [
|
|
45854
|
+
...embed.embed_ids ?? [],
|
|
45855
|
+
...extractEmbedIdsFromContent(embed.content)
|
|
45856
|
+
];
|
|
45857
|
+
for (const childId of childIds) {
|
|
45858
|
+
const normalizedChildId = normalizeEmbedId(childId);
|
|
45859
|
+
if (normalizedChildId && !seen.has(normalizedChildId)) queue.push(normalizedChildId);
|
|
45860
|
+
}
|
|
45861
|
+
}
|
|
45862
|
+
return Array.from(seen);
|
|
45863
|
+
}
|
|
45864
|
+
function getEmbedFileReferences(embed) {
|
|
45865
|
+
const embedId = cleanString(embed.embed_id ?? embed.embedId ?? embed.id);
|
|
45866
|
+
if (!embedId) return [];
|
|
45867
|
+
const decoded = decodeEmbedContent(embed.content);
|
|
45868
|
+
const type = (stringField2(decoded, ["type", "embed_type", "embedType"]) || cleanString(embed.type) || "file").toLowerCase();
|
|
45869
|
+
if (!FILE_LIKE_TYPES.has(type)) return [];
|
|
45870
|
+
const title = inferTitle(embedId, type, decoded, embed.content);
|
|
45871
|
+
const nodeType = inferNodeType(title, type);
|
|
45872
|
+
const url = urlForType(type, decoded);
|
|
45873
|
+
const mimeType = stringField2(decoded, ["mime_type", "file_type", "mimeType"]);
|
|
45874
|
+
const createdAt = numberValue2(embed.created_at ?? embed.createdAt) ?? 0;
|
|
45875
|
+
return [{
|
|
45876
|
+
embedId: normalizeEmbedId(embedId),
|
|
45877
|
+
contentRef: `embed:${normalizeEmbedId(embedId)}`,
|
|
45878
|
+
title,
|
|
45879
|
+
subtitle: labelForNodeType(nodeType, type),
|
|
45880
|
+
type,
|
|
45881
|
+
nodeType,
|
|
45882
|
+
iconName: iconNameForNodeType(nodeType),
|
|
45883
|
+
createdAt,
|
|
45884
|
+
updatedAt: createdAt,
|
|
45885
|
+
metadata: buildMetadata(nodeType, type, decoded),
|
|
45886
|
+
appId: stringField2(decoded, ["app_id", "appId"]) || cleanString(embed.app_id ?? embed.appId) || null,
|
|
45887
|
+
skillId: stringField2(decoded, ["skill_id", "skillId"]) || cleanString(embed.skill_id ?? embed.skillId) || null,
|
|
45888
|
+
url: url && isSupportedPublicUrl(url) ? url : null,
|
|
45889
|
+
mimeType: mimeType || null
|
|
45890
|
+
}];
|
|
45891
|
+
}
|
|
45892
|
+
function collectExampleChatFileReferences(embeds, messages = []) {
|
|
45893
|
+
if (embeds.length === 0) return [];
|
|
45894
|
+
const lookup = buildEmbedLookup(embeds);
|
|
45895
|
+
const referencedIds = extractReferencedExampleEmbedIds(messages, embeds);
|
|
45896
|
+
const candidateIds = referencedIds.length > 0 ? expandEmbedIds(referencedIds, embeds) : embeds.map((embed) => normalizeEmbedId(embed.embed_id));
|
|
45897
|
+
const rows = [];
|
|
45898
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45899
|
+
for (const embedId of candidateIds) {
|
|
45900
|
+
const embed = lookup.get(embedId);
|
|
45901
|
+
if (!embed) continue;
|
|
45902
|
+
for (const row of getEmbedFileReferences(embed)) {
|
|
45903
|
+
const key = `${row.embedId}:${row.title}`.toLowerCase();
|
|
45904
|
+
if (seen.has(key)) continue;
|
|
45905
|
+
rows.push(row);
|
|
45906
|
+
seen.add(key);
|
|
45907
|
+
}
|
|
45908
|
+
}
|
|
45909
|
+
return rows;
|
|
45910
|
+
}
|
|
45911
|
+
|
|
45277
45912
|
// ../ui/src/i18n/locales/en.json
|
|
45278
45913
|
var en_default = {
|
|
45279
45914
|
activity: {
|
|
@@ -53211,6 +53846,34 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
|
|
|
53211
53846
|
text: "[images-search] Show me more photos of the Orion spacecraft"
|
|
53212
53847
|
}
|
|
53213
53848
|
},
|
|
53849
|
+
audio_generate_product_success_chime: {
|
|
53850
|
+
title: {
|
|
53851
|
+
text: "Audio Generate Product Success Chime"
|
|
53852
|
+
},
|
|
53853
|
+
summary: {
|
|
53854
|
+
text: "Create a short product success chime with the Audio Generate app skill."
|
|
53855
|
+
},
|
|
53856
|
+
message_1: {
|
|
53857
|
+
text: "Create a short, friendly success chime for an OpenMates workflow finishing. Keep it clean, modern, and subtle enough for a product notification."
|
|
53858
|
+
},
|
|
53859
|
+
message_2: {
|
|
53860
|
+
text: '```json\n{"type":"app_skill_use","embed_id":"8d96310e-a05a-41e8-a687-08ce2ce1ce9a","app_id":"audio","skill_id":"generate"}\n```\n\nI created a short, friendly product success chime you can use as a subtle workflow-complete notification.'
|
|
53861
|
+
}
|
|
53862
|
+
},
|
|
53863
|
+
audio_speak_friendly_welcome_message: {
|
|
53864
|
+
title: {
|
|
53865
|
+
text: "Audio Speak Friendly Welcome Message"
|
|
53866
|
+
},
|
|
53867
|
+
summary: {
|
|
53868
|
+
text: "Turn a short welcome line into a friendly spoken message with the Audio Speak app skill."
|
|
53869
|
+
},
|
|
53870
|
+
message_1: {
|
|
53871
|
+
text: "Say this as a warm, natural welcome message: Welcome back to OpenMates. Your workspace is ready whenever you are."
|
|
53872
|
+
},
|
|
53873
|
+
message_2: {
|
|
53874
|
+
text: '```json\n{"type":"app_skill_use","embed_id":"463ace0f-02f9-43c2-94ee-cf385162bb75","app_id":"audio","skill_id":"speak"}\n```\n\nI generated the welcome line as a friendly spoken audio message.'
|
|
53875
|
+
}
|
|
53876
|
+
},
|
|
53214
53877
|
audio_transcribe_voice_note: {
|
|
53215
53878
|
title: {
|
|
53216
53879
|
text: "Transcribe a voice note"
|
|
@@ -66113,8 +66776,10 @@ function getExampleChatConversation(query) {
|
|
|
66113
66776
|
category: message.category ?? chat.category,
|
|
66114
66777
|
modelName: message.model_name ?? null,
|
|
66115
66778
|
createdAt: message.created_at,
|
|
66116
|
-
embedIds: []
|
|
66779
|
+
embedIds: extractReferencedExampleEmbedIds([message], chat.embeds)
|
|
66117
66780
|
})),
|
|
66781
|
+
embeds: chat.embeds,
|
|
66782
|
+
files: collectExampleChatFileReferences(chat.embeds, chat.messages),
|
|
66118
66783
|
followUpSuggestions: chat.follow_up_suggestions.map(translate)
|
|
66119
66784
|
};
|
|
66120
66785
|
}
|
|
@@ -70007,7 +70672,7 @@ async function requestProjectRemoteOperation(options) {
|
|
|
70007
70672
|
throw new ProjectRequesterError("source_offline", "The selected Project source is offline.");
|
|
70008
70673
|
}
|
|
70009
70674
|
const timeoutMs = options.timeoutMs ?? REMOTE_PROTOCOL_TIMEOUT_MS;
|
|
70010
|
-
let sourceSessionId =
|
|
70675
|
+
let sourceSessionId = stringField3(options.source, "source_session_id");
|
|
70011
70676
|
let keyEpoch = numberField(options.source, "key_epoch");
|
|
70012
70677
|
let routingIdentity = null;
|
|
70013
70678
|
if (!sourceSessionId || !keyEpoch) {
|
|
@@ -70159,7 +70824,7 @@ function parseJsonObject(value) {
|
|
|
70159
70824
|
}
|
|
70160
70825
|
throw new ProjectRequesterError("invalid_remote_payload", "The Project source returned an invalid payload.");
|
|
70161
70826
|
}
|
|
70162
|
-
function
|
|
70827
|
+
function stringField3(value, key) {
|
|
70163
70828
|
return typeof value[key] === "string" && value[key] ? value[key] : null;
|
|
70164
70829
|
}
|
|
70165
70830
|
function numberField(value, key) {
|
|
@@ -71092,7 +71757,7 @@ function splitTaskAskInstruction(instruction) {
|
|
|
71092
71757
|
const suffix = instruction.includes(":") ? instruction.split(":").slice(1).join(":") : instruction;
|
|
71093
71758
|
return suffix.split(/[,;]\s*/).map((title) => title.trim()).filter(Boolean).map((title) => ({ title }));
|
|
71094
71759
|
}
|
|
71095
|
-
function
|
|
71760
|
+
function isRecord3(value) {
|
|
71096
71761
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
71097
71762
|
}
|
|
71098
71763
|
function isPrivateCliOutputKey(key) {
|
|
@@ -71100,7 +71765,7 @@ function isPrivateCliOutputKey(key) {
|
|
|
71100
71765
|
}
|
|
71101
71766
|
function sanitizeWorkspaceAskOutput(value) {
|
|
71102
71767
|
if (Array.isArray(value)) return value.map((item) => sanitizeWorkspaceAskOutput(item));
|
|
71103
|
-
if (!
|
|
71768
|
+
if (!isRecord3(value)) return value;
|
|
71104
71769
|
const sanitized = {};
|
|
71105
71770
|
for (const [key, nested] of Object.entries(value)) {
|
|
71106
71771
|
if (isPrivateCliOutputKey(key)) continue;
|
|
@@ -71110,20 +71775,20 @@ function sanitizeWorkspaceAskOutput(value) {
|
|
|
71110
71775
|
}
|
|
71111
71776
|
async function prepareTaskAskOutput(result, masterKey) {
|
|
71112
71777
|
const output = sanitizeWorkspaceAskOutput(result);
|
|
71113
|
-
if (
|
|
71778
|
+
if (isRecord3(result.task)) {
|
|
71114
71779
|
output.task = taskToJson(await decryptUserTask(result.task, masterKey));
|
|
71115
71780
|
}
|
|
71116
|
-
if (Array.isArray(result.tasks) && result.tasks.every(
|
|
71781
|
+
if (Array.isArray(result.tasks) && result.tasks.every(isRecord3)) {
|
|
71117
71782
|
output.tasks = (await decryptUserTasks(result.tasks, masterKey)).map(taskToJson);
|
|
71118
71783
|
}
|
|
71119
71784
|
return output;
|
|
71120
71785
|
}
|
|
71121
71786
|
async function preparePlanAskOutput(result, masterKey) {
|
|
71122
71787
|
const output = sanitizeWorkspaceAskOutput(result);
|
|
71123
|
-
if (
|
|
71788
|
+
if (isRecord3(result.plan)) {
|
|
71124
71789
|
output.plan = planToJson(await decryptUserPlan(result.plan, masterKey));
|
|
71125
71790
|
}
|
|
71126
|
-
if (Array.isArray(result.plans) && result.plans.every(
|
|
71791
|
+
if (Array.isArray(result.plans) && result.plans.every(isRecord3)) {
|
|
71127
71792
|
output.plans = (await decryptUserPlans(result.plans, masterKey)).map(planToJson);
|
|
71128
71793
|
}
|
|
71129
71794
|
return output;
|
|
@@ -73437,6 +74102,28 @@ async function handleChats(client, subcommand, rest, flags, redactor) {
|
|
|
73437
74102
|
}
|
|
73438
74103
|
return;
|
|
73439
74104
|
}
|
|
74105
|
+
if (subcommand === "files") {
|
|
74106
|
+
const chatId = rest[0];
|
|
74107
|
+
if (!chatId) {
|
|
74108
|
+
throw new Error("Missing chat ID. Usage: openmates chats files <chat-id> [--json]");
|
|
74109
|
+
}
|
|
74110
|
+
const resolvedId = chatId.toLowerCase() === "last" ? "__last__" : chatId;
|
|
74111
|
+
if (apiKey) {
|
|
74112
|
+
throw new Error("Chat file listing through --api-key is not supported; use an authenticated CLI session so encrypted chat embeds can be decrypted locally.");
|
|
74113
|
+
}
|
|
74114
|
+
if (!client.hasSession()) {
|
|
74115
|
+
const example = resolveExampleChatForOpen(resolvedId === "__last__" ? "1" : resolvedId);
|
|
74116
|
+
if (!example) {
|
|
74117
|
+
throw new Error(`Example chat '${chatId}' not found. Run 'openmates chats list' to see available examples.`);
|
|
74118
|
+
}
|
|
74119
|
+
printChatFiles(example.chat, example.files, flags, { example: true });
|
|
74120
|
+
return;
|
|
74121
|
+
}
|
|
74122
|
+
const { chat, messages } = await client.getChatMessages(resolvedId, teamContext);
|
|
74123
|
+
const result = await loadChatFileReferencesForCli(client, messages);
|
|
74124
|
+
printChatFiles(chat, result.files, flags, { errors: result.errors });
|
|
74125
|
+
return;
|
|
74126
|
+
}
|
|
73440
74127
|
if (subcommand === "messages") {
|
|
73441
74128
|
const chatId = rest[0];
|
|
73442
74129
|
if (!chatId) {
|
|
@@ -74413,6 +75100,113 @@ function resolveExampleChatForOpen(target) {
|
|
|
74413
75100
|
}
|
|
74414
75101
|
return getExampleChatConversation(target);
|
|
74415
75102
|
}
|
|
75103
|
+
function collectMessageEmbedIdsForFiles(messages) {
|
|
75104
|
+
const ids = /* @__PURE__ */ new Set();
|
|
75105
|
+
const inlineEmbedRefRe = /embed:([a-zA-Z0-9_.:-]+)/g;
|
|
75106
|
+
for (const message of messages) {
|
|
75107
|
+
for (const embedId of message.embedIds ?? []) {
|
|
75108
|
+
if (embedId) ids.add(embedId);
|
|
75109
|
+
}
|
|
75110
|
+
for (const match of Array.from((message.content ?? "").matchAll(inlineEmbedRefRe))) {
|
|
75111
|
+
if (match[1]) ids.add(match[1]);
|
|
75112
|
+
}
|
|
75113
|
+
for (const segment of parseMessageSegments(message.content ?? "")) {
|
|
75114
|
+
if (segment.type === "embed" && segment.value) ids.add(segment.value);
|
|
75115
|
+
}
|
|
75116
|
+
}
|
|
75117
|
+
return Array.from(ids);
|
|
75118
|
+
}
|
|
75119
|
+
function fileReferenceKey(file) {
|
|
75120
|
+
return `${file.embedId}:${file.title}`.toLowerCase();
|
|
75121
|
+
}
|
|
75122
|
+
function chatFileReferenceFromEmbed(embed) {
|
|
75123
|
+
return getEmbedFileReferences({
|
|
75124
|
+
embedId: embed.embedId,
|
|
75125
|
+
type: embed.type,
|
|
75126
|
+
content: embed.content,
|
|
75127
|
+
appId: embed.appId,
|
|
75128
|
+
skillId: embed.skillId,
|
|
75129
|
+
createdAt: embed.createdAt
|
|
75130
|
+
});
|
|
75131
|
+
}
|
|
75132
|
+
async function loadChatFileReferencesForCli(client, messages) {
|
|
75133
|
+
const queue = collectMessageEmbedIdsForFiles(messages);
|
|
75134
|
+
const visitedEmbeds = /* @__PURE__ */ new Set();
|
|
75135
|
+
const seenFiles = /* @__PURE__ */ new Set();
|
|
75136
|
+
const files = [];
|
|
75137
|
+
const errors = [];
|
|
75138
|
+
while (queue.length > 0) {
|
|
75139
|
+
const embedId = queue.shift();
|
|
75140
|
+
if (!embedId || visitedEmbeds.has(embedId)) continue;
|
|
75141
|
+
visitedEmbeds.add(embedId);
|
|
75142
|
+
try {
|
|
75143
|
+
const embed = await client.getEmbed(embedId);
|
|
75144
|
+
for (const file of chatFileReferenceFromEmbed(embed)) {
|
|
75145
|
+
const key = fileReferenceKey(file);
|
|
75146
|
+
if (seenFiles.has(key)) continue;
|
|
75147
|
+
files.push(file);
|
|
75148
|
+
seenFiles.add(key);
|
|
75149
|
+
}
|
|
75150
|
+
for (const childId of extractEmbedIdsFromContent(embed.content)) {
|
|
75151
|
+
if (childId && !visitedEmbeds.has(childId)) queue.push(childId);
|
|
75152
|
+
}
|
|
75153
|
+
} catch (error) {
|
|
75154
|
+
errors.push({
|
|
75155
|
+
embed_id: embedId,
|
|
75156
|
+
message: error instanceof Error ? error.message : String(error)
|
|
75157
|
+
});
|
|
75158
|
+
}
|
|
75159
|
+
}
|
|
75160
|
+
return { files, errors };
|
|
75161
|
+
}
|
|
75162
|
+
function chatFileToJson(file) {
|
|
75163
|
+
return {
|
|
75164
|
+
embed_id: file.embedId,
|
|
75165
|
+
content_ref: file.contentRef,
|
|
75166
|
+
title: file.title,
|
|
75167
|
+
type: file.type,
|
|
75168
|
+
node_type: file.nodeType,
|
|
75169
|
+
metadata: file.metadata,
|
|
75170
|
+
app_id: file.appId,
|
|
75171
|
+
skill_id: file.skillId,
|
|
75172
|
+
url: file.url,
|
|
75173
|
+
mime_type: file.mimeType
|
|
75174
|
+
};
|
|
75175
|
+
}
|
|
75176
|
+
function printChatFiles(chat, files, flags, options = {}) {
|
|
75177
|
+
if (flags.json === true) {
|
|
75178
|
+
printJson2({
|
|
75179
|
+
chat_id: chat.id,
|
|
75180
|
+
title: chat.title,
|
|
75181
|
+
source: options.example ? "example" : "chat",
|
|
75182
|
+
count: files.length,
|
|
75183
|
+
files: files.map(chatFileToJson),
|
|
75184
|
+
errors: options.errors ?? []
|
|
75185
|
+
});
|
|
75186
|
+
return;
|
|
75187
|
+
}
|
|
75188
|
+
const title = chat.title ?? chat.shortId ?? chat.id;
|
|
75189
|
+
header(`Files for ${title}`);
|
|
75190
|
+
if (options.example) {
|
|
75191
|
+
process.stdout.write("\x1B[2mPublic example chat files are resolved from bundled static embed metadata.\x1B[0m\n");
|
|
75192
|
+
}
|
|
75193
|
+
if (files.length === 0) {
|
|
75194
|
+
process.stdout.write("\x1B[2mNo files found for this chat.\x1B[0m\n");
|
|
75195
|
+
} else {
|
|
75196
|
+
for (const file of files) {
|
|
75197
|
+
const appSkill = [file.appId, file.skillId].filter(Boolean).join("/");
|
|
75198
|
+
const suffix = appSkill ? ` \x1B[2m${appSkill}\x1B[0m` : "";
|
|
75199
|
+
process.stdout.write(` \x1B[1m${file.title}\x1B[0m \x1B[2m${file.metadata}\x1B[0m${suffix}
|
|
75200
|
+
`);
|
|
75201
|
+
process.stdout.write(` \x1B[2m${file.contentRef}${file.url ? ` ${file.url}` : ""}\x1B[0m
|
|
75202
|
+
`);
|
|
75203
|
+
}
|
|
75204
|
+
}
|
|
75205
|
+
for (const error of options.errors ?? []) {
|
|
75206
|
+
process.stderr.write(`Warning: could not inspect embed ${error.embed_id}: ${error.message}
|
|
75207
|
+
`);
|
|
75208
|
+
}
|
|
75209
|
+
}
|
|
74416
75210
|
async function openUrl(url) {
|
|
74417
75211
|
const { exec: exec2 } = await import("child_process");
|
|
74418
75212
|
const platform4 = process.platform;
|
|
@@ -80447,6 +81241,7 @@ function printChatsHelp() {
|
|
|
80447
81241
|
openmates chats list [--limit <n>] [--page <n>] [--json]
|
|
80448
81242
|
openmates chats show <chat-id> [--raw] [--json] [--all]
|
|
80449
81243
|
openmates chats messages <chat-id> [--json]
|
|
81244
|
+
openmates chats files <chat-id> [--json]
|
|
80450
81245
|
openmates chats <chat-id> add-to-project <project-id> [--folder <folder-id>] [--openmates-only|--repo-copy|--remote-cache-copy|--remote-copy] [--json]
|
|
80451
81246
|
openmates chats <chat-id> remove-from-project <project-id> [--json]
|
|
80452
81247
|
openmates chats fork <chat-id> --from-message <message-id> [--title <title>] [--json]
|
|
@@ -80474,6 +81269,11 @@ Options for 'show':
|
|
|
80474
81269
|
--raw Show raw decrypted message content without rendering embeds
|
|
80475
81270
|
or cleaning embed references. Useful for debugging.
|
|
80476
81271
|
|
|
81272
|
+
Options for 'files':
|
|
81273
|
+
Lists uploaded and generated files connected to a saved or public example chat.
|
|
81274
|
+
Saved chats require an authenticated CLI session so encrypted embeds can be
|
|
81275
|
+
decrypted locally. Public examples also work while logged out.
|
|
81276
|
+
|
|
80477
81277
|
Options for 'fork', 'rewind', and 'retry':
|
|
80478
81278
|
--from-message <id> Message boundary for non-destructive fork.
|
|
80479
81279
|
--to-message <id> Message boundary to keep when rewinding.
|
|
@@ -80551,6 +81351,8 @@ Examples:
|
|
|
80551
81351
|
openmates chats open gigantic-airplanes-transporting-rocket-parts
|
|
80552
81352
|
openmates chats show d262cb68
|
|
80553
81353
|
openmates chats messages d262cb68
|
|
81354
|
+
openmates chats files d262cb68
|
|
81355
|
+
openmates chats files example-audio-speak-friendly-welcome-message --json
|
|
80554
81356
|
openmates chats fork d262cb68 --from-message 8f4e2a1c --title "Clean branch"
|
|
80555
81357
|
openmates chats rewind d262cb68 --to-message 8f4e2a1c --send "Continue from here" --yes
|
|
80556
81358
|
openmates chats retry d262cb68 --yes
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -113,7 +113,8 @@ services:
|
|
|
113
113
|
test: ["CMD", "/usr/local/bin/openmates-directus-health"]
|
|
114
114
|
interval: 10s
|
|
115
115
|
timeout: 8s
|
|
116
|
-
|
|
116
|
+
# cms-setup creates the indexes validated by this health script; cold CI runners can take several minutes.
|
|
117
|
+
start_period: 10m
|
|
117
118
|
retries: 12
|
|
118
119
|
|
|
119
120
|
cms-database:
|
|
@@ -225,12 +226,25 @@ services:
|
|
|
225
226
|
mem_limit: ${CORE_WORKER_MEMORY_LIMIT:-3g}
|
|
226
227
|
environment:
|
|
227
228
|
<<: *openmates-worker-env
|
|
228
|
-
CELERY_QUEUES: persistence,health_check,server_stats,demo,e2e_tests,
|
|
229
|
+
CELERY_QUEUES: persistence,health_check,server_stats,demo,e2e_tests,push
|
|
229
230
|
CELERY_AUTOSCALE_MAX: ${CORE_WORKER_CONCURRENCY:-${CELERY_AUTOSCALE_MAX:-3}}
|
|
230
231
|
CELERY_AUTOSCALE_MIN: ${CELERY_AUTOSCALE_MIN:-1}
|
|
231
232
|
CELERY_METRICS_PORT: "9109"
|
|
232
233
|
command: >
|
|
233
|
-
sh -c "chown -R celeryuser:celeryuser /vault-data && gosu celeryuser python -m celery -A backend.core.api.app.tasks.celery_config worker --loglevel=info --queues=persistence,health_check,server_stats,demo,e2e_tests,
|
|
234
|
+
sh -c "chown -R celeryuser:celeryuser /vault-data && gosu celeryuser python -m celery -A backend.core.api.app.tasks.celery_config worker --loglevel=info --queues=persistence,health_check,server_stats,demo,e2e_tests,push --concurrency=$${CELERY_AUTOSCALE_MAX} --max-tasks-per-child=50 --max-memory-per-child=600000 --prefetch-multiplier=1"
|
|
235
|
+
|
|
236
|
+
reminder-worker:
|
|
237
|
+
<<: *openmates-worker-base
|
|
238
|
+
container_name: reminder-worker
|
|
239
|
+
mem_limit: ${REMINDER_WORKER_MEMORY_LIMIT:-1536m}
|
|
240
|
+
environment:
|
|
241
|
+
<<: *openmates-worker-env
|
|
242
|
+
CELERY_QUEUES: reminder
|
|
243
|
+
CELERY_AUTOSCALE_MAX: ${REMINDER_WORKER_CONCURRENCY:-2}
|
|
244
|
+
CELERY_AUTOSCALE_MIN: ${CELERY_AUTOSCALE_MIN:-1}
|
|
245
|
+
CELERY_METRICS_PORT: "9111"
|
|
246
|
+
command: >
|
|
247
|
+
sh -c "chown -R celeryuser:celeryuser /vault-data && gosu celeryuser python -m celery -A backend.core.api.app.tasks.celery_config worker --loglevel=info --queues=reminder --concurrency=$${CELERY_AUTOSCALE_MAX} --max-tasks-per-child=50 --max-memory-per-child=600000 --prefetch-multiplier=1"
|
|
234
248
|
|
|
235
249
|
workflow-worker:
|
|
236
250
|
<<: *openmates-worker-base
|