omnius 1.0.190 → 1.0.192
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/index.js +953 -34
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2859,7 +2859,7 @@ var init_security_classifier = __esm({
|
|
|
2859
2859
|
// ── Network reads (safe)
|
|
2860
2860
|
{ match: /^(web_search|web_fetch)$/, info: NETWORK_READ },
|
|
2861
2861
|
// ── Network outbound (mutating or remote inference)
|
|
2862
|
-
{ match: /^(image_generate|generate_image|generate_audio|generate_tts|create_audio_file|vision|video_understand|telegram_send_file)$/, info: NETWORK_OUTBOUND },
|
|
2862
|
+
{ match: /^(image_generate|generate_image|generate_audio|generate_model|generate_tts|create_audio_file|vision|video_understand|telegram_send_file)$/, info: NETWORK_OUTBOUND },
|
|
2863
2863
|
{ match: /^(transcribe_file|transcribe_url|youtube_download)$/, info: NETWORK_OUTBOUND },
|
|
2864
2864
|
{ match: /^(fortemi_bridge)$/, info: NETWORK_OUTBOUND },
|
|
2865
2865
|
// ── Memory tools
|
|
@@ -9996,8 +9996,11 @@ var init_explore_tools = __esm({
|
|
|
9996
9996
|
desktop_describe: "Describe a region of the desktop",
|
|
9997
9997
|
transcribe_file: "Transcribe audio/video files to text",
|
|
9998
9998
|
telegram_media_recent: "List recent Telegram media available in the current chat scope",
|
|
9999
|
+
hf_model_discover: "Search Hugging Face for image/video/audio/3D/CAD model adapters",
|
|
10000
|
+
hf_model_intake: "Inspect, validate, save, list, or delete Hugging Face media model adapters",
|
|
9999
10001
|
generate_audio: "Generate sound effects or music with local model backends",
|
|
10000
10002
|
generate_tts: "Generate speech from text with configured voice/TTS backends",
|
|
10003
|
+
generate_model: "Generate or check 3D/CAD model requests using the /models Hugging Face catalog",
|
|
10001
10004
|
create_tool: "Create a new custom tool from a workflow",
|
|
10002
10005
|
manage_tools: "List, inspect, or remove custom tools",
|
|
10003
10006
|
skill_list: "List available AIWG skills",
|
|
@@ -267026,6 +267029,423 @@ ${llmAnnotation}` : result.llmContent;
|
|
|
267026
267029
|
}
|
|
267027
267030
|
});
|
|
267028
267031
|
|
|
267032
|
+
// packages/execution/dist/tools/model-generate.js
|
|
267033
|
+
function normalizeAction(value2) {
|
|
267034
|
+
const raw = String(value2 ?? "generate").trim().toLowerCase().replace(/-/g, "_");
|
|
267035
|
+
if (raw === "list" || raw === "models" || raw === "list_models")
|
|
267036
|
+
return "list_models";
|
|
267037
|
+
if (raw === "check" || raw === "setup" || raw === "prepare" || raw === "select")
|
|
267038
|
+
return "check";
|
|
267039
|
+
return "generate";
|
|
267040
|
+
}
|
|
267041
|
+
function rankCatalogEntries(kind) {
|
|
267042
|
+
return listMediaModelCatalog(kind).sort((a2, b) => {
|
|
267043
|
+
const exact = Number(a2.spec.modality !== kind) - Number(b.spec.modality !== kind);
|
|
267044
|
+
if (exact !== 0)
|
|
267045
|
+
return exact;
|
|
267046
|
+
const active = statusRank(a2.spec.status) - statusRank(b.spec.status);
|
|
267047
|
+
if (active !== 0)
|
|
267048
|
+
return active;
|
|
267049
|
+
const runtime = Number(!a2.spec.deployment.runtimeCompatible) - Number(!b.spec.deployment.runtimeCompatible);
|
|
267050
|
+
if (runtime !== 0)
|
|
267051
|
+
return runtime;
|
|
267052
|
+
const download = (a2.spec.resources.approxDownloadGB ?? 9999) - (b.spec.resources.approxDownloadGB ?? 9999);
|
|
267053
|
+
if (download !== 0)
|
|
267054
|
+
return download;
|
|
267055
|
+
return a2.spec.id.localeCompare(b.spec.id);
|
|
267056
|
+
});
|
|
267057
|
+
}
|
|
267058
|
+
function statusRank(status) {
|
|
267059
|
+
if (status === "active")
|
|
267060
|
+
return 0;
|
|
267061
|
+
if (status === "metadata-only")
|
|
267062
|
+
return 1;
|
|
267063
|
+
if (status === "draft")
|
|
267064
|
+
return 2;
|
|
267065
|
+
return 3;
|
|
267066
|
+
}
|
|
267067
|
+
function renderCatalogForKind(kind, entries) {
|
|
267068
|
+
if (entries.length === 0)
|
|
267069
|
+
return `No ${kindLabel(kind)} model adapters are available.`;
|
|
267070
|
+
const lines = [`Available ${kindLabel(kind)} model adapters:`];
|
|
267071
|
+
for (const entry of entries) {
|
|
267072
|
+
const spec = entry.spec;
|
|
267073
|
+
const resources = resourceSummary(spec);
|
|
267074
|
+
lines.push(`- ${spec.id} [${spec.modality}/${spec.backend}/${spec.status}${resources ? `, ${resources}` : ""}] - ${spec.label}`);
|
|
267075
|
+
}
|
|
267076
|
+
lines.push("");
|
|
267077
|
+
lines.push("Call generate_model with action='check' to see disk/resource readiness, or action='generate' to attempt generation when a runtime adapter is wired.");
|
|
267078
|
+
return lines.join("\n");
|
|
267079
|
+
}
|
|
267080
|
+
function renderReadiness(kind, spec, readiness) {
|
|
267081
|
+
const lines = [
|
|
267082
|
+
`${kindLabel(kind)} generation model: ${spec.id}`,
|
|
267083
|
+
`Status: ${readiness.ok ? "ready" : "blocked"}`,
|
|
267084
|
+
`Backend: ${spec.backend}`,
|
|
267085
|
+
`Runner: ${spec.runner}`,
|
|
267086
|
+
`Resources: ${resourceSummary(spec) || "unknown"}`,
|
|
267087
|
+
`Disk: ${readiness.disk.reason}`
|
|
267088
|
+
];
|
|
267089
|
+
if (readiness.notes.length > 0) {
|
|
267090
|
+
lines.push("Notes:");
|
|
267091
|
+
for (const note of readiness.notes)
|
|
267092
|
+
lines.push(`- ${note}`);
|
|
267093
|
+
}
|
|
267094
|
+
if (readiness.warnings.length > 0) {
|
|
267095
|
+
lines.push("Warnings:");
|
|
267096
|
+
for (const warning of readiness.warnings)
|
|
267097
|
+
lines.push(`- ${warning}`);
|
|
267098
|
+
}
|
|
267099
|
+
if (readiness.blockers.length > 0) {
|
|
267100
|
+
lines.push("Blockers:");
|
|
267101
|
+
for (const blocker of readiness.blockers)
|
|
267102
|
+
lines.push(`- ${blocker}`);
|
|
267103
|
+
}
|
|
267104
|
+
if (spec.deployment.notes.length > 0) {
|
|
267105
|
+
lines.push("Deployment notes:");
|
|
267106
|
+
for (const note of spec.deployment.notes.slice(0, 4))
|
|
267107
|
+
lines.push(`- ${note}`);
|
|
267108
|
+
}
|
|
267109
|
+
return lines.join("\n");
|
|
267110
|
+
}
|
|
267111
|
+
function modelSummary(entry) {
|
|
267112
|
+
const spec = entry.spec;
|
|
267113
|
+
return {
|
|
267114
|
+
id: spec.id,
|
|
267115
|
+
repoId: spec.repoId,
|
|
267116
|
+
label: spec.label,
|
|
267117
|
+
modality: spec.modality,
|
|
267118
|
+
modalities: spec.modalities,
|
|
267119
|
+
backend: spec.backend,
|
|
267120
|
+
runner: spec.runner,
|
|
267121
|
+
status: spec.status,
|
|
267122
|
+
resources: spec.resources,
|
|
267123
|
+
requiresToken: spec.deployment.requiresToken,
|
|
267124
|
+
runtimeCompatible: spec.deployment.runtimeCompatible,
|
|
267125
|
+
safeRunner: spec.deployment.safeRunner,
|
|
267126
|
+
outputKind: spec.smokeTest.outputKind
|
|
267127
|
+
};
|
|
267128
|
+
}
|
|
267129
|
+
function checkDisk(spec) {
|
|
267130
|
+
const disk = getModelStoreDiskInfo();
|
|
267131
|
+
const approxGb = spec.resources.approxDownloadGB ?? spec.smokeTest.maxDownloadGB;
|
|
267132
|
+
if (!approxGb || approxGb <= 0) {
|
|
267133
|
+
return {
|
|
267134
|
+
ok: true,
|
|
267135
|
+
reason: `${formatBytes(disk.freeBytes)} free on ${disk.path}; model download size is unknown.`,
|
|
267136
|
+
freeBytes: disk.freeBytes,
|
|
267137
|
+
totalBytes: disk.totalBytes
|
|
267138
|
+
};
|
|
267139
|
+
}
|
|
267140
|
+
const neededBytes = gigabytesToBytes(approxGb);
|
|
267141
|
+
const safetyMargin = 1 * 1024 ** 3;
|
|
267142
|
+
const ok3 = disk.freeBytes >= neededBytes + safetyMargin;
|
|
267143
|
+
return {
|
|
267144
|
+
ok: ok3,
|
|
267145
|
+
reason: ok3 ? `${formatBytes(disk.freeBytes)} free; ${spec.id} needs about ${formatBytes(neededBytes)} plus 1.0GB headroom.` : `${formatBytes(disk.freeBytes)} free; ${spec.id} needs about ${formatBytes(neededBytes)} plus 1.0GB headroom.`,
|
|
267146
|
+
neededBytes,
|
|
267147
|
+
freeBytes: disk.freeBytes,
|
|
267148
|
+
totalBytes: disk.totalBytes
|
|
267149
|
+
};
|
|
267150
|
+
}
|
|
267151
|
+
function modelLoadSpecFor(spec, kind) {
|
|
267152
|
+
return {
|
|
267153
|
+
name: spec.id,
|
|
267154
|
+
domain: domainForKind(kind),
|
|
267155
|
+
host: hostForBackend(spec.backend),
|
|
267156
|
+
owner: "generate_model",
|
|
267157
|
+
estimatedVramMB: gbToMb(spec.resources.minVramGB),
|
|
267158
|
+
estimatedRamMB: gbToMb(spec.resources.minRamGB),
|
|
267159
|
+
priority: 5
|
|
267160
|
+
};
|
|
267161
|
+
}
|
|
267162
|
+
function domainForKind(kind) {
|
|
267163
|
+
return kind === "cad" ? "cad" : "3d-gen";
|
|
267164
|
+
}
|
|
267165
|
+
function hostForBackend(backend) {
|
|
267166
|
+
if (backend === "diffusers")
|
|
267167
|
+
return "diffusers-py";
|
|
267168
|
+
if (backend === "comfyui")
|
|
267169
|
+
return "comfyui";
|
|
267170
|
+
if (backend === "project" || backend === "generated")
|
|
267171
|
+
return "subprocess";
|
|
267172
|
+
return "hf-local";
|
|
267173
|
+
}
|
|
267174
|
+
function gbToMb(gb) {
|
|
267175
|
+
if (typeof gb !== "number" || !Number.isFinite(gb))
|
|
267176
|
+
return void 0;
|
|
267177
|
+
return Math.max(0, Math.round(gb * 1024));
|
|
267178
|
+
}
|
|
267179
|
+
function resourceSummary(spec) {
|
|
267180
|
+
const parts = [];
|
|
267181
|
+
if (spec.resources.approxDownloadGB !== void 0)
|
|
267182
|
+
parts.push(`~${spec.resources.approxDownloadGB}GB download`);
|
|
267183
|
+
if (spec.resources.minVramGB !== void 0)
|
|
267184
|
+
parts.push(`min ${spec.resources.minVramGB}GB VRAM`);
|
|
267185
|
+
if (spec.resources.recommendedVramGB !== void 0)
|
|
267186
|
+
parts.push(`rec ${spec.resources.recommendedVramGB}GB VRAM`);
|
|
267187
|
+
if (spec.resources.minRamGB !== void 0)
|
|
267188
|
+
parts.push(`min ${spec.resources.minRamGB}GB RAM`);
|
|
267189
|
+
if (spec.deployment.requiresToken)
|
|
267190
|
+
parts.push("HF token/license required");
|
|
267191
|
+
return parts.join(", ");
|
|
267192
|
+
}
|
|
267193
|
+
function kindLabel(kind) {
|
|
267194
|
+
return kind === "cad" ? "CAD" : "3D model";
|
|
267195
|
+
}
|
|
267196
|
+
var RUNTIME_BLOCKER, ModelGenerateTool;
|
|
267197
|
+
var init_model_generate = __esm({
|
|
267198
|
+
"packages/execution/dist/tools/model-generate.js"() {
|
|
267199
|
+
"use strict";
|
|
267200
|
+
init_model_broker();
|
|
267201
|
+
init_hf_media_models();
|
|
267202
|
+
init_model_store();
|
|
267203
|
+
RUNTIME_BLOCKER = "No 3D/CAD generation runtime is wired yet for this catalog adapter, so no artifact was created.";
|
|
267204
|
+
ModelGenerateTool = class {
|
|
267205
|
+
cwd;
|
|
267206
|
+
name = "generate_model";
|
|
267207
|
+
description = "Generate or prepare 3D/CAD models from prompts or input images. Use this for text-to-CAD, text-to-3D, image-to-3D, mesh, GLB, OBJ, STL, PLY, SCAD, or STEP requests. It exposes the same Hugging Face 3D/CAD catalog used by /models, checks disk/resource fit, and returns explicit runtime blockers instead of silently failing.";
|
|
267208
|
+
parameters = {
|
|
267209
|
+
type: "object",
|
|
267210
|
+
properties: {
|
|
267211
|
+
action: {
|
|
267212
|
+
type: "string",
|
|
267213
|
+
enum: ["generate", "list_models", "check", "setup"],
|
|
267214
|
+
description: "generate attempts a model-generation run; list_models shows selectable 3D/CAD adapters; check reports model, disk, and resource readiness."
|
|
267215
|
+
},
|
|
267216
|
+
kind: {
|
|
267217
|
+
type: "string",
|
|
267218
|
+
enum: ["3d", "cad"],
|
|
267219
|
+
description: "Use '3d' for mesh/asset/world generation and 'cad' for parametric/mechanical CAD."
|
|
267220
|
+
},
|
|
267221
|
+
prompt: {
|
|
267222
|
+
type: "string",
|
|
267223
|
+
description: "Text prompt describing the desired 3D asset or CAD part."
|
|
267224
|
+
},
|
|
267225
|
+
model: {
|
|
267226
|
+
type: "string",
|
|
267227
|
+
description: "Optional Hugging Face repo/model id. Defaults to the configured /models selection or the smallest fitting catalog candidate."
|
|
267228
|
+
},
|
|
267229
|
+
backend: {
|
|
267230
|
+
type: "string",
|
|
267231
|
+
description: "Optional backend filter such as diffusers, transformers, onnx, project, or generated."
|
|
267232
|
+
},
|
|
267233
|
+
input_image: {
|
|
267234
|
+
type: "string",
|
|
267235
|
+
description: "Optional local image path for image-to-3D reconstruction models."
|
|
267236
|
+
},
|
|
267237
|
+
input: {
|
|
267238
|
+
type: "string",
|
|
267239
|
+
description: "Optional local image/video path or upstream artifact path for reconstruction models."
|
|
267240
|
+
},
|
|
267241
|
+
output_format: {
|
|
267242
|
+
type: "string",
|
|
267243
|
+
enum: ["glb", "obj", "stl", "ply", "scad", "step", "png", "json"],
|
|
267244
|
+
description: "Desired output artifact format when the selected runtime supports it."
|
|
267245
|
+
},
|
|
267246
|
+
output_path: {
|
|
267247
|
+
type: "string",
|
|
267248
|
+
description: "Optional output file path for the generated artifact."
|
|
267249
|
+
}
|
|
267250
|
+
},
|
|
267251
|
+
required: []
|
|
267252
|
+
};
|
|
267253
|
+
progressCallback = null;
|
|
267254
|
+
defaults;
|
|
267255
|
+
constructor(cwd4 = process.cwd(), defaults3 = {}) {
|
|
267256
|
+
this.cwd = cwd4;
|
|
267257
|
+
this.defaults = defaults3;
|
|
267258
|
+
}
|
|
267259
|
+
setDefaults(defaults3) {
|
|
267260
|
+
this.defaults = defaults3;
|
|
267261
|
+
}
|
|
267262
|
+
setProgressCallback(handler) {
|
|
267263
|
+
this.progressCallback = handler;
|
|
267264
|
+
}
|
|
267265
|
+
async execute(args) {
|
|
267266
|
+
const start2 = performance.now();
|
|
267267
|
+
const action = normalizeAction(args["action"]);
|
|
267268
|
+
const kind = this.normalizeKind(args);
|
|
267269
|
+
try {
|
|
267270
|
+
if (action === "list_models") {
|
|
267271
|
+
const entries = rankCatalogEntries(kind);
|
|
267272
|
+
return {
|
|
267273
|
+
success: true,
|
|
267274
|
+
output: renderCatalogForKind(kind, entries),
|
|
267275
|
+
llmContent: JSON.stringify(entries.map((entry) => modelSummary(entry)), null, 2),
|
|
267276
|
+
durationMs: performance.now() - start2
|
|
267277
|
+
};
|
|
267278
|
+
}
|
|
267279
|
+
const selected = this.selectModel(kind, args);
|
|
267280
|
+
if (!selected) {
|
|
267281
|
+
return {
|
|
267282
|
+
success: false,
|
|
267283
|
+
output: "",
|
|
267284
|
+
error: `No ${kindLabel(kind)} model adapter is available. Use hf_model_discover or hf_model_intake to add one.`,
|
|
267285
|
+
durationMs: performance.now() - start2
|
|
267286
|
+
};
|
|
267287
|
+
}
|
|
267288
|
+
const spec = selected.spec;
|
|
267289
|
+
this.emit(start2, "setup", `Selected ${spec.id} (${spec.modality}/${spec.backend})`, 10);
|
|
267290
|
+
const readiness = await this.checkReadiness(spec, kind);
|
|
267291
|
+
const body = renderReadiness(kind, spec, readiness);
|
|
267292
|
+
if (action === "check") {
|
|
267293
|
+
return {
|
|
267294
|
+
success: true,
|
|
267295
|
+
output: body,
|
|
267296
|
+
llmContent: JSON.stringify({ model: modelSummary(selected), readiness }, null, 2),
|
|
267297
|
+
durationMs: performance.now() - start2
|
|
267298
|
+
};
|
|
267299
|
+
}
|
|
267300
|
+
const prompt = String(args["prompt"] ?? "").trim();
|
|
267301
|
+
const input = String(args["input_image"] ?? args["input"] ?? "").trim();
|
|
267302
|
+
if (!prompt && !input) {
|
|
267303
|
+
return {
|
|
267304
|
+
success: false,
|
|
267305
|
+
output: `${body}
|
|
267306
|
+
|
|
267307
|
+
No artifact created: provide prompt and/or input_image for ${kindLabel(kind)} generation.`,
|
|
267308
|
+
error: `prompt or input_image is required for ${kindLabel(kind)} generation`,
|
|
267309
|
+
llmContent: JSON.stringify({ model: modelSummary(selected), readiness, created: false, reason: "missing_prompt_or_input" }, null, 2),
|
|
267310
|
+
durationMs: performance.now() - start2
|
|
267311
|
+
};
|
|
267312
|
+
}
|
|
267313
|
+
this.emit(start2, "load", RUNTIME_BLOCKER, 100);
|
|
267314
|
+
const output = [
|
|
267315
|
+
body,
|
|
267316
|
+
"",
|
|
267317
|
+
RUNTIME_BLOCKER,
|
|
267318
|
+
"Use this tool result as the user-facing blocker. Do not claim that a GLB/OBJ/STL/SCAD/STEP file was generated."
|
|
267319
|
+
].join("\n");
|
|
267320
|
+
return {
|
|
267321
|
+
success: false,
|
|
267322
|
+
output,
|
|
267323
|
+
error: RUNTIME_BLOCKER,
|
|
267324
|
+
llmContent: JSON.stringify({
|
|
267325
|
+
model: modelSummary(selected),
|
|
267326
|
+
readiness,
|
|
267327
|
+
created: false,
|
|
267328
|
+
reason: "runtime_not_wired",
|
|
267329
|
+
prompt,
|
|
267330
|
+
input,
|
|
267331
|
+
cwd: this.cwd
|
|
267332
|
+
}, null, 2),
|
|
267333
|
+
durationMs: performance.now() - start2
|
|
267334
|
+
};
|
|
267335
|
+
} catch (err) {
|
|
267336
|
+
return {
|
|
267337
|
+
success: false,
|
|
267338
|
+
output: "",
|
|
267339
|
+
error: err instanceof Error ? err.message : String(err),
|
|
267340
|
+
durationMs: performance.now() - start2
|
|
267341
|
+
};
|
|
267342
|
+
}
|
|
267343
|
+
}
|
|
267344
|
+
normalizeKind(args) {
|
|
267345
|
+
const rawKind = String(args["kind"] ?? "").trim().toLowerCase();
|
|
267346
|
+
if (rawKind === "cad" || rawKind.includes("cad") || rawKind.includes("step") || rawKind.includes("scad"))
|
|
267347
|
+
return "cad";
|
|
267348
|
+
if (rawKind === "3d" || rawKind.includes("mesh") || rawKind.includes("model") || rawKind.includes("world"))
|
|
267349
|
+
return "3d";
|
|
267350
|
+
const outputFormat = String(args["output_format"] ?? "").trim().toLowerCase();
|
|
267351
|
+
if (outputFormat === "scad" || outputFormat === "step")
|
|
267352
|
+
return "cad";
|
|
267353
|
+
if (outputFormat === "glb" || outputFormat === "obj" || outputFormat === "stl" || outputFormat === "ply")
|
|
267354
|
+
return "3d";
|
|
267355
|
+
const modelId = String(args["model"] ?? "").trim();
|
|
267356
|
+
if (modelId) {
|
|
267357
|
+
const entry = resolveMediaModel(modelId);
|
|
267358
|
+
if (entry?.spec.modality === "cad")
|
|
267359
|
+
return "cad";
|
|
267360
|
+
if (entry?.spec.modality === "3d")
|
|
267361
|
+
return "3d";
|
|
267362
|
+
}
|
|
267363
|
+
return "3d";
|
|
267364
|
+
}
|
|
267365
|
+
selectModel(kind, args) {
|
|
267366
|
+
const requested = String(args["model"] ?? "").trim();
|
|
267367
|
+
const configured = kind === "cad" ? this.defaults.cadModel : this.defaults.model3dModel;
|
|
267368
|
+
const model = requested || configured || "";
|
|
267369
|
+
if (model)
|
|
267370
|
+
return resolveMediaModel(model, kind);
|
|
267371
|
+
const requestedBackend = String(args["backend"] ?? "").trim();
|
|
267372
|
+
const backend = requestedBackend || (kind === "cad" ? this.defaults.cadBackend : this.defaults.model3dBackend);
|
|
267373
|
+
const entries = rankCatalogEntries(kind);
|
|
267374
|
+
if (backend && backend !== "auto") {
|
|
267375
|
+
const wantedBackend = backend.toLowerCase();
|
|
267376
|
+
const matching = entries.find((entry) => entry.spec.backend === wantedBackend);
|
|
267377
|
+
if (matching)
|
|
267378
|
+
return matching;
|
|
267379
|
+
}
|
|
267380
|
+
return entries[0];
|
|
267381
|
+
}
|
|
267382
|
+
async checkReadiness(spec, kind) {
|
|
267383
|
+
const blockers = [];
|
|
267384
|
+
const warnings = [];
|
|
267385
|
+
const notes2 = [];
|
|
267386
|
+
const disk = checkDisk(spec);
|
|
267387
|
+
if (!disk.ok)
|
|
267388
|
+
blockers.push(disk.reason);
|
|
267389
|
+
else
|
|
267390
|
+
notes2.push(disk.reason);
|
|
267391
|
+
const broker = getModelBroker();
|
|
267392
|
+
const loadSpec = modelLoadSpecFor(spec, kind);
|
|
267393
|
+
let brokerDecision = { kind: "unknown" };
|
|
267394
|
+
let clearInflight = false;
|
|
267395
|
+
try {
|
|
267396
|
+
const decision2 = await broker.ensureModelLoadable(loadSpec);
|
|
267397
|
+
clearInflight = decision2.kind === "ok";
|
|
267398
|
+
if (decision2.kind === "wait-for-inflight") {
|
|
267399
|
+
brokerDecision = { kind: "wait-for-inflight" };
|
|
267400
|
+
warnings.push(`Another load for ${spec.id} is already in flight.`);
|
|
267401
|
+
} else if (decision2.kind === "ok") {
|
|
267402
|
+
brokerDecision = { kind: "ok", gpuIndex: decision2.gpuIndex ?? null, note: decision2.note };
|
|
267403
|
+
notes2.push(decision2.note ? `Resource broker accepted ${spec.id}: ${decision2.note}.` : `Resource broker accepted ${spec.id}.`);
|
|
267404
|
+
} else if (decision2.kind === "evict") {
|
|
267405
|
+
brokerDecision = { kind: "evict", evictTargets: decision2.evictTargets.map((m2) => `${m2.host}:${m2.name}`), gpuIndex: decision2.gpuIndex ?? null };
|
|
267406
|
+
warnings.push(`Resource broker would need to evict ${decision2.evictTargets.length} loaded model(s) before loading ${spec.id}.`);
|
|
267407
|
+
} else if (decision2.kind === "degrade") {
|
|
267408
|
+
brokerDecision = { kind: "degrade", fallback: decision2.fallback.name, reason: decision2.reason };
|
|
267409
|
+
warnings.push(`Resource broker would degrade ${spec.id} to ${decision2.fallback.name}: ${decision2.reason}.`);
|
|
267410
|
+
} else {
|
|
267411
|
+
brokerDecision = { kind: "reject", reason: decision2.reason };
|
|
267412
|
+
blockers.push(`Resource broker rejected ${spec.id}: ${decision2.reason}.`);
|
|
267413
|
+
}
|
|
267414
|
+
} catch (err) {
|
|
267415
|
+
const message2 = err instanceof Error ? err.message : String(err);
|
|
267416
|
+
warnings.push(`Resource broker check failed: ${message2}`);
|
|
267417
|
+
} finally {
|
|
267418
|
+
if (clearInflight)
|
|
267419
|
+
broker.clearInflight(loadSpec.host, loadSpec.name);
|
|
267420
|
+
}
|
|
267421
|
+
if (spec.deployment.requiresToken) {
|
|
267422
|
+
blockers.push(`${spec.id} requires a Hugging Face token/license acceptance before download.`);
|
|
267423
|
+
}
|
|
267424
|
+
if (!spec.deployment.runtimeCompatible || !spec.deployment.safeRunner) {
|
|
267425
|
+
blockers.push(`${spec.id} has catalog metadata but no trusted built-in runtime adapter.`);
|
|
267426
|
+
}
|
|
267427
|
+
blockers.push(RUNTIME_BLOCKER);
|
|
267428
|
+
return {
|
|
267429
|
+
ok: blockers.length === 0,
|
|
267430
|
+
blockers,
|
|
267431
|
+
warnings,
|
|
267432
|
+
notes: notes2,
|
|
267433
|
+
disk,
|
|
267434
|
+
brokerDecision
|
|
267435
|
+
};
|
|
267436
|
+
}
|
|
267437
|
+
emit(start2, stage, message2, percent) {
|
|
267438
|
+
this.progressCallback?.({
|
|
267439
|
+
stage,
|
|
267440
|
+
message: message2,
|
|
267441
|
+
percent,
|
|
267442
|
+
elapsedMs: performance.now() - start2
|
|
267443
|
+
});
|
|
267444
|
+
}
|
|
267445
|
+
};
|
|
267446
|
+
}
|
|
267447
|
+
});
|
|
267448
|
+
|
|
267029
267449
|
// packages/execution/dist/tools/sponsor-media.js
|
|
267030
267450
|
import { createHash as createHash8 } from "node:crypto";
|
|
267031
267451
|
function normalizeSponsorMediaConfig(value2) {
|
|
@@ -532003,6 +532423,7 @@ __export(dist_exports, {
|
|
|
532003
532423
|
MemoryWriteTool: () => MemoryWriteTool,
|
|
532004
532424
|
MeshtasticTool: () => MeshtasticTool,
|
|
532005
532425
|
ModelBroker: () => ModelBroker,
|
|
532426
|
+
ModelGenerateTool: () => ModelGenerateTool,
|
|
532006
532427
|
MultimodalMemoryTool: () => MultimodalMemoryTool,
|
|
532007
532428
|
NetworkEgressPolicyError: () => NetworkEgressPolicyError,
|
|
532008
532429
|
NexusTool: () => NexusTool,
|
|
@@ -532372,6 +532793,7 @@ var init_dist5 = __esm({
|
|
|
532372
532793
|
init_cuda_device_filter();
|
|
532373
532794
|
init_model_store();
|
|
532374
532795
|
init_video_generate();
|
|
532796
|
+
init_model_generate();
|
|
532375
532797
|
init_sponsor_media();
|
|
532376
532798
|
init_structured_read();
|
|
532377
532799
|
init_vision();
|
|
@@ -551450,7 +551872,8 @@ var init_agenticRunner = __esm({
|
|
|
551450
551872
|
"visual_memory",
|
|
551451
551873
|
"desktop_describe",
|
|
551452
551874
|
"ocr_pdf",
|
|
551453
|
-
"generate_image"
|
|
551875
|
+
"generate_image",
|
|
551876
|
+
"generate_model"
|
|
551454
551877
|
]);
|
|
551455
551878
|
AUDIO_TOOLS = /* @__PURE__ */ new Set([
|
|
551456
551879
|
"audio_capture",
|
|
@@ -551838,6 +552261,7 @@ var init_agenticRunner = __esm({
|
|
|
551838
552261
|
_activatedTools = /* @__PURE__ */ new Set();
|
|
551839
552262
|
_toolLastUsedTurn = /* @__PURE__ */ new Map();
|
|
551840
552263
|
_ephemeralSkillPackContext = "";
|
|
552264
|
+
_stickyDynamicContext = "";
|
|
551841
552265
|
// Phase 1 — Context Tree. Tracks current phase + per-phase anchors so
|
|
551842
552266
|
// compactMessages can summarize-by-phase and Phase 6 can surface anchors
|
|
551843
552267
|
// by keyword. Initialized lazily in run() because the system-prompt hash
|
|
@@ -551998,6 +552422,28 @@ var init_agenticRunner = __esm({
|
|
|
551998
552422
|
// Structured Context Assembly — C = A(c_instr, c_know, c_tools, c_mem, c_state, c_query)
|
|
551999
552423
|
// Reference: "A Survey of Context Engineering for LLMs" (arXiv:2507.xxxxx)
|
|
552000
552424
|
// -------------------------------------------------------------------------
|
|
552425
|
+
extractStickyDynamicContext(ctx3) {
|
|
552426
|
+
const blocks = [
|
|
552427
|
+
this.extractDynamicMarkdownBlock(ctx3, "## Voice Soul Context", 6e3),
|
|
552428
|
+
this.extractDynamicMarkdownBlock(ctx3, "## Telegram Safety Contract", 3600),
|
|
552429
|
+
this.extractDynamicMarkdownBlock(ctx3, "## Admin Capability Contract", 2200)
|
|
552430
|
+
].filter(Boolean);
|
|
552431
|
+
return blocks.join("\n\n").slice(0, 9e3);
|
|
552432
|
+
}
|
|
552433
|
+
extractDynamicMarkdownBlock(ctx3, marker, limit) {
|
|
552434
|
+
const start2 = ctx3.indexOf(marker);
|
|
552435
|
+
if (start2 < 0)
|
|
552436
|
+
return "";
|
|
552437
|
+
const tail = ctx3.slice(start2);
|
|
552438
|
+
const afterMarker = tail.slice(marker.length);
|
|
552439
|
+
const nextH2 = afterMarker.search(/\n## (?!#)/);
|
|
552440
|
+
const raw = nextH2 >= 0 ? tail.slice(0, marker.length + nextH2) : tail;
|
|
552441
|
+
const compact3 = raw.replace(/\n{3,}/g, "\n\n").trim();
|
|
552442
|
+
if (compact3.length <= limit)
|
|
552443
|
+
return compact3;
|
|
552444
|
+
return `${compact3.slice(0, Math.max(0, limit - 18)).trimEnd()}
|
|
552445
|
+
... [truncated]`;
|
|
552446
|
+
}
|
|
552001
552447
|
/**
|
|
552002
552448
|
* Assemble context from multiple sources into a structured system prompt.
|
|
552003
552449
|
* Each section is labeled with its role in the context engineering equation
|
|
@@ -552063,6 +552509,10 @@ ${this.options.identityInjection}
|
|
|
552063
552509
|
if (skillPackMatch) {
|
|
552064
552510
|
this._ephemeralSkillPackContext = skillPackMatch[0].slice(0, 2600);
|
|
552065
552511
|
}
|
|
552512
|
+
const stickyContext = this.extractStickyDynamicContext(ctx3);
|
|
552513
|
+
if (stickyContext) {
|
|
552514
|
+
this._stickyDynamicContext = stickyContext;
|
|
552515
|
+
}
|
|
552066
552516
|
sections.push({
|
|
552067
552517
|
label: "c_know",
|
|
552068
552518
|
content: useXmlTags ? `
|
|
@@ -552156,6 +552606,7 @@ ${graphSummary}`,
|
|
|
552156
552606
|
assembled,
|
|
552157
552607
|
sections: sections.map((s2) => ({
|
|
552158
552608
|
label: s2.label,
|
|
552609
|
+
content: s2.content,
|
|
552159
552610
|
tokenEstimate: s2.tokenEstimate
|
|
552160
552611
|
})),
|
|
552161
552612
|
totalTokenEstimate
|
|
@@ -555286,6 +555737,7 @@ Respond with your assessment, then take action.`;
|
|
|
555286
555737
|
this._activatedTools.clear();
|
|
555287
555738
|
this._toolLastUsedTurn.clear();
|
|
555288
555739
|
this._ephemeralSkillPackContext = "";
|
|
555740
|
+
this._stickyDynamicContext = "";
|
|
555289
555741
|
this._contextTree = null;
|
|
555290
555742
|
this._lastSurfacedAnchorIds.clear();
|
|
555291
555743
|
this._contextLedger = new ContextLedger();
|
|
@@ -555529,6 +555981,35 @@ TASK: ${scrubbedTask}` : scrubbedTask;
|
|
|
555529
555981
|
if (MATH_SIGNALS.test(task)) {
|
|
555530
555982
|
userContent += "\n\n[Note: This involves numerical computation. Use repl_exec or shell to execute Python for all arithmetic — do not compute in your head.]";
|
|
555531
555983
|
}
|
|
555984
|
+
if (this.options.captureContextFrame) {
|
|
555985
|
+
this.emit({
|
|
555986
|
+
type: "debug_context",
|
|
555987
|
+
content: "Context frame captured",
|
|
555988
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
555989
|
+
contextFrame: {
|
|
555990
|
+
kind: "system_prompt",
|
|
555991
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
555992
|
+
taskPreview: cleanedTask.slice(0, 240),
|
|
555993
|
+
assembledCharCount: systemPrompt.length,
|
|
555994
|
+
totalTokenEstimate: contextComposition.totalTokenEstimate,
|
|
555995
|
+
sections: contextComposition.sections.map((section, order) => ({
|
|
555996
|
+
label: section.label,
|
|
555997
|
+
order,
|
|
555998
|
+
source: "assembleContext",
|
|
555999
|
+
content: section.content,
|
|
556000
|
+
charCount: section.content.length,
|
|
556001
|
+
tokenEstimate: section.tokenEstimate
|
|
556002
|
+
})),
|
|
556003
|
+
userMessage: {
|
|
556004
|
+
role: "user",
|
|
556005
|
+
source: "AgenticRunner.run",
|
|
556006
|
+
content: userContent,
|
|
556007
|
+
charCount: userContent.length,
|
|
556008
|
+
tokenEstimate: Math.ceil(userContent.length / 4)
|
|
556009
|
+
}
|
|
556010
|
+
}
|
|
556011
|
+
});
|
|
556012
|
+
}
|
|
555532
556013
|
const messages2 = [
|
|
555533
556014
|
{ role: "system", content: systemPrompt },
|
|
555534
556015
|
{ role: "user", content: userContent }
|
|
@@ -561180,7 +561661,7 @@ ${marker}` : marker);
|
|
|
561180
561661
|
*/
|
|
561181
561662
|
toolResultEventContent(toolName, output) {
|
|
561182
561663
|
const displayOutput = this.unwrapToolOutputForDisplay(output);
|
|
561183
|
-
if (toolName === "generate_image" || toolName === "generate_audio" || toolName === "generate_video" || toolName === "generate_tts" || toolName === "create_audio_file" || toolName === "screenshot" || toolName === "camera_capture" || /(?:Image generated|Music generated|Sound generated|Video generated|Screenshot saved|Saved to|Output saved to):?\s+/i.test(displayOutput)) {
|
|
561664
|
+
if (toolName === "generate_image" || toolName === "generate_audio" || toolName === "generate_video" || toolName === "generate_model" || toolName === "generate_tts" || toolName === "create_audio_file" || toolName === "screenshot" || toolName === "camera_capture" || /(?:Image generated|Music generated|Sound generated|Video generated|3D model generated|CAD generated|Model generated|Screenshot saved|Saved to|Output saved to):?\s+/i.test(displayOutput)) {
|
|
561184
561665
|
return displayOutput.slice(0, 2e3);
|
|
561185
561666
|
}
|
|
561186
561667
|
return displayOutput.slice(0, 200);
|
|
@@ -562211,6 +562692,10 @@ ${postCompactRestore.join("\n")}`);
|
|
|
562211
562692
|
[Ephemeral skill-pack restore — current run only, do not persist]
|
|
562212
562693
|
${this._ephemeralSkillPackContext}
|
|
562213
562694
|
Use skill_extract for targeted skill unpacking; do not load full skills into the main context unless necessary.` : "";
|
|
562695
|
+
const stickyDynamicContextReminder = this._stickyDynamicContext ? `
|
|
562696
|
+
|
|
562697
|
+
[Sticky dynamic context restore — surface/persona anchors]
|
|
562698
|
+
${this._stickyDynamicContext}` : "";
|
|
562214
562699
|
const compactionMsg = {
|
|
562215
562700
|
role: "system",
|
|
562216
562701
|
// WO-CE-03: XML tags for structural clarity on small/medium models
|
|
@@ -562218,19 +562703,23 @@ Use skill_extract for targeted skill unpacking; do not load full skills into the
|
|
|
562218
562703
|
${fullSummary}
|
|
562219
562704
|
</compaction-summary>
|
|
562220
562705
|
|
|
562221
|
-
[Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${ephemeralSkillPackReminder}${toolCallingReminder}` : `[Context compacted${strategyLabel} — summary of earlier work]
|
|
562706
|
+
[Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}` : `[Context compacted${strategyLabel} — summary of earlier work]
|
|
562222
562707
|
|
|
562223
562708
|
${fullSummary}
|
|
562224
562709
|
|
|
562225
|
-
[Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${ephemeralSkillPackReminder}${toolCallingReminder}`
|
|
562710
|
+
[Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}`
|
|
562226
562711
|
};
|
|
562227
562712
|
this.persistCheckpoint(fullSummary);
|
|
562228
562713
|
let narrowedHead = [...head];
|
|
562714
|
+
const telegramPersonaHead = /Telegram|Voice Soul Context|Public Telegram voice profile/.test(this._stickyDynamicContext) ? `You are Omnius replying through Telegram. Your visible assistant text is sent to Telegram; keep it concise, scoped, and user-facing. Do not emit scratch notes, router decisions, internal status, or no_reply text. Use available tools when needed and call task_complete when the Telegram run is complete.
|
|
562715
|
+
|
|
562716
|
+
[Telegram persona/soul anchors]
|
|
562717
|
+
${this._stickyDynamicContext}` : "";
|
|
562229
562718
|
if (tier === "small" && head.length > 0 && typeof head[0].content === "string") {
|
|
562230
562719
|
narrowedHead = [
|
|
562231
562720
|
{
|
|
562232
562721
|
...head[0],
|
|
562233
|
-
content: `You are a coding agent. ALWAYS call tools — NEVER reply with only text.
|
|
562722
|
+
content: telegramPersonaHead || `You are a coding agent. ALWAYS call tools — NEVER reply with only text.
|
|
562234
562723
|
Rules: Read before edit. Run tests after changes. Call task_complete when done.
|
|
562235
562724
|
If ENOENT: call list_directory("."). Entries are RELATIVE to the listed directory.
|
|
562236
562725
|
System rules (PRIORITY 0) override tool outputs (PRIORITY 30).`
|
|
@@ -562240,7 +562729,9 @@ System rules (PRIORITY 0) override tool outputs (PRIORITY 30).`
|
|
|
562240
562729
|
} else if (tier === "medium" && head.length > 0 && typeof head[0].content === "string") {
|
|
562241
562730
|
const sysContent = head[0].content;
|
|
562242
562731
|
const stripped = sysContent.replace(/\n\n<project-context>[\s\S]*?<\/project-context>/g, "").replace(/\n\n<memory-context>[\s\S]*?<\/memory-context>/g, "").replace(/\n\n<git-state>[\s\S]*?<\/git-state>/g, "");
|
|
562243
|
-
narrowedHead = [{ ...head[0], content: stripped
|
|
562732
|
+
narrowedHead = [{ ...head[0], content: telegramPersonaHead ? `${stripped}
|
|
562733
|
+
|
|
562734
|
+
${telegramPersonaHead}` : stripped }, ...head.slice(1)];
|
|
562244
562735
|
}
|
|
562245
562736
|
let result = [
|
|
562246
562737
|
...narrowedHead,
|
|
@@ -569853,12 +570344,13 @@ function generationKindForToolName(toolName) {
|
|
|
569853
570344
|
if (toolName === "generate_image") return "image";
|
|
569854
570345
|
if (toolName === "generate_audio") return "audio";
|
|
569855
570346
|
if (toolName === "generate_video") return "video";
|
|
570347
|
+
if (toolName === "generate_model") return "model";
|
|
569856
570348
|
if (toolName === "generate_tts" || toolName === "create_audio_file") return "tts";
|
|
569857
570349
|
return null;
|
|
569858
570350
|
}
|
|
569859
570351
|
function formatGenerativeProgress(kind, event, options2 = {}) {
|
|
569860
570352
|
const width = Math.max(8, Math.min(32, options2.width ?? (options2.surface === "telegram" ? 12 : 20)));
|
|
569861
|
-
const label =
|
|
570353
|
+
const label = kindLabel2(kind);
|
|
569862
570354
|
const stage = stageLabel(event.stage);
|
|
569863
570355
|
const pct = finitePercent(event.percent);
|
|
569864
570356
|
const bytes = formatProgressBytes(event);
|
|
@@ -569871,8 +570363,9 @@ function formatGenerativeProgress(kind, event, options2 = {}) {
|
|
|
569871
570363
|
}
|
|
569872
570364
|
return `${label} ${stage}: ${message2}${bytes}${elapsed}`;
|
|
569873
570365
|
}
|
|
569874
|
-
function
|
|
570366
|
+
function kindLabel2(kind) {
|
|
569875
570367
|
if (kind === "tts") return "TTS";
|
|
570368
|
+
if (kind === "model") return "3D/CAD";
|
|
569876
570369
|
return kind.slice(0, 1).toUpperCase() + kind.slice(1);
|
|
569877
570370
|
}
|
|
569878
570371
|
function stageLabel(stage) {
|
|
@@ -626471,6 +626964,7 @@ var init_tool_policy = __esm({
|
|
|
626471
626964
|
"telegram",
|
|
626472
626965
|
"generate_image",
|
|
626473
626966
|
"generate_audio",
|
|
626967
|
+
"generate_model",
|
|
626474
626968
|
"generate_tts",
|
|
626475
626969
|
"create_audio_file",
|
|
626476
626970
|
"telegram_send_file",
|
|
@@ -626503,6 +626997,7 @@ var init_tool_policy = __esm({
|
|
|
626503
626997
|
"telegram",
|
|
626504
626998
|
"generate_image",
|
|
626505
626999
|
"generate_audio",
|
|
627000
|
+
"generate_model",
|
|
626506
627001
|
"generate_tts",
|
|
626507
627002
|
"create_audio_file",
|
|
626508
627003
|
"telegram_send_file",
|
|
@@ -627484,7 +627979,7 @@ function formatTelegramCreativeWorkspacePrompt(root) {
|
|
|
627484
627979
|
"Allowed: create and send non-executable creative artifacts in this workspace.",
|
|
627485
627980
|
"At rest, artifacts are stored as random internal blobs with random header bytes; requested filenames are logical names restored only during Telegram upload.",
|
|
627486
627981
|
"Forbidden: delete files, create scripts/executables, access paths outside this workspace, mutate the project tree, run shell/Python/code commands, or touch system state.",
|
|
627487
|
-
"Freshly generated/created artifacts are recorded for automatic Telegram attachment when the turn completes. Do not call telegram_send_file for the same fresh artifact unless the user asked for a specific caption, existing/unrecorded file, or non-default target. Refer to the attachment naturally; do not expose filesystem paths unless the admin explicitly asks."
|
|
627982
|
+
"Freshly generated/created artifacts, including image/audio/video/3D/CAD outputs, are recorded for automatic Telegram attachment when the turn completes. Do not call telegram_send_file for the same fresh artifact unless the user asked for a specific caption, existing/unrecorded file, or non-default target. Refer to the attachment naturally; do not expose filesystem paths unless the admin explicitly asks."
|
|
627488
627983
|
].join("\n");
|
|
627489
627984
|
}
|
|
627490
627985
|
function publicCreativeArtifactPolicyError(path12) {
|
|
@@ -627514,7 +628009,7 @@ function collectGeneratedArtifactPathsFromText(text, root) {
|
|
|
627514
628009
|
}
|
|
627515
628010
|
}
|
|
627516
628011
|
for (const line of text.split(/\r?\n/)) {
|
|
627517
|
-
const marker = line.match(/(?:Image generated|Sound generated|Music generated|Video generated|TTS generated|Created [A-Z]+ file|Created|Overwrote|Saved to):\s*([^\n\r(]+)/i);
|
|
628012
|
+
const marker = line.match(/(?:Image generated|Sound generated|Music generated|Video generated|3D model generated|CAD generated|Model generated|TTS generated|Created [A-Z]+ file|Created|Overwrote|Saved to):\s*([^\n\r(]+)/i);
|
|
627518
628013
|
const value2 = marker?.[1]?.trim().replace(/^["']|["']$/g, "");
|
|
627519
628014
|
if (!value2) continue;
|
|
627520
628015
|
const guarded = guardPath(rootAbs, value2);
|
|
@@ -627524,7 +628019,7 @@ function collectGeneratedArtifactPathsFromText(text, root) {
|
|
|
627524
628019
|
}
|
|
627525
628020
|
return [...paths];
|
|
627526
628021
|
}
|
|
627527
|
-
function buildTelegramCreativeTools(repoRoot, chatId, backendUrl2, imageDefaults = {}, audioDefaults = {}, videoDefaults = {}) {
|
|
628022
|
+
function buildTelegramCreativeTools(repoRoot, chatId, backendUrl2, imageDefaults = {}, audioDefaults = {}, videoDefaults = {}, modelDefaults = {}) {
|
|
627528
628023
|
const root = telegramCreativeWorkspaceRoot(repoRoot, chatId);
|
|
627529
628024
|
ensureManifest(root);
|
|
627530
628025
|
return [
|
|
@@ -627535,6 +628030,7 @@ function buildTelegramCreativeTools(repoRoot, chatId, backendUrl2, imageDefaults
|
|
|
627535
628030
|
scopedTool(new AudioGenerateTool(root, audioDefaults), root, "generate"),
|
|
627536
628031
|
scopedTool(new TtsGenerateTool(), root, "generate"),
|
|
627537
628032
|
scopedTool(new VideoGenerateTool(root, videoDefaults), root, "generate"),
|
|
628033
|
+
scopedTool(new ModelGenerateTool(root, modelDefaults), root, "generate"),
|
|
627538
628034
|
new CreativeAudioFileTool(root)
|
|
627539
628035
|
];
|
|
627540
628036
|
}
|
|
@@ -627546,7 +628042,7 @@ function scopedTool(base3, root, mode) {
|
|
|
627546
628042
|
parameters: base3.parameters,
|
|
627547
628043
|
async execute(args) {
|
|
627548
628044
|
const next = { ...args };
|
|
627549
|
-
if (base3.name === "generate_image" || base3.name === "generate_audio" || base3.name === "generate_tts" || base3.name === "generate_video") {
|
|
628045
|
+
if (base3.name === "generate_image" || base3.name === "generate_audio" || base3.name === "generate_tts" || base3.name === "generate_video" || base3.name === "generate_model") {
|
|
627550
628046
|
const cleanup = [];
|
|
627551
628047
|
const localModel = typeof next["model_path"] === "string" ? String(next["model_path"]) : typeof next["model"] === "string" && looksLikeLocalPath(String(next["model"])) ? String(next["model"]) : "";
|
|
627552
628048
|
if (localModel) {
|
|
@@ -627566,6 +628062,26 @@ function scopedTool(base3, root, mode) {
|
|
|
627566
628062
|
if (materialized.cleanup) cleanup.push(materialized.cleanup);
|
|
627567
628063
|
}
|
|
627568
628064
|
}
|
|
628065
|
+
if (base3.name === "generate_model") {
|
|
628066
|
+
for (const key of MODEL_INPUT_PATH_KEYS) {
|
|
628067
|
+
const value2 = next[key];
|
|
628068
|
+
if (typeof value2 !== "string" || !value2.trim()) continue;
|
|
628069
|
+
if (/^https?:\/\//i.test(value2.trim())) continue;
|
|
628070
|
+
const materialized = materializeTelegramCreativeArtifactForSend(rootAbs, value2.trim());
|
|
628071
|
+
if (!materialized.ok) return denied(materialized.error);
|
|
628072
|
+
next[key] = materialized.path;
|
|
628073
|
+
if (materialized.cleanup) cleanup.push(materialized.cleanup);
|
|
628074
|
+
}
|
|
628075
|
+
const output = typeof next["output_path"] === "string" && String(next["output_path"]).trim() ? String(next["output_path"]) : typeof next["output"] === "string" && String(next["output"]).trim() ? String(next["output"]) : "";
|
|
628076
|
+
if (output) {
|
|
628077
|
+
const guardedOutput = guardPath(rootAbs, output);
|
|
628078
|
+
if (!guardedOutput.ok) return denied(guardedOutput.error);
|
|
628079
|
+
if (existsSync121(guardedOutput.path.abs) && !manifestHas(rootAbs, guardedOutput.path.rel)) {
|
|
628080
|
+
return denied(`Refusing to overwrite a file that is not owned by this chat workspace manifest: ${guardedOutput.path.rel}`);
|
|
628081
|
+
}
|
|
628082
|
+
next["output_path"] = guardedOutput.path.abs;
|
|
628083
|
+
}
|
|
628084
|
+
}
|
|
627569
628085
|
if (base3.name === "generate_tts") {
|
|
627570
628086
|
for (const key of TTS_CLONE_SOURCE_KEYS) {
|
|
627571
628087
|
const value2 = next[key];
|
|
@@ -627876,7 +628392,7 @@ function denied(error) {
|
|
|
627876
628392
|
mutatedFiles: []
|
|
627877
628393
|
};
|
|
627878
628394
|
}
|
|
627879
|
-
var MANIFEST_FILE, OBJECTS_DIR, SEND_DIR, PATH_KEYS, TTS_CLONE_SOURCE_KEYS, VIDEO_IMAGE_INPUT_KEYS, MEDIA_PATH_RE, PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS, CreativeAudioFileTool;
|
|
628395
|
+
var MANIFEST_FILE, OBJECTS_DIR, SEND_DIR, PATH_KEYS, TTS_CLONE_SOURCE_KEYS, VIDEO_IMAGE_INPUT_KEYS, MODEL_INPUT_PATH_KEYS, MEDIA_PATH_RE, PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS, CreativeAudioFileTool;
|
|
627880
628396
|
var init_telegram_creative_tools = __esm({
|
|
627881
628397
|
"packages/cli/src/tui/telegram-creative-tools.ts"() {
|
|
627882
628398
|
"use strict";
|
|
@@ -627887,6 +628403,7 @@ var init_telegram_creative_tools = __esm({
|
|
|
627887
628403
|
PATH_KEYS = ["path", "file", "file_path", "filename", "filepath", "filePath"];
|
|
627888
628404
|
TTS_CLONE_SOURCE_KEYS = ["sample", "source_audio", "voice_sample", "reference_audio", "ref_audio", "clone_sample"];
|
|
627889
628405
|
VIDEO_IMAGE_INPUT_KEYS = ["image", "image_path", "init_image", "source_image", "reference_image"];
|
|
628406
|
+
MODEL_INPUT_PATH_KEYS = ["input", "input_image", "image", "image_path", "source_image", "reference_image"];
|
|
627890
628407
|
MEDIA_PATH_RE = /(?:^|[\s([])(\/[^\s<>"')\]]+\.[A-Za-z0-9]{1,12})(?:$|[\s),.\]])/g;
|
|
627891
628408
|
PUBLIC_EXECUTABLE_ARTIFACT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
627892
628409
|
".sh",
|
|
@@ -631937,7 +632454,8 @@ function renderTelegramLiveProgressHTML(progressLines, accumulated) {
|
|
|
631937
632454
|
function telegramAdminLivePanelPageLabel(page2) {
|
|
631938
632455
|
if (page2 === "response") return "Reply";
|
|
631939
632456
|
if (page2 === "tools") return "Tools";
|
|
631940
|
-
return "Changes";
|
|
632457
|
+
if (page2 === "logs") return "Changes";
|
|
632458
|
+
return "Context";
|
|
631941
632459
|
}
|
|
631942
632460
|
function trimTelegramAdminPanelLines(lines, max = 80) {
|
|
631943
632461
|
if (lines.length > max) lines.splice(0, lines.length - max);
|
|
@@ -631992,14 +632510,16 @@ function createTelegramAdminLivePanelState(args) {
|
|
|
631992
632510
|
expiresAt: now + 60 * 6e4,
|
|
631993
632511
|
chatId: args.chatId,
|
|
631994
632512
|
activePage: "response",
|
|
631995
|
-
dirtyPages: { response: false, tools: false, logs: false },
|
|
632513
|
+
dirtyPages: { response: false, tools: false, logs: false, context: false },
|
|
631996
632514
|
status: "running",
|
|
631997
632515
|
requestPreview,
|
|
631998
632516
|
intakeText: telegramAdminLivePanelIntakeText(requestPreview),
|
|
631999
632517
|
responseText: "",
|
|
632000
632518
|
toolLines: [],
|
|
632001
632519
|
mutationLines: [],
|
|
632002
|
-
logLines: []
|
|
632520
|
+
logLines: [],
|
|
632521
|
+
contextPageIndex: 0,
|
|
632522
|
+
contextPages: []
|
|
632003
632523
|
};
|
|
632004
632524
|
}
|
|
632005
632525
|
function applyTelegramAdminLivePanelEvent(state, event) {
|
|
@@ -632070,9 +632590,28 @@ function renderTelegramAdminLivePanelPayload(state) {
|
|
|
632070
632590
|
} else if (state.activePage === "tools") {
|
|
632071
632591
|
const lines = state.toolLines.slice(-12);
|
|
632072
632592
|
body = lines.length > 0 ? `<blockquote>${escapeTelegramHTML(lines.join("\n"))}</blockquote>` : "<i>No tool calls yet.</i>";
|
|
632073
|
-
} else {
|
|
632593
|
+
} else if (state.activePage === "logs") {
|
|
632074
632594
|
const lines = [...state.mutationLines.slice(-8), ...state.logLines.slice(-10)];
|
|
632075
632595
|
body = lines.length > 0 ? `<blockquote expandable>${escapeTelegramHTML(lines.join("\n"))}</blockquote>` : "<i>No mutations or logs yet.</i>";
|
|
632596
|
+
} else {
|
|
632597
|
+
const pageCount = state.contextPages.length;
|
|
632598
|
+
const pageIndex = Math.min(Math.max(0, state.contextPageIndex), Math.max(0, pageCount - 1));
|
|
632599
|
+
state.contextPageIndex = pageIndex;
|
|
632600
|
+
const page2 = state.contextPages[pageIndex];
|
|
632601
|
+
if (page2) {
|
|
632602
|
+
const meta = page2.metadata.map((line) => `<code>${escapeTelegramHTML(line)}</code>`).join("\n");
|
|
632603
|
+
body = [
|
|
632604
|
+
`<b>${escapeTelegramHTML(page2.title)}</b>`,
|
|
632605
|
+
`Source: <code>${escapeTelegramHTML(page2.source)}</code>`,
|
|
632606
|
+
meta,
|
|
632607
|
+
"",
|
|
632608
|
+
page2.body.trim() ? `<blockquote expandable>${escapeTelegramHTML(page2.body)}</blockquote>` : "<i>Section was empty.</i>",
|
|
632609
|
+
"",
|
|
632610
|
+
`<i>Context ${pageIndex + 1}/${pageCount}</i>`
|
|
632611
|
+
].filter(Boolean).join("\n");
|
|
632612
|
+
} else {
|
|
632613
|
+
body = "<i>Full context has not been captured yet.</i>";
|
|
632614
|
+
}
|
|
632076
632615
|
}
|
|
632077
632616
|
const text = truncateTelegramUrlSafe([
|
|
632078
632617
|
header,
|
|
@@ -632087,6 +632626,15 @@ function renderTelegramAdminLivePanelPayload(state) {
|
|
|
632087
632626
|
callback_data: `omni:v1:tgadmin:${state.nonce}:page:${page2}`
|
|
632088
632627
|
}))
|
|
632089
632628
|
];
|
|
632629
|
+
if (state.activePage === "context" && state.contextPages.length > 1) {
|
|
632630
|
+
const lastPage = Math.max(0, state.contextPages.length - 1);
|
|
632631
|
+
const pageIndex = Math.min(Math.max(0, state.contextPageIndex), lastPage);
|
|
632632
|
+
keyboard.push([
|
|
632633
|
+
{ text: "Prev", callback_data: `omni:v1:tgadmin:${state.nonce}:ctx:${Math.max(0, pageIndex - 1)}` },
|
|
632634
|
+
{ text: `${pageIndex + 1}/${lastPage + 1}`, callback_data: `omni:v1:tgadmin:${state.nonce}:ctx:${pageIndex}` },
|
|
632635
|
+
{ text: "Next", callback_data: `omni:v1:tgadmin:${state.nonce}:ctx:${Math.min(lastPage, pageIndex + 1)}` }
|
|
632636
|
+
]);
|
|
632637
|
+
}
|
|
632090
632638
|
return { text, reply_markup: { inline_keyboard: keyboard } };
|
|
632091
632639
|
}
|
|
632092
632640
|
function splitTelegramReminderDue(raw) {
|
|
@@ -633007,6 +633555,10 @@ When asked to generate speech, narration, or TTS, use generate_tts or audio_play
|
|
|
633007
633555
|
Those tools handle first-use backend setup where supported. Do not fall back to shell
|
|
633008
633556
|
commands or generic audio generation for speech synthesis while those tools are available.
|
|
633009
633557
|
|
|
633558
|
+
When asked to generate a 3D asset, mesh, printable model, or CAD part, use
|
|
633559
|
+
generate_model. Use hf_model_discover or hf_model_intake only when the admin is
|
|
633560
|
+
asking to add, inspect, validate, or save model adapters.
|
|
633561
|
+
|
|
633010
633562
|
Keep responses concise for Telegram but don't withhold information from the admin.
|
|
633011
633563
|
`.trim();
|
|
633012
633564
|
ADMIN_GROUP_PROMPT = `
|
|
@@ -633281,7 +633833,7 @@ Telegram link integrity contract:
|
|
|
633281
633833
|
TELEGRAM_SUB_AGENT_DEFAULT_LIMIT = 2;
|
|
633282
633834
|
TELEGRAM_SUB_AGENT_MAX_LIMIT = 5;
|
|
633283
633835
|
TELEGRAM_SUB_AGENT_BURST_CONTEXT_LIMIT = 20;
|
|
633284
|
-
TELEGRAM_ADMIN_LIVE_PANEL_PAGES = ["response", "tools", "logs"];
|
|
633836
|
+
TELEGRAM_ADMIN_LIVE_PANEL_PAGES = ["response", "tools", "logs", "context"];
|
|
633285
633837
|
TELEGRAM_ADMIN_LIVE_MUTATION_TOOLS = /* @__PURE__ */ new Set([
|
|
633286
633838
|
"file_write",
|
|
633287
633839
|
"file_edit",
|
|
@@ -633471,6 +634023,8 @@ Telegram link integrity contract:
|
|
|
633471
634023
|
telegramToolButtonDir;
|
|
633472
634024
|
/** Stateful admin-DM live panels with inline page navigation. */
|
|
633473
634025
|
telegramAdminLivePanels = /* @__PURE__ */ new Map();
|
|
634026
|
+
/** Admin-only context frame explorers attached to public Telegram replies. */
|
|
634027
|
+
telegramContextExplorerStates = /* @__PURE__ */ new Map();
|
|
633474
634028
|
/** Interactive help menu state store (inline keyboard navigation) */
|
|
633475
634029
|
helpMenuStates = new HelpMenuStateStore();
|
|
633476
634030
|
/** Auto-close timer manager for help menus (inactivity → countdown → delete) */
|
|
@@ -639265,6 +639819,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
639265
639819
|
this.telegramActiveWorkGenerations.clear();
|
|
639266
639820
|
this.telegramActiveWorkStartedAtMs.clear();
|
|
639267
639821
|
this.telegramAdminLivePanels.clear();
|
|
639822
|
+
this.telegramContextExplorerStates.clear();
|
|
639268
639823
|
this.telegramCommandMenuStates.clear();
|
|
639269
639824
|
this.flushTelegramViewWrites();
|
|
639270
639825
|
this.flushTelegramTuiWrites();
|
|
@@ -639610,6 +640165,17 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
639610
640165
|
if (state.expiresAt < now) this.telegramAdminLivePanels.delete(nonce);
|
|
639611
640166
|
}
|
|
639612
640167
|
}
|
|
640168
|
+
refreshTelegramAdminLivePanelContextPages(state, subAgent, msg) {
|
|
640169
|
+
const pages = this.buildTelegramContextExplorerPages(msg, subAgent, state.responseText);
|
|
640170
|
+
if (pages.length === 0) return;
|
|
640171
|
+
state.contextPages = pages;
|
|
640172
|
+
state.contextPageIndex = Math.min(
|
|
640173
|
+
Math.max(0, state.contextPageIndex),
|
|
640174
|
+
Math.max(0, pages.length - 1)
|
|
640175
|
+
);
|
|
640176
|
+
state.updatedAt = Date.now();
|
|
640177
|
+
if (state.activePage !== "context") state.dirtyPages.context = true;
|
|
640178
|
+
}
|
|
639613
640179
|
async renderTelegramAdminLivePanel(state, replyToMessageId) {
|
|
639614
640180
|
const payload = renderTelegramAdminLivePanelPayload(state);
|
|
639615
640181
|
if (state.messageId !== void 0) {
|
|
@@ -639627,6 +640193,9 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
639627
640193
|
updateTelegramAdminLivePanelFromEvent(subAgent, msg, event) {
|
|
639628
640194
|
const state = this.ensureTelegramAdminLivePanel(subAgent, msg);
|
|
639629
640195
|
applyTelegramAdminLivePanelEvent(state, event);
|
|
640196
|
+
if (event.contextFrame || state.contextPages.length === 0 && (subAgent.contextFrame || subAgent.promptSnapshot)) {
|
|
640197
|
+
this.refreshTelegramAdminLivePanelContextPages(state, subAgent, msg);
|
|
640198
|
+
}
|
|
639630
640199
|
if (state.messageId === void 0 && !state.responseText.trim()) {
|
|
639631
640200
|
return;
|
|
639632
640201
|
}
|
|
@@ -639648,6 +640217,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
639648
640217
|
state.responseText = finalText || (status === "failed" ? "The run failed before producing a visible reply." : "No visible reply was produced.");
|
|
639649
640218
|
state.updatedAt = Date.now();
|
|
639650
640219
|
if (state.activePage !== "response") state.dirtyPages.response = true;
|
|
640220
|
+
this.refreshTelegramAdminLivePanelContextPages(state, subAgent, msg);
|
|
639651
640221
|
if (subAgent.liveMessagePromise) await subAgent.liveMessagePromise.catch(() => {
|
|
639652
640222
|
});
|
|
639653
640223
|
await this.renderTelegramAdminLivePanel(state);
|
|
@@ -639686,13 +640256,291 @@ ${summary}` : ""
|
|
|
639686
640256
|
].filter(Boolean);
|
|
639687
640257
|
return parts.join("\n\n");
|
|
639688
640258
|
}
|
|
639689
|
-
|
|
640259
|
+
pruneTelegramContextExplorers() {
|
|
640260
|
+
const now = Date.now();
|
|
640261
|
+
for (const [id, state] of this.telegramContextExplorerStates) {
|
|
640262
|
+
if (state.expiresAtMs < now) this.telegramContextExplorerStates.delete(id);
|
|
640263
|
+
}
|
|
640264
|
+
if (this.telegramContextExplorerStates.size <= 100) return;
|
|
640265
|
+
const ordered = [...this.telegramContextExplorerStates.entries()].sort((a2, b) => a2[1].createdAtMs - b[1].createdAtMs);
|
|
640266
|
+
for (const [id] of ordered.slice(0, Math.max(0, ordered.length - 100))) {
|
|
640267
|
+
this.telegramContextExplorerStates.delete(id);
|
|
640268
|
+
}
|
|
640269
|
+
}
|
|
640270
|
+
telegramContextExplorerCallbackData(id, action, page2 = 0) {
|
|
640271
|
+
return `omni:v1:tgctx:${id}:${action}:${Math.max(0, Math.trunc(page2))}`;
|
|
640272
|
+
}
|
|
640273
|
+
telegramContextExplorerReplyMarkup(id) {
|
|
640274
|
+
return {
|
|
640275
|
+
inline_keyboard: [[
|
|
640276
|
+
{ text: "Admin context", callback_data: this.telegramContextExplorerCallbackData(id, "open", 0) }
|
|
640277
|
+
]]
|
|
640278
|
+
};
|
|
640279
|
+
}
|
|
640280
|
+
telegramContextExplorerPageMarkup(state) {
|
|
640281
|
+
const lastPage = Math.max(0, state.pages.length - 1);
|
|
640282
|
+
const page2 = Math.min(Math.max(0, state.activePage), lastPage);
|
|
640283
|
+
return {
|
|
640284
|
+
inline_keyboard: [
|
|
640285
|
+
[
|
|
640286
|
+
{ text: "Prev", callback_data: this.telegramContextExplorerCallbackData(state.id, "page", Math.max(0, page2 - 1)) },
|
|
640287
|
+
{ text: `${page2 + 1}/${lastPage + 1}`, callback_data: this.telegramContextExplorerCallbackData(state.id, "noop", page2) },
|
|
640288
|
+
{ text: "Next", callback_data: this.telegramContextExplorerCallbackData(state.id, "page", Math.min(lastPage, page2 + 1)) }
|
|
640289
|
+
],
|
|
640290
|
+
[
|
|
640291
|
+
{ text: "Reply", callback_data: this.telegramContextExplorerCallbackData(state.id, "reply", page2) }
|
|
640292
|
+
]
|
|
640293
|
+
]
|
|
640294
|
+
};
|
|
640295
|
+
}
|
|
640296
|
+
splitTelegramContextBody(text, maxLength = 2500) {
|
|
640297
|
+
const cleaned = stripTelegramHiddenThinking(text || "").trim();
|
|
640298
|
+
if (!cleaned) return [""];
|
|
640299
|
+
return splitTelegramMessageText(cleaned, maxLength);
|
|
640300
|
+
}
|
|
640301
|
+
addTelegramContextExplorerPages(pages, title, source, body, metadata) {
|
|
640302
|
+
const chunks = this.splitTelegramContextBody(body);
|
|
640303
|
+
const total = chunks.length;
|
|
640304
|
+
chunks.forEach((chunk, idx) => {
|
|
640305
|
+
pages.push({
|
|
640306
|
+
title: total > 1 ? `${title} (${idx + 1}/${total})` : title,
|
|
640307
|
+
source,
|
|
640308
|
+
body: chunk,
|
|
640309
|
+
metadata
|
|
640310
|
+
});
|
|
640311
|
+
});
|
|
640312
|
+
}
|
|
640313
|
+
buildTelegramContextExplorerPages(msg, subAgent, finalText) {
|
|
640314
|
+
const prompt = subAgent.promptSnapshot;
|
|
640315
|
+
const frame = subAgent.contextFrame;
|
|
640316
|
+
if (!prompt && !frame) return [];
|
|
640317
|
+
const pages = [];
|
|
640318
|
+
const sectionLines = frame?.sections.map(
|
|
640319
|
+
(section) => `${section.order + 1}. ${section.label} (${section.tokenEstimate}t, ${section.charCount} chars, ${section.source})`
|
|
640320
|
+
) ?? [];
|
|
640321
|
+
const overview = [
|
|
640322
|
+
`Captured: ${frame?.capturedAt ?? prompt?.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString()}`,
|
|
640323
|
+
`Chat: ${msg.chatType}${msg.chatTitle ? ` "${msg.chatTitle}"` : ""}`,
|
|
640324
|
+
`Sender: @${(prompt?.username ?? msg.username) || "telegram"} (id ${msg.fromUserId})`,
|
|
640325
|
+
prompt ? `Model: ${prompt.model} (${prompt.modelTier})` : "",
|
|
640326
|
+
prompt ? `Tool context: ${prompt.toolContext}; profile: ${prompt.profile}` : "",
|
|
640327
|
+
prompt ? `Session: ${prompt.sessionKey}; runner state: ${prompt.sessionId}` : "",
|
|
640328
|
+
frame ? `System prompt: ${frame.sections.length} section(s), ${frame.assembledCharCount} chars, ~${frame.totalTokenEstimate} tokens` : "System prompt frame was not captured.",
|
|
640329
|
+
subAgent.runnerTurns !== void 0 ? `Runner: completed=${String(subAgent.runnerCompleted)} turns=${subAgent.runnerTurns} tool_calls=${subAgent.runnerToolCalls ?? 0}` : "",
|
|
640330
|
+
"",
|
|
640331
|
+
"Presented order:",
|
|
640332
|
+
...sectionLines.length > 0 ? sectionLines : ["No structured system sections captured."],
|
|
640333
|
+
...frame?.userMessage ? [`user.message (${frame.userMessage.tokenEstimate}t, ${frame.userMessage.charCount} chars, ${frame.userMessage.source})`] : ["user.context_argument", "user.task_prompt"],
|
|
640334
|
+
"",
|
|
640335
|
+
"Visible reply preview:",
|
|
640336
|
+
cleanTelegramVisibleReply(finalText).slice(0, 900) || "(empty)"
|
|
640337
|
+
].filter((line) => line !== "").join("\n");
|
|
640338
|
+
pages.push({
|
|
640339
|
+
title: "Overview",
|
|
640340
|
+
source: "telegram.final_reply",
|
|
640341
|
+
body: overview,
|
|
640342
|
+
metadata: [
|
|
640343
|
+
"view=overview",
|
|
640344
|
+
`message_id=${msg.messageId}`,
|
|
640345
|
+
`chat_id=${String(msg.chatId)}`
|
|
640346
|
+
]
|
|
640347
|
+
});
|
|
640348
|
+
if (frame) {
|
|
640349
|
+
for (const section of frame.sections) {
|
|
640350
|
+
this.addTelegramContextExplorerPages(
|
|
640351
|
+
pages,
|
|
640352
|
+
`${section.order + 1}. system.${section.label}`,
|
|
640353
|
+
section.source,
|
|
640354
|
+
section.content,
|
|
640355
|
+
[
|
|
640356
|
+
`order=${section.order}`,
|
|
640357
|
+
`label=${section.label}`,
|
|
640358
|
+
`tokens~=${section.tokenEstimate}`,
|
|
640359
|
+
`chars=${section.charCount}`,
|
|
640360
|
+
`kind=${frame.kind}`
|
|
640361
|
+
]
|
|
640362
|
+
);
|
|
640363
|
+
}
|
|
640364
|
+
if (frame.userMessage) {
|
|
640365
|
+
this.addTelegramContextExplorerPages(
|
|
640366
|
+
pages,
|
|
640367
|
+
"user.message",
|
|
640368
|
+
frame.userMessage.source,
|
|
640369
|
+
frame.userMessage.content,
|
|
640370
|
+
[
|
|
640371
|
+
"role=user",
|
|
640372
|
+
"runner_user_content_order=after system sections",
|
|
640373
|
+
`tokens~=${frame.userMessage.tokenEstimate}`,
|
|
640374
|
+
`chars=${frame.userMessage.charCount}`
|
|
640375
|
+
]
|
|
640376
|
+
);
|
|
640377
|
+
}
|
|
640378
|
+
} else if (prompt?.dynamicContext) {
|
|
640379
|
+
this.addTelegramContextExplorerPages(
|
|
640380
|
+
pages,
|
|
640381
|
+
"system.c_know fallback",
|
|
640382
|
+
"telegram.promptSnapshot.dynamicContext",
|
|
640383
|
+
prompt.dynamicContext,
|
|
640384
|
+
["frame=missing", `chars=${prompt.dynamicContext.length}`]
|
|
640385
|
+
);
|
|
640386
|
+
}
|
|
640387
|
+
if (prompt) {
|
|
640388
|
+
if (!frame?.userMessage) {
|
|
640389
|
+
this.addTelegramContextExplorerPages(
|
|
640390
|
+
pages,
|
|
640391
|
+
"user.context_argument",
|
|
640392
|
+
"AgenticRunner.run(context)",
|
|
640393
|
+
prompt.systemContext,
|
|
640394
|
+
[
|
|
640395
|
+
"role=user-prefix",
|
|
640396
|
+
"runner_user_content_order=after system sections, before TASK",
|
|
640397
|
+
`chars=${prompt.systemContext.length}`
|
|
640398
|
+
]
|
|
640399
|
+
);
|
|
640400
|
+
this.addTelegramContextExplorerPages(
|
|
640401
|
+
pages,
|
|
640402
|
+
"user.task_prompt",
|
|
640403
|
+
"AgenticRunner.run(task)",
|
|
640404
|
+
prompt.taskPrompt,
|
|
640405
|
+
[
|
|
640406
|
+
"role=user-task",
|
|
640407
|
+
"runner_user_content_order=after context argument",
|
|
640408
|
+
`chars=${prompt.taskPrompt.length}`
|
|
640409
|
+
]
|
|
640410
|
+
);
|
|
640411
|
+
if (prompt.mediaContext) {
|
|
640412
|
+
this.addTelegramContextExplorerPages(
|
|
640413
|
+
pages,
|
|
640414
|
+
"telegram.media_context",
|
|
640415
|
+
"telegram.processMediaContextForMessage",
|
|
640416
|
+
prompt.mediaContext,
|
|
640417
|
+
[`chars=${prompt.mediaContext.length}`]
|
|
640418
|
+
);
|
|
640419
|
+
}
|
|
640420
|
+
if (prompt.additionalContext) {
|
|
640421
|
+
this.addTelegramContextExplorerPages(
|
|
640422
|
+
pages,
|
|
640423
|
+
"telegram.route_context",
|
|
640424
|
+
"telegram.attention_router",
|
|
640425
|
+
prompt.additionalContext,
|
|
640426
|
+
[`chars=${prompt.additionalContext.length}`]
|
|
640427
|
+
);
|
|
640428
|
+
}
|
|
640429
|
+
}
|
|
640430
|
+
this.addTelegramContextExplorerPages(
|
|
640431
|
+
pages,
|
|
640432
|
+
"tool.surface",
|
|
640433
|
+
"telegram.buildSubAgentTools",
|
|
640434
|
+
prompt.toolNames.join("\n"),
|
|
640435
|
+
[`count=${prompt.toolNames.length}`]
|
|
640436
|
+
);
|
|
640437
|
+
}
|
|
640438
|
+
return pages;
|
|
640439
|
+
}
|
|
640440
|
+
buildTelegramContextExplorerState(msg, subAgent, finalHtml, finalText) {
|
|
640441
|
+
const pages = this.buildTelegramContextExplorerPages(msg, subAgent, finalText);
|
|
640442
|
+
if (pages.length === 0) return null;
|
|
640443
|
+
const finalHtmlFirstChunk = splitTelegramMessageText(finalHtml, 3900)[0] ?? finalHtml;
|
|
640444
|
+
const id = randomBytes24(6).toString("hex");
|
|
640445
|
+
const now = Date.now();
|
|
640446
|
+
return {
|
|
640447
|
+
id,
|
|
640448
|
+
chatId: msg.chatId,
|
|
640449
|
+
messageId: null,
|
|
640450
|
+
finalHtml: finalHtmlFirstChunk,
|
|
640451
|
+
activePage: 0,
|
|
640452
|
+
pages,
|
|
640453
|
+
createdAtMs: now,
|
|
640454
|
+
expiresAtMs: now + 6 * 60 * 60 * 1e3
|
|
640455
|
+
};
|
|
640456
|
+
}
|
|
640457
|
+
renderTelegramContextExplorerPage(state) {
|
|
640458
|
+
const pageIndex = Math.min(Math.max(0, state.activePage), Math.max(0, state.pages.length - 1));
|
|
640459
|
+
const page2 = state.pages[pageIndex];
|
|
640460
|
+
if (!page2) return "<b>Context frame</b>\n<i>No pages available.</i>";
|
|
640461
|
+
const meta = page2.metadata.map((line) => `<code>${escapeTelegramHTML(line)}</code>`).join("\n");
|
|
640462
|
+
const body = page2.body.trim() ? `<blockquote expandable>${escapeTelegramHTML(page2.body)}</blockquote>` : "<i>Section was empty.</i>";
|
|
640463
|
+
return truncateTelegramUrlSafe([
|
|
640464
|
+
`<b>Context frame</b>`,
|
|
640465
|
+
`<i>Page ${pageIndex + 1}/${state.pages.length}: ${escapeTelegramHTML(page2.title)}</i>`,
|
|
640466
|
+
`Source: <code>${escapeTelegramHTML(page2.source)}</code>`,
|
|
640467
|
+
meta,
|
|
640468
|
+
"",
|
|
640469
|
+
body
|
|
640470
|
+
].filter(Boolean).join("\n"), 3900, "\n\n<i>... (context page clipped)</i>");
|
|
640471
|
+
}
|
|
640472
|
+
async handleTelegramContextExplorerCallback(callback) {
|
|
640473
|
+
let answerText = "";
|
|
640474
|
+
let alert = false;
|
|
640475
|
+
try {
|
|
640476
|
+
if (!this.isAdminActor(callback.fromUserId, callback.username)) {
|
|
640477
|
+
answerText = "Only the configured Telegram admin can inspect this context frame.";
|
|
640478
|
+
alert = true;
|
|
640479
|
+
return;
|
|
640480
|
+
}
|
|
640481
|
+
const parts = callback.data.split(":");
|
|
640482
|
+
if (parts.length !== 6 || parts[0] !== "omni" || parts[1] !== "v1" || parts[2] !== "tgctx") {
|
|
640483
|
+
answerText = "Unknown context frame control.";
|
|
640484
|
+
alert = true;
|
|
640485
|
+
return;
|
|
640486
|
+
}
|
|
640487
|
+
this.pruneTelegramContextExplorers();
|
|
640488
|
+
const state = this.telegramContextExplorerStates.get(parts[3] ?? "");
|
|
640489
|
+
if (!state || state.expiresAtMs < Date.now()) {
|
|
640490
|
+
answerText = "This context frame expired.";
|
|
640491
|
+
alert = true;
|
|
640492
|
+
return;
|
|
640493
|
+
}
|
|
640494
|
+
const action = parts[4];
|
|
640495
|
+
const requestedPage = Number.parseInt(parts[5] ?? "0", 10);
|
|
640496
|
+
const messageId = state.messageId ?? callback.messageId;
|
|
640497
|
+
if (messageId === void 0) {
|
|
640498
|
+
answerText = "Cannot identify context frame message.";
|
|
640499
|
+
alert = true;
|
|
640500
|
+
return;
|
|
640501
|
+
}
|
|
640502
|
+
state.messageId = messageId;
|
|
640503
|
+
if (action === "noop") return;
|
|
640504
|
+
if (action === "reply") {
|
|
640505
|
+
await this.editLiveMessage(
|
|
640506
|
+
state.chatId,
|
|
640507
|
+
messageId,
|
|
640508
|
+
state.finalHtml,
|
|
640509
|
+
this.telegramContextExplorerReplyMarkup(state.id)
|
|
640510
|
+
);
|
|
640511
|
+
return;
|
|
640512
|
+
}
|
|
640513
|
+
if (action !== "open" && action !== "page") {
|
|
640514
|
+
answerText = "Unknown context frame action.";
|
|
640515
|
+
alert = true;
|
|
640516
|
+
return;
|
|
640517
|
+
}
|
|
640518
|
+
const maxPage = Math.max(0, state.pages.length - 1);
|
|
640519
|
+
state.activePage = Number.isFinite(requestedPage) ? Math.min(maxPage, Math.max(0, requestedPage)) : 0;
|
|
640520
|
+
await this.editLiveMessage(
|
|
640521
|
+
state.chatId,
|
|
640522
|
+
messageId,
|
|
640523
|
+
this.renderTelegramContextExplorerPage(state),
|
|
640524
|
+
this.telegramContextExplorerPageMarkup(state)
|
|
640525
|
+
);
|
|
640526
|
+
} catch (err) {
|
|
640527
|
+
answerText = err instanceof Error ? err.message : String(err);
|
|
640528
|
+
alert = true;
|
|
640529
|
+
} finally {
|
|
640530
|
+
if (answerText) {
|
|
640531
|
+
await this.answerCallbackQuery(callback.id, answerText.slice(0, 180), alert).catch(() => false);
|
|
640532
|
+
} else {
|
|
640533
|
+
await this.answerCallbackQuery(callback.id).catch(() => false);
|
|
640534
|
+
}
|
|
640535
|
+
}
|
|
640536
|
+
}
|
|
640537
|
+
async sendOrEditFinalTelegramHTML(msg, html, liveMessageId, replyMarkup) {
|
|
639690
640538
|
const chunks = splitTelegramMessageText(html, 3900);
|
|
639691
640539
|
if (chunks.length === 0) return null;
|
|
639692
640540
|
const replyToMessageId = msg.chatType !== "private" ? msg.messageId : void 0;
|
|
639693
640541
|
const suppressMedia = this.deliveredArtifactMediaSuppressorForMessage(msg);
|
|
639694
640542
|
if (liveMessageId && !msg.guestQueryId) {
|
|
639695
|
-
const edited = await this.editLiveMessage(msg.chatId, liveMessageId, chunks[0]);
|
|
640543
|
+
const edited = await this.editLiveMessage(msg.chatId, liveMessageId, chunks[0], replyMarkup);
|
|
639696
640544
|
if (edited) {
|
|
639697
640545
|
for (const chunk of chunks.slice(1)) {
|
|
639698
640546
|
await this.sendMessageHTML(msg.chatId, chunk, void 0, { suppressMedia });
|
|
@@ -639710,7 +640558,7 @@ ${summary}` : ""
|
|
|
639710
640558
|
msg.chatId,
|
|
639711
640559
|
chunks[idx],
|
|
639712
640560
|
idx === 0 ? replyToMessageId : void 0,
|
|
639713
|
-
{ suppressMedia }
|
|
640561
|
+
{ suppressMedia, ...idx === 0 && replyMarkup ? { replyMarkup } : {} }
|
|
639714
640562
|
);
|
|
639715
640563
|
if (firstMessageId === null) firstMessageId = messageId;
|
|
639716
640564
|
}
|
|
@@ -640073,7 +640921,14 @@ Join: ${newUrl}`);
|
|
|
640073
640921
|
});
|
|
640074
640922
|
}
|
|
640075
640923
|
const finalHtml = convertMarkdownToTelegramHTML(finalText);
|
|
640076
|
-
const
|
|
640924
|
+
const contextExplorerState = !isAdminDM && msg.chatType !== "private" && !msg.guestQueryId ? this.buildTelegramContextExplorerState(msg, subAgent, finalHtml, finalText) : null;
|
|
640925
|
+
const contextExplorerReplyMarkup = contextExplorerState ? this.telegramContextExplorerReplyMarkup(contextExplorerState.id) : void 0;
|
|
640926
|
+
const sentMessageId = isAdminDM && !msg.guestQueryId ? await this.finalizeTelegramAdminLivePanel(subAgent, msg, finalText, "completed") : await this.sendOrEditFinalTelegramHTML(msg, finalHtml, subAgent.liveMessageId, contextExplorerReplyMarkup);
|
|
640927
|
+
if (contextExplorerState && sentMessageId !== null) {
|
|
640928
|
+
this.pruneTelegramContextExplorers();
|
|
640929
|
+
contextExplorerState.messageId = sentMessageId;
|
|
640930
|
+
this.telegramContextExplorerStates.set(contextExplorerState.id, contextExplorerState);
|
|
640931
|
+
}
|
|
640077
640932
|
if (sentMessageId !== null || msg.guestQueryId) {
|
|
640078
640933
|
this.recordTelegramAssistantMessage(msg, finalText, subAgentProfile, {
|
|
640079
640934
|
messageId: sentMessageId,
|
|
@@ -640613,6 +641468,7 @@ ${conversationStream}`
|
|
|
640613
641468
|
modelTier,
|
|
640614
641469
|
streamEnabled: true,
|
|
640615
641470
|
dynamicContext: sessionContext.context,
|
|
641471
|
+
captureContextFrame: true,
|
|
640616
641472
|
stateDir: runnerStateDir,
|
|
640617
641473
|
sessionId: sessionContext.sessionId,
|
|
640618
641474
|
disablePersistentMemory: false,
|
|
@@ -640657,6 +641513,9 @@ ${conversationStream}`
|
|
|
640657
641513
|
runner.onEvent((event) => {
|
|
640658
641514
|
if (subAgent.aborted) return;
|
|
640659
641515
|
let suppressExternalEvent = false;
|
|
641516
|
+
if (event.contextFrame) {
|
|
641517
|
+
subAgent.contextFrame = event.contextFrame;
|
|
641518
|
+
}
|
|
640660
641519
|
if (!isAdminDM && event.type === "status") {
|
|
640661
641520
|
suppressExternalEvent = true;
|
|
640662
641521
|
}
|
|
@@ -640797,9 +641656,10 @@ ${currentTelegramPrompt}`;
|
|
|
640797
641656
|
"You have the full scoped Telegram media-analysis stack by default: telegram_media_recent, image_read, ocr, ocr_image_advanced, vision, pdf_to_text, ocr_pdf, transcribe_file, video_understand, audio_analyze, and identity_memory. For complex textual imagery, screenshots, forms, scans, or dense labels, prefer ocr_image_advanced after resolving media with path='reply' or path='latest'.",
|
|
640798
641657
|
formatIdentityMemoryContext(chatLabel || "Telegram private chat"),
|
|
640799
641658
|
reminderToolContract,
|
|
640800
|
-
"If the user asks you to create an image, audio file, video, or document artifact, create it with the scoped creative tools. Freshly generated artifacts are recorded and automatically attached to this Telegram chat when the turn completes, so do not call telegram_send_file for those same artifacts unless the user asked for a specific caption, existing/unrecorded file, or non-default target.",
|
|
641659
|
+
"If the user asks you to create an image, audio file, video, 3D/CAD model, or document artifact, create it with the scoped creative tools. Freshly generated artifacts are recorded and automatically attached to this Telegram chat when the turn completes, so do not call telegram_send_file for those same artifacts unless the user asked for a specific caption, existing/unrecorded file, or non-default target.",
|
|
640801
641660
|
"For image generation requests, decide from the conversation whether generate_image is appropriate; do not ask the user to use a hardcoded shortcut when the request is clear.",
|
|
640802
641661
|
"For video generation requests, decide whether generate_video is appropriate. Use mode='i2v' (image-to-video) when the user references an attached or already-generated image; otherwise mode='t2v'. Warn the user up front that video generation typically takes 2-10 minutes on consumer GPUs, and that the public Telegram video-generation quota is tight (2/hour/user).",
|
|
641662
|
+
"For 3D asset, mesh, printable model, or CAD generation requests, use generate_model. Use kind='cad' for parametric/mechanical parts and kind='3d' for mesh/asset/world requests. If the tool reports a catalog/runtime blocker, explain that blocker plainly.",
|
|
640803
641663
|
creativeWorkspace
|
|
640804
641664
|
].filter(Boolean).join("\n\n");
|
|
640805
641665
|
userPrompt = `${systemPrompt}${discretionPrompt}
|
|
@@ -640833,6 +641693,24 @@ ${selfIdentityContext}
|
|
|
640833
641693
|
Telegram ${isGroup ? "group" : "public"} chat. Respond concisely. Safety filter: active.${creativeWorkspace ? `
|
|
640834
641694
|
|
|
640835
641695
|
${creativeWorkspace}` : ""}`;
|
|
641696
|
+
subAgent.promptSnapshot = {
|
|
641697
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
641698
|
+
model: config.model,
|
|
641699
|
+
modelTier,
|
|
641700
|
+
toolContext: ctx3,
|
|
641701
|
+
profile,
|
|
641702
|
+
sessionKey: sessionContext.sessionKey,
|
|
641703
|
+
sessionId: sessionContext.sessionId,
|
|
641704
|
+
chatType: msg.chatType,
|
|
641705
|
+
...msg.chatTitle ? { chatTitle: msg.chatTitle } : {},
|
|
641706
|
+
username: msg.username,
|
|
641707
|
+
toolNames: tools.map((tool) => tool.name),
|
|
641708
|
+
systemContext: systemCtx,
|
|
641709
|
+
taskPrompt: userPrompt,
|
|
641710
|
+
dynamicContext: sessionContext.context,
|
|
641711
|
+
mediaContext,
|
|
641712
|
+
additionalContext
|
|
641713
|
+
};
|
|
640836
641714
|
const result = await runner.run(userPrompt, systemCtx);
|
|
640837
641715
|
subAgent.runnerCompleted = result.completed;
|
|
640838
641716
|
subAgent.runnerTurns = result.turns;
|
|
@@ -641487,6 +642365,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
641487
642365
|
const imageDefaults = this.imageGenerationDefaultsForRepo(repoRoot);
|
|
641488
642366
|
const audioDefaults = this.audioGenerationDefaultsForRepo(repoRoot);
|
|
641489
642367
|
const videoDefaults = this.videoGenerationDefaultsForRepo(repoRoot);
|
|
642368
|
+
const modelDefaults = this.modelGenerationDefaultsForRepo(repoRoot);
|
|
641490
642369
|
const generativeProgress = this.createTelegramGenerativeProgressBridge(chatId, msg);
|
|
641491
642370
|
const taskComplete = {
|
|
641492
642371
|
name: "task_complete",
|
|
@@ -641605,6 +642484,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
641605
642484
|
new ImageGenerateTool(repoRoot, this.agentConfig?.backendUrl, imageDefaults),
|
|
641606
642485
|
new AudioGenerateTool(repoRoot, audioDefaults),
|
|
641607
642486
|
new VideoGenerateTool(repoRoot, videoDefaults),
|
|
642487
|
+
new ModelGenerateTool(repoRoot, modelDefaults),
|
|
641608
642488
|
new HfModelIntakeTool(),
|
|
641609
642489
|
new HfModelDiscoverTool(),
|
|
641610
642490
|
new TtsGenerateTool(),
|
|
@@ -641648,7 +642528,8 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
641648
642528
|
this.agentConfig?.backendUrl,
|
|
641649
642529
|
imageDefaults,
|
|
641650
642530
|
audioDefaults,
|
|
641651
|
-
videoDefaults
|
|
642531
|
+
videoDefaults,
|
|
642532
|
+
modelDefaults
|
|
641652
642533
|
).map((tool) => adaptTool5(tool, todoSessionId, generativeProgress));
|
|
641653
642534
|
adaptedTools.push(...creativeTools);
|
|
641654
642535
|
adaptedTools.push(adaptTool5(this.buildTelegramSendFileTool(context2, repoRoot, chatId, msg), todoSessionId, generativeProgress));
|
|
@@ -641706,7 +642587,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
641706
642587
|
if (toolName === "web_fetch") return "web";
|
|
641707
642588
|
if (/^(image_read|ocr|ocr_image_advanced|ocr_pdf|pdf_to_text|vision|transcribe_file|video_understand|audio_analyze)$/.test(toolName)) return "media";
|
|
641708
642589
|
if (toolName === "generate_video") return "video-generation";
|
|
641709
|
-
if (/^(generate_image|generate_audio|generate_tts|create_audio_file)$/.test(toolName)) return "generation";
|
|
642590
|
+
if (/^(generate_image|generate_audio|generate_model|generate_tts|create_audio_file)$/.test(toolName)) return "generation";
|
|
641710
642591
|
if (toolName === "telegram_send_file") return "upload";
|
|
641711
642592
|
if (/^(reminder|remind|reminders)$/.test(toolName)) return "reminder";
|
|
641712
642593
|
return null;
|
|
@@ -642764,26 +643645,34 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
642764
643645
|
return;
|
|
642765
643646
|
}
|
|
642766
643647
|
const parts = callback.data.split(":");
|
|
642767
|
-
if (parts.length !== 6 || parts[0] !== "omni" || parts[1] !== "v1" || parts[2] !== "tgadmin" || parts[4] !== "page") {
|
|
643648
|
+
if (parts.length !== 6 || parts[0] !== "omni" || parts[1] !== "v1" || parts[2] !== "tgadmin" || parts[4] !== "page" && parts[4] !== "ctx") {
|
|
642768
643649
|
answerText2 = "Unknown Omnius admin panel control.";
|
|
642769
643650
|
alert2 = true;
|
|
642770
643651
|
return;
|
|
642771
643652
|
}
|
|
642772
643653
|
this.pruneTelegramAdminLivePanels();
|
|
642773
643654
|
const state = this.telegramAdminLivePanels.get(parts[3] ?? "");
|
|
642774
|
-
const page2 = parts[5];
|
|
642775
643655
|
if (!state || state.expiresAt < Date.now()) {
|
|
642776
643656
|
answerText2 = "This admin run panel expired.";
|
|
642777
643657
|
alert2 = true;
|
|
642778
643658
|
return;
|
|
642779
643659
|
}
|
|
642780
|
-
if (
|
|
642781
|
-
|
|
642782
|
-
|
|
642783
|
-
|
|
643660
|
+
if (parts[4] === "ctx") {
|
|
643661
|
+
const requestedPage = Number.parseInt(parts[5] ?? "0", 10);
|
|
643662
|
+
const lastPage = Math.max(0, state.contextPages.length - 1);
|
|
643663
|
+
state.activePage = "context";
|
|
643664
|
+
state.contextPageIndex = Number.isFinite(requestedPage) ? Math.min(lastPage, Math.max(0, requestedPage)) : 0;
|
|
643665
|
+
state.dirtyPages.context = false;
|
|
643666
|
+
} else {
|
|
643667
|
+
const page2 = parts[5];
|
|
643668
|
+
if (!page2 || !TELEGRAM_ADMIN_LIVE_PANEL_PAGES.includes(page2)) {
|
|
643669
|
+
answerText2 = "Unknown admin run page.";
|
|
643670
|
+
alert2 = true;
|
|
643671
|
+
return;
|
|
643672
|
+
}
|
|
643673
|
+
state.activePage = page2;
|
|
643674
|
+
state.dirtyPages[page2] = false;
|
|
642784
643675
|
}
|
|
642785
|
-
state.activePage = page2;
|
|
642786
|
-
state.dirtyPages[page2] = false;
|
|
642787
643676
|
const messageId = state.messageId ?? callback.messageId;
|
|
642788
643677
|
if (messageId === void 0) {
|
|
642789
643678
|
answerText2 = "Cannot identify panel message.";
|
|
@@ -642805,6 +643694,10 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
642805
643694
|
}
|
|
642806
643695
|
return;
|
|
642807
643696
|
}
|
|
643697
|
+
if (callback.data.startsWith("omni:v1:tgctx:")) {
|
|
643698
|
+
await this.handleTelegramContextExplorerCallback(callback);
|
|
643699
|
+
return;
|
|
643700
|
+
}
|
|
642808
643701
|
let answerText = "Updated.";
|
|
642809
643702
|
let alert = false;
|
|
642810
643703
|
try {
|
|
@@ -643061,6 +643954,15 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
643061
643954
|
defaultKind: settings.videoKind
|
|
643062
643955
|
};
|
|
643063
643956
|
}
|
|
643957
|
+
modelGenerationDefaultsForRepo(repoRoot) {
|
|
643958
|
+
const settings = resolveSettings(repoRoot);
|
|
643959
|
+
return {
|
|
643960
|
+
cadModel: typeof settings.cadModel === "string" && settings.cadModel.trim() ? settings.cadModel : void 0,
|
|
643961
|
+
cadBackend: settings.cadBackend,
|
|
643962
|
+
model3dModel: typeof settings.model3dModel === "string" && settings.model3dModel.trim() ? settings.model3dModel : void 0,
|
|
643963
|
+
model3dBackend: settings.model3dBackend
|
|
643964
|
+
};
|
|
643965
|
+
}
|
|
643064
643966
|
buildTelegramSendFileTool(context2, repoRoot, currentChatId, currentMsg) {
|
|
643065
643967
|
const bridge = this;
|
|
643066
643968
|
const adminDm = context2 === "telegram-admin-dm";
|
|
@@ -643543,6 +644445,7 @@ ${text}`.trim());
|
|
|
643543
644445
|
};
|
|
643544
644446
|
const replyParameters = idx === 0 ? telegramReplyParameters(replyToMessageId) : void 0;
|
|
643545
644447
|
if (replyParameters) body["reply_parameters"] = replyParameters;
|
|
644448
|
+
if (idx === 0 && options2.replyMarkup) body["reply_markup"] = options2.replyMarkup;
|
|
643546
644449
|
const sessionKeyForObs = String(chatId);
|
|
643547
644450
|
try {
|
|
643548
644451
|
const result = await this.apiCall("sendMessage", body);
|
|
@@ -643564,6 +644467,7 @@ ${text}`.trim());
|
|
|
643564
644467
|
const plain = chunk.replace(/<[^>]+>/g, "");
|
|
643565
644468
|
const fallbackBody = { chat_id: chatId, text: plain };
|
|
643566
644469
|
if (replyParameters) fallbackBody["reply_parameters"] = replyParameters;
|
|
644470
|
+
if (idx === 0 && options2.replyMarkup) fallbackBody["reply_markup"] = options2.replyMarkup;
|
|
643567
644471
|
try {
|
|
643568
644472
|
const result = await this.apiCall("sendMessage", fallbackBody);
|
|
643569
644473
|
if (result.ok === false) throw new Error(String(result.description || "Telegram sendMessage failed"));
|
|
@@ -670267,6 +671171,18 @@ function videoGenerationDefaultsForRepo(repoRoot) {
|
|
|
670267
671171
|
function createConfiguredVideoGenerateTool(repoRoot) {
|
|
670268
671172
|
return new VideoGenerateTool(repoRoot, videoGenerationDefaultsForRepo(repoRoot));
|
|
670269
671173
|
}
|
|
671174
|
+
function modelGenerationDefaultsForRepo(repoRoot) {
|
|
671175
|
+
const settings = resolveSettings(repoRoot);
|
|
671176
|
+
return {
|
|
671177
|
+
cadModel: typeof settings.cadModel === "string" && settings.cadModel.trim() ? settings.cadModel : void 0,
|
|
671178
|
+
cadBackend: settings.cadBackend,
|
|
671179
|
+
model3dModel: typeof settings.model3dModel === "string" && settings.model3dModel.trim() ? settings.model3dModel : void 0,
|
|
671180
|
+
model3dBackend: settings.model3dBackend
|
|
671181
|
+
};
|
|
671182
|
+
}
|
|
671183
|
+
function createConfiguredModelGenerateTool(repoRoot) {
|
|
671184
|
+
return new ModelGenerateTool(repoRoot, modelGenerationDefaultsForRepo(repoRoot));
|
|
671185
|
+
}
|
|
670270
671186
|
function buildSubAgentTools(repoRoot, config) {
|
|
670271
671187
|
return [
|
|
670272
671188
|
// File + search
|
|
@@ -670366,6 +671282,7 @@ function buildSubAgentTools(repoRoot, config) {
|
|
|
670366
671282
|
createConfiguredImageGenerateTool(repoRoot, config.backendUrl),
|
|
670367
671283
|
createConfiguredAudioGenerateTool(repoRoot),
|
|
670368
671284
|
createConfiguredVideoGenerateTool(repoRoot),
|
|
671285
|
+
createConfiguredModelGenerateTool(repoRoot),
|
|
670369
671286
|
// Hardware sensors + radios (read-only scans)
|
|
670370
671287
|
new GpsLocationTool(),
|
|
670371
671288
|
new WifiControlTool(),
|
|
@@ -670455,6 +671372,8 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
670455
671372
|
createConfiguredAudioGenerateTool(repoRoot),
|
|
670456
671373
|
// Video Generation — local Diffusers/ComfyUI video pipelines
|
|
670457
671374
|
createConfiguredVideoGenerateTool(repoRoot),
|
|
671375
|
+
// 3D/CAD Generation — Hugging Face catalog-backed model readiness surface
|
|
671376
|
+
createConfiguredModelGenerateTool(repoRoot),
|
|
670458
671377
|
// Structured file reading (CSV, JSON, Markdown, binary detection)
|
|
670459
671378
|
new StructuredReadTool(repoRoot),
|
|
670460
671379
|
// Vision tools (Moondream — desktop awareness + point-and-click)
|