@naparnik/mcp 0.10.22 → 0.10.38
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/CHANGELOG.md +113 -0
- package/dist/{chunk-KWTLR6D2.js → chunk-MCZJVJFA.js} +1498 -1009
- package/dist/cli.js +57 -63
- package/dist/index.d.ts +859 -634
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { createHash, randomBytes, randomUUID } from 'crypto';
|
|
2
1
|
import { execFile, spawn, execFileSync } from 'child_process';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { createHash, randomBytes, randomUUID } from 'crypto';
|
|
3
|
+
import { existsSync, readFileSync, closeSync, mkdirSync, openSync, readdirSync, statSync, rmSync, writeFileSync, renameSync, symlinkSync, chmodSync, lstatSync, realpathSync, mkdtempSync, linkSync, readlinkSync, appendFileSync, fstatSync, readSync, fsyncSync } from 'fs';
|
|
4
|
+
import { platform, homedir, arch, release, userInfo, tmpdir } from 'os';
|
|
5
|
+
import { win32, join, dirname, sep, resolve, relative, isAbsolute, basename, extname } from 'path';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { gunzipSync } from 'zlib';
|
|
8
|
-
import { pathToFileURL } from 'url';
|
|
8
|
+
import { pathToFileURL, fileURLToPath } from 'url';
|
|
9
9
|
import { readFile } from 'fs/promises';
|
|
10
10
|
|
|
11
11
|
var __defProp = Object.defineProperty;
|
|
@@ -176,12 +176,12 @@ var StdioServerTransport = class {
|
|
|
176
176
|
throw new McpError(McpErrorCode.InternalError, "Stdio-\u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043D\u0435 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0451\u043D");
|
|
177
177
|
}
|
|
178
178
|
const line = encodeNdjsonLine(message);
|
|
179
|
-
await new Promise((
|
|
179
|
+
await new Promise((resolve5, reject) => {
|
|
180
180
|
let settled = false;
|
|
181
181
|
const done = () => {
|
|
182
182
|
if (settled) return;
|
|
183
183
|
settled = true;
|
|
184
|
-
|
|
184
|
+
resolve5();
|
|
185
185
|
};
|
|
186
186
|
const flushed = process.stdout.write(line, "utf8", (err) => {
|
|
187
187
|
if (err !== null && err !== void 0) {
|
|
@@ -226,8 +226,8 @@ var StdioServerTransport = class {
|
|
|
226
226
|
function toolSuccess(content, structured) {
|
|
227
227
|
return { type: "success", content, ...structured !== void 0 ? { structured } : {} };
|
|
228
228
|
}
|
|
229
|
-
function toolMixed(blocks) {
|
|
230
|
-
return { type: "success", content: blocks };
|
|
229
|
+
function toolMixed(blocks, structured) {
|
|
230
|
+
return { type: "success", content: blocks, ...structured !== void 0 ? { structured } : {} };
|
|
231
231
|
}
|
|
232
232
|
function toolError(error40, code) {
|
|
233
233
|
return { type: "error", error: error40 };
|
|
@@ -412,6 +412,13 @@ var McpServer = class {
|
|
|
412
412
|
* Обрабатывает запрос инициализации.
|
|
413
413
|
*/
|
|
414
414
|
handleInitialize(params) {
|
|
415
|
+
const client = params?.["clientInfo"];
|
|
416
|
+
if (typeof client?.name === "string") {
|
|
417
|
+
this.toolContext = {
|
|
418
|
+
...this.toolContext,
|
|
419
|
+
host: { name: client.name, version: typeof client.version === "string" ? client.version : "" }
|
|
420
|
+
};
|
|
421
|
+
}
|
|
415
422
|
const clientVersion = params?.["protocolVersion"];
|
|
416
423
|
const negotiatedVersion = typeof clientVersion === "string" && clientVersion.length > 0 ? clientVersion : MCP_PROTOCOL_VERSION;
|
|
417
424
|
return {
|
|
@@ -658,8 +665,8 @@ function describeFailure(err) {
|
|
|
658
665
|
const bottom = err.cause;
|
|
659
666
|
if (bottom instanceof Error) {
|
|
660
667
|
const code = bottom.code;
|
|
661
|
-
const
|
|
662
|
-
return err.message ===
|
|
668
|
+
const tail2 = typeof code === "string" ? `${code}: ${bottom.message}` : bottom.message;
|
|
669
|
+
return err.message === tail2 || tail2 === "" ? err.message : `${err.message} (${tail2})`;
|
|
663
670
|
}
|
|
664
671
|
return err.message;
|
|
665
672
|
}
|
|
@@ -679,8 +686,8 @@ function loadConfig(env = process.env) {
|
|
|
679
686
|
throw new NaparnikConfigError(state.message);
|
|
680
687
|
}
|
|
681
688
|
function fromHost(value) {
|
|
682
|
-
const
|
|
683
|
-
return /^\$\{[^}]*\}$/.test(
|
|
689
|
+
const text2 = (value ?? "").trim();
|
|
690
|
+
return /^\$\{[^}]*\}$/.test(text2) ? "" : text2;
|
|
684
691
|
}
|
|
685
692
|
function readConfig(env = process.env) {
|
|
686
693
|
const apiKey = fromHost(env["NAPARNIK_API_KEY"]);
|
|
@@ -720,9 +727,9 @@ function parsePositiveInt(raw, fallback) {
|
|
|
720
727
|
}
|
|
721
728
|
|
|
722
729
|
// src/version.ts
|
|
723
|
-
var VERSION = "0.10.
|
|
730
|
+
var VERSION = "0.10.38";
|
|
724
731
|
var USER_AGENT = `naparnik-mcp/${VERSION}`;
|
|
725
|
-
var MIN_ENGINE = "2026.09.
|
|
732
|
+
var MIN_ENGINE = "2026.09.24-446";
|
|
726
733
|
var LAUNCHER_PROTOCOL = 1;
|
|
727
734
|
|
|
728
735
|
// src/contracts/sdk-headers.ts
|
|
@@ -890,9 +897,9 @@ var NaparnikApiClient = class {
|
|
|
890
897
|
return headers;
|
|
891
898
|
}
|
|
892
899
|
async parse(response, shape = {}) {
|
|
893
|
-
let
|
|
900
|
+
let text2;
|
|
894
901
|
try {
|
|
895
|
-
|
|
902
|
+
text2 = await response.text();
|
|
896
903
|
} catch (err) {
|
|
897
904
|
throw new NaparnikServerError(
|
|
898
905
|
`\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u043E\u0431\u043E\u0440\u0432\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u0438 \u0447\u0442\u0435\u043D\u0438\u0438 \u043E\u0442\u0432\u0435\u0442\u0430 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430: ${describe(err)}`,
|
|
@@ -900,15 +907,15 @@ var NaparnikApiClient = class {
|
|
|
900
907
|
);
|
|
901
908
|
}
|
|
902
909
|
if (response.ok) {
|
|
903
|
-
if (shape.wantText === true) return
|
|
904
|
-
if (
|
|
910
|
+
if (shape.wantText === true) return text2;
|
|
911
|
+
if (text2 === "") return {};
|
|
905
912
|
try {
|
|
906
|
-
return JSON.parse(
|
|
913
|
+
return JSON.parse(text2);
|
|
907
914
|
} catch {
|
|
908
|
-
throw new NaparnikServerError("\u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A \u0432\u0435\u0440\u043D\u0443\u043B \u043D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 JSON", response.status, truncate(
|
|
915
|
+
throw new NaparnikServerError("\u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A \u0432\u0435\u0440\u043D\u0443\u043B \u043D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u044B\u0439 JSON", response.status, truncate(text2));
|
|
909
916
|
}
|
|
910
917
|
}
|
|
911
|
-
const payload = safeJson(
|
|
918
|
+
const payload = safeJson(text2);
|
|
912
919
|
switch (response.status) {
|
|
913
920
|
// ⚠ ЗАПАСНЫЕ ТЕКСТЫ ЗДЕСЬ ВЕЛИ В ПАНЕЛЬ, КОТОРОЙ НЕТ, и молча: обычно
|
|
914
921
|
// сервер присылает свой текст, и эти строки видны только когда 401
|
|
@@ -940,20 +947,20 @@ var NaparnikApiClient = class {
|
|
|
940
947
|
throw new NaparnikServerError(
|
|
941
948
|
`\u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A \u043E\u0442\u0432\u0435\u0442\u0438\u043B \u043E\u0448\u0438\u0431\u043A\u043E\u0439 ${response.status}. \u042D\u0442\u043E \u0432\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0439 \u0441\u0431\u043E\u0439 \u043D\u0430 \u043D\u0430\u0448\u0435\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u0435.`,
|
|
942
949
|
response.status,
|
|
943
|
-
truncate(
|
|
950
|
+
truncate(text2)
|
|
944
951
|
);
|
|
945
952
|
}
|
|
946
953
|
throw new NaparnikClientError(
|
|
947
954
|
messageFrom(payload) ?? `\u0417\u0430\u043F\u0440\u043E\u0441 \u043E\u0442\u043A\u043B\u043E\u043D\u0451\u043D (${response.status}).`,
|
|
948
955
|
response.status,
|
|
949
|
-
truncate(
|
|
956
|
+
truncate(text2)
|
|
950
957
|
);
|
|
951
958
|
}
|
|
952
959
|
}
|
|
953
960
|
};
|
|
954
|
-
function safeJson(
|
|
961
|
+
function safeJson(text2) {
|
|
955
962
|
try {
|
|
956
|
-
return JSON.parse(
|
|
963
|
+
return JSON.parse(text2);
|
|
957
964
|
} catch {
|
|
958
965
|
return null;
|
|
959
966
|
}
|
|
@@ -970,17 +977,17 @@ function messageFrom(payload) {
|
|
|
970
977
|
function numberOr(value, fallback) {
|
|
971
978
|
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
972
979
|
}
|
|
973
|
-
function truncate(
|
|
974
|
-
return
|
|
980
|
+
function truncate(text2, limit = 500) {
|
|
981
|
+
return text2.length > limit ? `${text2.slice(0, limit)}\u2026` : text2;
|
|
975
982
|
}
|
|
976
983
|
function networkHint(err) {
|
|
977
|
-
const
|
|
984
|
+
const text2 = describeFailure(err);
|
|
978
985
|
const proxy = ["HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"].find((i) => (process.env[i] ?? "").trim() !== "");
|
|
979
986
|
if (proxy !== void 0) {
|
|
980
987
|
return `
|
|
981
988
|
\u041D\u0430 \u044D\u0442\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u0435 \u0437\u0430\u0434\u0430\u043D ${proxy}, \u043D\u043E Node \u043D\u0435 \u0445\u043E\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u043E\u043A\u0441\u0438 \u0441\u0430\u043C \u2014 \u0437\u0430\u043F\u0440\u043E\u0441 \u0443\u0448\u0451\u043B \u043D\u0430\u043F\u0440\u044F\u043C\u0443\u044E. \u0415\u0441\u043B\u0438 \u0432\u044B\u0445\u043E\u0434 \u0432 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u043E\u043A\u0441\u0438, \u043D\u0443\u0436\u0435\u043D Node 24 \u0438\u043B\u0438 \u043D\u043E\u0432\u0435\u0435 \u0441 NODE_USE_ENV_PROXY=1.`;
|
|
982
989
|
}
|
|
983
|
-
if (/CERT|SELF_SIGNED|UNABLE_TO_VERIFY/i.test(
|
|
990
|
+
if (/CERT|SELF_SIGNED|UNABLE_TO_VERIFY/i.test(text2)) {
|
|
984
991
|
return "\n\u041F\u043E\u0445\u043E\u0436\u0435 \u043D\u0430 \u043F\u0435\u0440\u0435\u0445\u0432\u0430\u0442 TLS (\u043A\u043E\u0440\u043F\u043E\u0440\u0430\u0442\u0438\u0432\u043D\u044B\u0439 \u0430\u043D\u0442\u0438\u0432\u0438\u0440\u0443\u0441 \u0438\u043B\u0438 \u043F\u0440\u043E\u043A\u0441\u0438). \u041F\u0443\u0442\u044C \u043A \u043A\u043E\u0440\u043D\u0435\u0432\u043E\u043C\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u0443 \u043E\u0440\u0433\u0430\u043D\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044F \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0439 NODE_EXTRA_CA_CERTS.";
|
|
985
992
|
}
|
|
986
993
|
return "";
|
|
@@ -989,7 +996,175 @@ function describe(err) {
|
|
|
989
996
|
return describeFailure(err);
|
|
990
997
|
}
|
|
991
998
|
function sleep(ms) {
|
|
992
|
-
return new Promise((
|
|
999
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
1000
|
+
}
|
|
1001
|
+
var TAIL_MS = 10 * 6e4;
|
|
1002
|
+
var AWAY_NOTE = "\u0421\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443: \u043C\u043E\u0436\u043D\u043E \u043E\u0442\u043E\u0439\u0442\u0438, \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440 \u043D\u0435 \u0443\u0441\u043D\u0451\u0442, \u043F\u043E\u043A\u0430 \u0438\u0434\u0451\u0442 \u0440\u0430\u0431\u043E\u0442\u0430. \u0422\u043E\u043B\u044C\u043A\u043E \u043A\u0440\u044B\u0448\u043A\u0443 \u043D\u043E\u0443\u0442\u0431\u0443\u043A\u0430 \u043D\u0435 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0442\u044C.";
|
|
1003
|
+
var realClock = {
|
|
1004
|
+
now: () => Date.now(),
|
|
1005
|
+
later(ms, fire) {
|
|
1006
|
+
const timer = setTimeout(fire, ms);
|
|
1007
|
+
timer.unref();
|
|
1008
|
+
return () => clearTimeout(timer);
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
var Wakefulness = class {
|
|
1012
|
+
constructor(blocker, opts = {}) {
|
|
1013
|
+
this.blocker = blocker;
|
|
1014
|
+
this.clock = opts.clock ?? realClock;
|
|
1015
|
+
this.pid = opts.pid ?? process.pid;
|
|
1016
|
+
this.tailMs = opts.tailMs ?? TAIL_MS;
|
|
1017
|
+
}
|
|
1018
|
+
blocker;
|
|
1019
|
+
holders = /* @__PURE__ */ new Set();
|
|
1020
|
+
until = 0;
|
|
1021
|
+
lamp = null;
|
|
1022
|
+
/**
|
|
1023
|
+
* Система однажды лампу не дала — больше не просим. Иначе каждый вызов
|
|
1024
|
+
* пытался бы заново запустить то, чего нет, а работа человека важнее.
|
|
1025
|
+
*/
|
|
1026
|
+
refused = false;
|
|
1027
|
+
cancelTail = null;
|
|
1028
|
+
clock;
|
|
1029
|
+
pid;
|
|
1030
|
+
tailMs;
|
|
1031
|
+
/** Держать компьютер бодрым; вернуть снятие. Снять второй раз — ничего не делает. */
|
|
1032
|
+
hold() {
|
|
1033
|
+
const token = /* @__PURE__ */ Symbol("hold");
|
|
1034
|
+
this.holders.add(token);
|
|
1035
|
+
this.sync();
|
|
1036
|
+
return () => {
|
|
1037
|
+
if (!this.holders.delete(token)) return;
|
|
1038
|
+
this.until = Math.max(this.until, this.clock.now() + this.tailMs);
|
|
1039
|
+
this.sync();
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Держать, пока идёт работа, — и когда она кончилась успехом, и когда упала.
|
|
1044
|
+
*
|
|
1045
|
+
* ⚠ Работа — функцией, а не готовым обещанием. Обещание уже запущено: тело
|
|
1046
|
+
* async-функции до первого await идёт при вычислении аргумента, и начало
|
|
1047
|
+
* работы оставалось без лампы (тест обёртки поймал ровно это).
|
|
1048
|
+
*/
|
|
1049
|
+
async during(work) {
|
|
1050
|
+
const release2 = this.hold();
|
|
1051
|
+
try {
|
|
1052
|
+
return await work();
|
|
1053
|
+
} finally {
|
|
1054
|
+
release2();
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
/**
|
|
1058
|
+
* Своя лампа для фоновой работы, привязанная к её процессу. Гаснет сама, когда
|
|
1059
|
+
* работа кончилась, — даже если нас к тому времени уже закрыли.
|
|
1060
|
+
*/
|
|
1061
|
+
follow(pid) {
|
|
1062
|
+
if (this.refused) return;
|
|
1063
|
+
try {
|
|
1064
|
+
if (this.blocker(pid) === null) this.refused = true;
|
|
1065
|
+
} catch {
|
|
1066
|
+
this.refused = true;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
sync() {
|
|
1070
|
+
const want = this.holders.size > 0 || this.clock.now() < this.until;
|
|
1071
|
+
if (want && this.lamp === null && !this.refused) this.light();
|
|
1072
|
+
if (!want && this.lamp !== null) {
|
|
1073
|
+
this.lamp.stop();
|
|
1074
|
+
this.lamp = null;
|
|
1075
|
+
}
|
|
1076
|
+
this.cancelTail?.();
|
|
1077
|
+
this.cancelTail = null;
|
|
1078
|
+
if (this.holders.size === 0 && want) {
|
|
1079
|
+
this.cancelTail = this.clock.later(this.until - this.clock.now(), () => this.sync());
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
light() {
|
|
1083
|
+
let lamp;
|
|
1084
|
+
try {
|
|
1085
|
+
lamp = this.blocker(this.pid);
|
|
1086
|
+
} catch {
|
|
1087
|
+
lamp = null;
|
|
1088
|
+
}
|
|
1089
|
+
if (lamp === null) {
|
|
1090
|
+
this.refused = true;
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
this.lamp = lamp;
|
|
1094
|
+
lamp.onExit(() => {
|
|
1095
|
+
if (this.lamp === lamp) this.lamp = null;
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
var ASLEEP = new Wakefulness(() => null);
|
|
1100
|
+
function systemBlocker(platform4 = process.platform, run = spawn, env = process.env) {
|
|
1101
|
+
return (pid) => {
|
|
1102
|
+
let command;
|
|
1103
|
+
let args;
|
|
1104
|
+
if (platform4 === "darwin") {
|
|
1105
|
+
command = "/usr/bin/caffeinate";
|
|
1106
|
+
args = ["-i", "-w", String(pid)];
|
|
1107
|
+
} else if (platform4 === "win32") {
|
|
1108
|
+
command = `${env["SystemRoot"] ?? "C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
1109
|
+
args = [
|
|
1110
|
+
"-NoProfile",
|
|
1111
|
+
"-NonInteractive",
|
|
1112
|
+
"-WindowStyle",
|
|
1113
|
+
"Hidden",
|
|
1114
|
+
// Закодированным, а не строкой: в тексте кавычки из C#, и Windows
|
|
1115
|
+
// склеивает их с кавычками командной строки непредсказуемо.
|
|
1116
|
+
"-EncodedCommand",
|
|
1117
|
+
Buffer.from(windowsScript(pid), "utf16le").toString("base64")
|
|
1118
|
+
];
|
|
1119
|
+
} else {
|
|
1120
|
+
return null;
|
|
1121
|
+
}
|
|
1122
|
+
const child = run(command, args, {
|
|
1123
|
+
stdio: "ignore",
|
|
1124
|
+
windowsHide: true,
|
|
1125
|
+
detached: false
|
|
1126
|
+
});
|
|
1127
|
+
child.unref();
|
|
1128
|
+
let exited = false;
|
|
1129
|
+
const listeners = [];
|
|
1130
|
+
const gone = () => {
|
|
1131
|
+
if (exited) return;
|
|
1132
|
+
exited = true;
|
|
1133
|
+
for (const cb of listeners) cb();
|
|
1134
|
+
};
|
|
1135
|
+
child.on("error", gone);
|
|
1136
|
+
child.on("exit", gone);
|
|
1137
|
+
return {
|
|
1138
|
+
stop() {
|
|
1139
|
+
try {
|
|
1140
|
+
child.kill();
|
|
1141
|
+
} catch {
|
|
1142
|
+
}
|
|
1143
|
+
},
|
|
1144
|
+
onExit(cb) {
|
|
1145
|
+
if (exited) cb();
|
|
1146
|
+
else listeners.push(cb);
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
function windowsScript(pid) {
|
|
1152
|
+
return [
|
|
1153
|
+
`$t = Add-Type -Name Power -Namespace Naparnik -PassThru -MemberDefinition '[DllImport("kernel32.dll")] public static extern uint SetThreadExecutionState(uint f);'`,
|
|
1154
|
+
"[void]$t::SetThreadExecutionState([uint32]2147483649)",
|
|
1155
|
+
`Wait-Process -Id ${pid} -ErrorAction SilentlyContinue`
|
|
1156
|
+
].join("\n");
|
|
1157
|
+
}
|
|
1158
|
+
function withWakefulness(awake) {
|
|
1159
|
+
return (tool) => {
|
|
1160
|
+
const original = tool.execute.bind(tool);
|
|
1161
|
+
return {
|
|
1162
|
+
...tool,
|
|
1163
|
+
async execute(input, ...rest) {
|
|
1164
|
+
return awake.during(() => original(input, ...rest));
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
};
|
|
993
1168
|
}
|
|
994
1169
|
var FINGERPRINT_VERSION = "mid1";
|
|
995
1170
|
var MIN_ID_LENGTH = 8;
|
|
@@ -1185,10 +1360,12 @@ function montageEnv(base, key) {
|
|
|
1185
1360
|
};
|
|
1186
1361
|
}
|
|
1187
1362
|
var Engine = class {
|
|
1188
|
-
constructor(env = process.env) {
|
|
1363
|
+
constructor(env = process.env, awake = ASLEEP) {
|
|
1189
1364
|
this.env = env;
|
|
1365
|
+
this.awake = awake;
|
|
1190
1366
|
}
|
|
1191
1367
|
env;
|
|
1368
|
+
awake;
|
|
1192
1369
|
passportCache;
|
|
1193
1370
|
versionAtStart;
|
|
1194
1371
|
pythonChecked;
|
|
@@ -1576,6 +1753,7 @@ var Engine = class {
|
|
|
1576
1753
|
} catch {
|
|
1577
1754
|
}
|
|
1578
1755
|
}
|
|
1756
|
+
if (child.pid !== void 0) this.awake.follow(child.pid);
|
|
1579
1757
|
this.watch(child, opts.place, id, opts.advice, log.file);
|
|
1580
1758
|
return { id };
|
|
1581
1759
|
}
|
|
@@ -1627,7 +1805,7 @@ var Engine = class {
|
|
|
1627
1805
|
});
|
|
1628
1806
|
});
|
|
1629
1807
|
child.on("close", (code, signal) => {
|
|
1630
|
-
const
|
|
1808
|
+
const tail2 = logTail();
|
|
1631
1809
|
if (signal) {
|
|
1632
1810
|
void this.run(place, [
|
|
1633
1811
|
"job-abort",
|
|
@@ -1635,17 +1813,17 @@ var Engine = class {
|
|
|
1635
1813
|
"--signal",
|
|
1636
1814
|
String(signal),
|
|
1637
1815
|
"--tail",
|
|
1638
|
-
lastLines(
|
|
1816
|
+
lastLines(tail2)
|
|
1639
1817
|
]).catch(() => {
|
|
1640
1818
|
});
|
|
1641
1819
|
return;
|
|
1642
1820
|
}
|
|
1643
|
-
if (code === 0 || code === 2 || code === 3 ||
|
|
1821
|
+
if (code === 0 || code === 2 || code === 3 || tail2.trim() === "") return;
|
|
1644
1822
|
void this.run(place, [
|
|
1645
1823
|
"job-fail",
|
|
1646
1824
|
id,
|
|
1647
1825
|
"--what",
|
|
1648
|
-
lastLines(
|
|
1826
|
+
lastLines(tail2),
|
|
1649
1827
|
"--what-to-do",
|
|
1650
1828
|
"\u043F\u043E\u043A\u0430\u0436\u0438 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0446\u0435\u043B\u0438\u043A\u043E\u043C"
|
|
1651
1829
|
]).catch(() => {
|
|
@@ -1689,15 +1867,14 @@ function parseFailure(err, fallback) {
|
|
|
1689
1867
|
return { ok: false, text: mine !== "" ? mine : e?.message ?? fallback };
|
|
1690
1868
|
}
|
|
1691
1869
|
function details(err) {
|
|
1692
|
-
|
|
1693
|
-
return [e?.stdout, e?.stderr, e?.message].filter(Boolean).join("\n").trim();
|
|
1870
|
+
return parseFailure(err, "").text.trim();
|
|
1694
1871
|
}
|
|
1695
1872
|
function lastLine(output) {
|
|
1696
1873
|
const lines = output.trim().split("\n");
|
|
1697
1874
|
return (lines[lines.length - 1] ?? "").trim();
|
|
1698
1875
|
}
|
|
1699
|
-
function lastLines(
|
|
1700
|
-
return
|
|
1876
|
+
function lastLines(text2, howMany) {
|
|
1877
|
+
return text2.trim().split("\n").slice(-8).join("\n");
|
|
1701
1878
|
}
|
|
1702
1879
|
var NOT_JSON = "\u0414\u0432\u0438\u0436\u043E\u043A \u043E\u0442\u0432\u0435\u0442\u0438\u043B \u043D\u0435 \u0442\u0435\u043C, \u0447\u0435\u0433\u043E \u0436\u0434\u0430\u043B\u0438. \u041E\u0431\u043D\u043E\u0432\u0438 \u0434\u0432\u0438\u0436\u043E\u043A \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u043C setup \u0441 what=engine \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438.";
|
|
1703
1880
|
|
|
@@ -13301,19 +13478,19 @@ function acquireVersionLock(dir, hooks = {}) {
|
|
|
13301
13478
|
};
|
|
13302
13479
|
}
|
|
13303
13480
|
async function withVersionLock(dir, work, hooks = {}) {
|
|
13304
|
-
const
|
|
13481
|
+
const release2 = acquireVersionLock(dir, hooks);
|
|
13305
13482
|
try {
|
|
13306
13483
|
return await work();
|
|
13307
13484
|
} finally {
|
|
13308
|
-
|
|
13485
|
+
release2();
|
|
13309
13486
|
}
|
|
13310
13487
|
}
|
|
13311
13488
|
function withVersionLockSync(dir, work) {
|
|
13312
|
-
const
|
|
13489
|
+
const release2 = acquireVersionLock(dir);
|
|
13313
13490
|
try {
|
|
13314
13491
|
return work();
|
|
13315
13492
|
} finally {
|
|
13316
|
-
|
|
13493
|
+
release2();
|
|
13317
13494
|
}
|
|
13318
13495
|
}
|
|
13319
13496
|
var PUBLICATION_FILE = ".publication.json";
|
|
@@ -13922,7 +14099,7 @@ function preparedCandidateAfterBootstrap(engine, before) {
|
|
|
13922
14099
|
}
|
|
13923
14100
|
return { ok: true, candidate, place };
|
|
13924
14101
|
}
|
|
13925
|
-
function blockCandidate(dir, candidate,
|
|
14102
|
+
function blockCandidate(dir, candidate, text2) {
|
|
13926
14103
|
if (!sameCandidateState(readCandidate(dir), candidate)) {
|
|
13927
14104
|
return {
|
|
13928
14105
|
ok: false,
|
|
@@ -13930,12 +14107,20 @@ function blockCandidate(dir, candidate, text) {
|
|
|
13930
14107
|
};
|
|
13931
14108
|
}
|
|
13932
14109
|
writeCandidate(dir, { ...candidate, state: "blocked" });
|
|
14110
|
+
const lead = candidate.baseCurrent === null ? `\u0412\u0435\u0440\u0441\u0438\u044F ${candidate.version} \u043D\u0435 \u0432\u0441\u0442\u0430\u043B\u0430.` : `\u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F ${candidate.version} \u043D\u0435 \u0432\u0441\u0442\u0430\u043B\u0430 \u2014 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043F\u0440\u0435\u0436\u043D\u044F\u044F ${candidate.baseCurrent}, \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043C\u043E\u0436\u043D\u043E.`;
|
|
13933
14111
|
return {
|
|
13934
14112
|
ok: false,
|
|
13935
|
-
text:
|
|
13936
|
-
|
|
14113
|
+
text: text2.includes("\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C:") ? `${lead}
|
|
14114
|
+
${text2}` : `${lead}
|
|
14115
|
+
${text2}
|
|
14116
|
+
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438 setup \u043F\u043E\u0437\u0436\u0435 \u2014 \u0441\u0432\u044F\u0437\u044C \u043C\u043E\u0433\u043B\u0430 \u043E\u0431\u043E\u0440\u0432\u0430\u0442\u044C\u0441\u044F. \u041E\u0442\u043A\u0430\u0436\u0435\u0442 \u0442\u0435\u043C \u0436\u0435 \u2014 \u044D\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044F \u0441\u043B\u043E\u043C\u0430\u043D\u0430: \u043C\u043E\u043D\u0442\u0438\u0440\u0443\u0439 \u043D\u0430 \u043F\u0440\u0435\u0436\u043D\u0435\u0439 \u0438 \u0434\u043E\u0436\u0434\u0438\u0441\u044C \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0439.`
|
|
13937
14117
|
};
|
|
13938
14118
|
}
|
|
14119
|
+
function commandWords(trouble) {
|
|
14120
|
+
const text2 = parseFailure(trouble, describeFailure(trouble)).text;
|
|
14121
|
+
if (!text2.includes("Traceback (most recent call last):")) return text2;
|
|
14122
|
+
return lastLine(text2);
|
|
14123
|
+
}
|
|
13939
14124
|
function sameCandidateState(actual, expected) {
|
|
13940
14125
|
if (actual === null) return false;
|
|
13941
14126
|
const samePayload = actual.payload === void 0 && expected.payload === void 0 || actual.payload !== void 0 && expected.payload !== void 0 && samePayloadProof(actual.payload, expected.payload);
|
|
@@ -13986,9 +14171,9 @@ async function prepareCopiedCandidateVenv(engine, dir, version2, place) {
|
|
|
13986
14171
|
if (engine.prepareCandidateVenv !== void 0) {
|
|
13987
14172
|
await engine.prepareCandidateVenv(place);
|
|
13988
14173
|
} else {
|
|
13989
|
-
const { execFile:
|
|
14174
|
+
const { execFile: execFile4 } = await import('child_process');
|
|
13990
14175
|
const { promisify: promisify3 } = await import('util');
|
|
13991
|
-
await promisify3(
|
|
14176
|
+
await promisify3(execFile4)(engine.bootstrapPython(), ["-m", "venv", "--copies", venv], {
|
|
13992
14177
|
timeout: 10 * 6e4,
|
|
13993
14178
|
encoding: "utf8",
|
|
13994
14179
|
env: { ...engine.pythonEnv(), PYTHONDONTWRITEBYTECODE: "1" }
|
|
@@ -14004,7 +14189,7 @@ async function prepareCopiedCandidateVenv(engine, dir, version2, place) {
|
|
|
14004
14189
|
}
|
|
14005
14190
|
async function candidatePipReady(engine, python) {
|
|
14006
14191
|
if (engine.candidatePipReady !== void 0) return engine.candidatePipReady(python);
|
|
14007
|
-
const { execFile:
|
|
14192
|
+
const { execFile: execFile4 } = await import('child_process');
|
|
14008
14193
|
const { promisify: promisify3 } = await import('util');
|
|
14009
14194
|
const env = { ...engine.pythonEnv(), PYTHONDONTWRITEBYTECODE: "1" };
|
|
14010
14195
|
delete env["PYTHONHOME"];
|
|
@@ -14012,7 +14197,7 @@ async function candidatePipReady(engine, python) {
|
|
|
14012
14197
|
delete env["VIRTUAL_ENV"];
|
|
14013
14198
|
delete env["__PYVENV_LAUNCHER__"];
|
|
14014
14199
|
try {
|
|
14015
|
-
await promisify3(
|
|
14200
|
+
await promisify3(execFile4)(python, ["-B", "-m", "pip", "--version"], {
|
|
14016
14201
|
timeout: 6e4,
|
|
14017
14202
|
encoding: "utf8",
|
|
14018
14203
|
env
|
|
@@ -14119,7 +14304,7 @@ async function activatePreparedCandidateLocked(engine, manifest, trial, extras =
|
|
|
14119
14304
|
if (installedVenvTrouble !== null) throw new Error(installedVenvTrouble);
|
|
14120
14305
|
} catch (trouble) {
|
|
14121
14306
|
return blockCandidate(dir, candidate, `\u041E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432\u043E \u2014 current \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.
|
|
14122
|
-
${
|
|
14307
|
+
${commandWords(trouble)}`);
|
|
14123
14308
|
}
|
|
14124
14309
|
}
|
|
14125
14310
|
const python = engine.candidatePython(place);
|
|
@@ -14163,7 +14348,7 @@ ${smoke}`);
|
|
|
14163
14348
|
dir,
|
|
14164
14349
|
candidate,
|
|
14165
14350
|
`\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0441\u0440\u0435\u0434\u0430 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432\u0430 \u2014 current \u0438 \u043E\u0431\u0449\u0438\u0435 \u0440\u0430\u0431\u043E\u0447\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044B \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.
|
|
14166
|
-
${
|
|
14351
|
+
${commandWords(trouble)}`
|
|
14167
14352
|
);
|
|
14168
14353
|
}
|
|
14169
14354
|
const firstCompatibility = await compatibilityProof(engine, dir, candidate.version, python, place);
|
|
@@ -14324,9 +14509,9 @@ async function dryRun(engine, build, expected, trial) {
|
|
|
14324
14509
|
}
|
|
14325
14510
|
}
|
|
14326
14511
|
async function probe(engine, consolePy) {
|
|
14327
|
-
const { execFile:
|
|
14512
|
+
const { execFile: execFile4 } = await import('child_process');
|
|
14328
14513
|
const { promisify: promisify3 } = await import('util');
|
|
14329
|
-
return promisify3(
|
|
14514
|
+
return promisify3(execFile4)(engine.enginePython(), [consolePy, "version"], {
|
|
14330
14515
|
timeout: 6e4,
|
|
14331
14516
|
encoding: "utf8",
|
|
14332
14517
|
env: engine.pythonEnv()
|
|
@@ -14508,8 +14693,8 @@ function fieldLine(header, start, length) {
|
|
|
14508
14693
|
return chunk.subarray(0, end === -1 ? chunk.length : end).toString("utf8");
|
|
14509
14694
|
}
|
|
14510
14695
|
function octal(header, start, length) {
|
|
14511
|
-
const
|
|
14512
|
-
const ch = Number.parseInt(
|
|
14696
|
+
const text2 = fieldLine(header, start, length).trim();
|
|
14697
|
+
const ch = Number.parseInt(text2, 8);
|
|
14513
14698
|
return Number.isFinite(ch) ? ch : 0;
|
|
14514
14699
|
}
|
|
14515
14700
|
function fieldSize(header, start, length) {
|
|
@@ -14769,7 +14954,7 @@ var probeShell = async (entry) => {
|
|
|
14769
14954
|
encoding: "utf8",
|
|
14770
14955
|
env
|
|
14771
14956
|
});
|
|
14772
|
-
await new Promise((
|
|
14957
|
+
await new Promise((resolve5, reject) => {
|
|
14773
14958
|
const child = spawn(process.execPath, [entry], { stdio: ["pipe", "pipe", "pipe"], env });
|
|
14774
14959
|
let output = "";
|
|
14775
14960
|
let errors = "";
|
|
@@ -14780,7 +14965,7 @@ var probeShell = async (entry) => {
|
|
|
14780
14965
|
finished = true;
|
|
14781
14966
|
clearTimeout(timer);
|
|
14782
14967
|
child.kill();
|
|
14783
|
-
if (trouble === void 0)
|
|
14968
|
+
if (trouble === void 0) resolve5();
|
|
14784
14969
|
else reject(trouble);
|
|
14785
14970
|
};
|
|
14786
14971
|
const send = (message) => {
|
|
@@ -15116,10 +15301,10 @@ function recoverInterruptedPublication(dir) {
|
|
|
15116
15301
|
\u041E\u043D\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0440\u0430\u0431\u043E\u0447\u0430\u044F: setup \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442 \u044D\u0442\u043E\u0442 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442 \u0438 \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u043E\u0431\u0435\u0440\u0451\u0442 \u0435\u0433\u043E \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435.`
|
|
15117
15302
|
};
|
|
15118
15303
|
}
|
|
15119
|
-
function platformKey(os = process.platform,
|
|
15120
|
-
if (os === "darwin") return
|
|
15121
|
-
if (os === "win32") return
|
|
15122
|
-
if (os === "linux") return
|
|
15304
|
+
function platformKey(os = process.platform, arch2 = process.arch) {
|
|
15305
|
+
if (os === "darwin") return arch2 === "arm64" ? "Darwin-arm64" : arch2 === "x64" ? "Darwin-x86_64" : null;
|
|
15306
|
+
if (os === "win32") return arch2 === "x64" ? "Windows-AMD64" : null;
|
|
15307
|
+
if (os === "linux") return arch2 === "x64" ? "Linux-x86_64" : arch2 === "arm64" ? "Linux-aarch64" : null;
|
|
15123
15308
|
return null;
|
|
15124
15309
|
}
|
|
15125
15310
|
function pythonSource(engineDir, key = platformKey()) {
|
|
@@ -15382,9 +15567,244 @@ function safePythonDirectory(home, pythonDir) {
|
|
|
15382
15567
|
}
|
|
15383
15568
|
}
|
|
15384
15569
|
function troubleText(what, trouble) {
|
|
15385
|
-
const
|
|
15570
|
+
const tail2 = trouble instanceof DeliveryError ? trouble.message : trouble instanceof Error ? trouble.message : String(trouble);
|
|
15386
15571
|
return `${what}, \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.
|
|
15387
|
-
${
|
|
15572
|
+
${tail2}` + (tail2.includes("\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C:") ? "" : "\n\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0438\u0441\u043F\u0440\u0430\u0432\u044C\u0442\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u0443\u044E \u043F\u0440\u0438\u0447\u0438\u043D\u0443 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup.");
|
|
15573
|
+
}
|
|
15574
|
+
|
|
15575
|
+
// src/progress.ts
|
|
15576
|
+
var realPace = {
|
|
15577
|
+
now: () => Date.now(),
|
|
15578
|
+
rest: (ms) => new Promise((done) => {
|
|
15579
|
+
setTimeout(done, ms);
|
|
15580
|
+
})
|
|
15581
|
+
};
|
|
15582
|
+
var WAIT_LIMIT_SECONDS = 55;
|
|
15583
|
+
var POLL_EVERY_MS = 2e3;
|
|
15584
|
+
var JOB_STILL_COMPUTING = "\u0415\u0449\u0451 \u0441\u0447\u0438\u0442\u0430\u0435\u0442";
|
|
15585
|
+
var JOB_IN_QUEUE = "\u0416\u0434\u0451\u0442 \u043E\u0447\u0435\u0440\u0435\u0434\u0438";
|
|
15586
|
+
function stillWorking(text2) {
|
|
15587
|
+
return text2.includes(JOB_STILL_COMPUTING) || text2.includes(JOB_IN_QUEUE);
|
|
15588
|
+
}
|
|
15589
|
+
function waitSeconds(asked) {
|
|
15590
|
+
if (asked === void 0 || !Number.isFinite(asked) || asked <= 0) return 0;
|
|
15591
|
+
return Math.min(Math.round(asked), WAIT_LIMIT_SECONDS);
|
|
15592
|
+
}
|
|
15593
|
+
function freshLines(text2, told) {
|
|
15594
|
+
const news = [];
|
|
15595
|
+
for (const row of text2.split("\n").slice(1)) {
|
|
15596
|
+
const line = row.trim();
|
|
15597
|
+
if (line.length === 0) continue;
|
|
15598
|
+
if (line.startsWith(JOB_STILL_COMPUTING)) continue;
|
|
15599
|
+
if (told.has(line)) continue;
|
|
15600
|
+
told.add(line);
|
|
15601
|
+
news.push(line);
|
|
15602
|
+
}
|
|
15603
|
+
return news;
|
|
15604
|
+
}
|
|
15605
|
+
async function followJob(opts) {
|
|
15606
|
+
const pace = opts.pace ?? realPace;
|
|
15607
|
+
const until = pace.now() + opts.seconds * 1e3;
|
|
15608
|
+
const told = /* @__PURE__ */ new Set();
|
|
15609
|
+
let state = await opts.ask();
|
|
15610
|
+
retell(state, told, opts.tell);
|
|
15611
|
+
while (state.ok && stillWorking(state.text) && pace.now() < until) {
|
|
15612
|
+
await pace.rest(POLL_EVERY_MS);
|
|
15613
|
+
try {
|
|
15614
|
+
state = await opts.ask();
|
|
15615
|
+
} catch {
|
|
15616
|
+
continue;
|
|
15617
|
+
}
|
|
15618
|
+
retell(state, told, opts.tell);
|
|
15619
|
+
}
|
|
15620
|
+
return state;
|
|
15621
|
+
}
|
|
15622
|
+
function retell(state, told, tell) {
|
|
15623
|
+
if (tell === void 0) return;
|
|
15624
|
+
for (const line of freshLines(state.text, told)) tell(line);
|
|
15625
|
+
}
|
|
15626
|
+
var PAUSES_LADDER = [
|
|
15627
|
+
"\u0423\u0431\u0435\u0440\u0443 \u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u0438 \u0437\u0430\u043F\u0438\u043D\u043A\u0438 \u2014 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0442\u0440\u043E\u0433\u0430\u044E.",
|
|
15628
|
+
"\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044B, \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u043F\u043E\u0432\u0435\u0440\u0445 \u0438 \u0437\u0432\u0443\u043A \u2014 \u044D\u0442\u043E \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u0430\u044F \u0440\u0430\u0431\u043E\u0442\u0430, \u0435\u0451 \u0437\u0434\u0435\u0441\u044C \u043D\u0435\u0442."
|
|
15629
|
+
];
|
|
15630
|
+
var PAYLOAD_LADDER = [
|
|
15631
|
+
"\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043F\u043E\u043B\u043E\u0436\u0443 \u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043E\u0434\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439 \u2014 \u0432 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F.",
|
|
15632
|
+
"\u041F\u043E\u0442\u043E\u043C ffmpeg, python \u0438 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430. \u0422\u044F\u0436\u0451\u043B\u043E\u0435 \u2014 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438, \u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F, \u0447\u0438\u0441\u0442\u043A\u0430 \u0433\u043E\u043B\u043E\u0441\u0430 \u2014 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435."
|
|
15633
|
+
];
|
|
15634
|
+
var INSTALL_WORDS = {
|
|
15635
|
+
ffmpeg: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E ffmpeg \u2014 \u0438\u043C \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0432\u0438\u0434\u0435\u043E",
|
|
15636
|
+
python: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E python",
|
|
15637
|
+
env: "\u0441\u043E\u0431\u0435\u0440\u0443 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
15638
|
+
model: "\u0441\u043A\u0430\u0447\u0430\u044E \u043C\u043E\u0434\u0435\u043B\u044C \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u044F \u0440\u0435\u0447\u0438 \u2014 \u043E\u043D\u0430 \u0438\u0437 \u0432\u0441\u0435\u0433\u043E \u0441\u0430\u043C\u0430\u044F \u0442\u044F\u0436\u0451\u043B\u0430\u044F",
|
|
15639
|
+
cutout: "\u0441\u043A\u0430\u0447\u0430\u044E \u0442\u043E, \u0447\u0435\u043C \u043E\u0442\u0434\u0435\u043B\u044F\u044E \u0433\u0435\u0440\u043E\u044F \u043E\u0442 \u0444\u043E\u043D\u0430",
|
|
15640
|
+
voice: "\u0441\u043A\u0430\u0447\u0430\u044E \u0442\u043E, \u0447\u0435\u043C \u0447\u0438\u0449\u0443 \u0433\u043E\u043B\u043E\u0441",
|
|
15641
|
+
browser: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u0440\u0438\u0441\u0443\u044E \u0433\u0440\u0430\u0444\u0438\u043A\u0443"
|
|
15642
|
+
};
|
|
15643
|
+
function installLadder(step) {
|
|
15644
|
+
if (step === "all") {
|
|
15645
|
+
return [
|
|
15646
|
+
"\u041F\u0440\u043E\u0432\u0435\u0440\u044E, \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0438 \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u043F\u043E \u043E\u0447\u0435\u0440\u0435\u0434\u0438.",
|
|
15647
|
+
"\u0422\u044F\u0436\u0451\u043B\u043E\u0435 \u0441\u044E\u0434\u0430 \u043D\u0435 \u0432\u0445\u043E\u0434\u0438\u0442: \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438 \u0438 \u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F \u0441\u0442\u0430\u0432\u044F\u0442\u0441\u044F \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \xAB\u0434\u0430\xBB \u043E\u0442 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430."
|
|
15648
|
+
];
|
|
15649
|
+
}
|
|
15650
|
+
const word = INSTALL_WORDS[step];
|
|
15651
|
+
if (word === void 0) return [];
|
|
15652
|
+
return [
|
|
15653
|
+
`\u0421\u0435\u0439\u0447\u0430\u0441 ${word}.`,
|
|
15654
|
+
"\u0418\u0434\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0430\u043C\u0438. \u041E\u0431\u043E\u0440\u0432\u0451\u0442\u0441\u044F \u2014 \u043F\u043E\u0432\u0442\u043E\u0440\u0438 \u0442\u043E\u0442 \u0436\u0435 \u0448\u0430\u0433: \u0443\u0436\u0435 \u0441\u043A\u0430\u0447\u0430\u043D\u043D\u043E\u0435 \u043D\u0435 \u043F\u0440\u043E\u043F\u0430\u0434\u0451\u0442."
|
|
15655
|
+
];
|
|
15656
|
+
}
|
|
15657
|
+
var CALLS_FILE = "calls.jsonl";
|
|
15658
|
+
var CALLS_PREVIOUS = "calls.1.jsonl";
|
|
15659
|
+
var CALLS_CAP_BYTES = 1e6;
|
|
15660
|
+
function withCallLog(home, now = () => Date.now()) {
|
|
15661
|
+
return (tool) => {
|
|
15662
|
+
const original = tool.execute.bind(tool);
|
|
15663
|
+
return {
|
|
15664
|
+
...tool,
|
|
15665
|
+
async execute(input, ...rest) {
|
|
15666
|
+
const started = now();
|
|
15667
|
+
const result = await original(input, ...rest);
|
|
15668
|
+
write(home, {
|
|
15669
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15670
|
+
tool: tool.name,
|
|
15671
|
+
ok: result.type === "success",
|
|
15672
|
+
ms: now() - started
|
|
15673
|
+
});
|
|
15674
|
+
return result;
|
|
15675
|
+
}
|
|
15676
|
+
};
|
|
15677
|
+
};
|
|
15678
|
+
}
|
|
15679
|
+
function write(home, line) {
|
|
15680
|
+
try {
|
|
15681
|
+
mkdirSync(home, { recursive: true });
|
|
15682
|
+
const file2 = join(home, CALLS_FILE);
|
|
15683
|
+
rotate(file2, join(home, CALLS_PREVIOUS));
|
|
15684
|
+
appendFileSync(file2, `${JSON.stringify(line)}
|
|
15685
|
+
`, { encoding: "utf8", mode: 384 });
|
|
15686
|
+
} catch {
|
|
15687
|
+
}
|
|
15688
|
+
}
|
|
15689
|
+
function rotate(file2, previous) {
|
|
15690
|
+
try {
|
|
15691
|
+
if (statSync(file2).size >= CALLS_CAP_BYTES) renameSync(file2, previous);
|
|
15692
|
+
} catch {
|
|
15693
|
+
}
|
|
15694
|
+
}
|
|
15695
|
+
|
|
15696
|
+
// src/contracts/crash-report.ts
|
|
15697
|
+
var CRASH_REPORT_PATH = "/crash-report";
|
|
15698
|
+
var CRASH_CONTRACT = "naparnik-crash/1";
|
|
15699
|
+
var CRASH_LIMITS = {
|
|
15700
|
+
bodyBytes: 65536,
|
|
15701
|
+
errorType: 120,
|
|
15702
|
+
message: 500,
|
|
15703
|
+
trace: 8e3,
|
|
15704
|
+
stage: 120,
|
|
15705
|
+
osPlatform: 32,
|
|
15706
|
+
osRelease: 64,
|
|
15707
|
+
osArch: 16,
|
|
15708
|
+
hostName: 64,
|
|
15709
|
+
hostVersion: 32,
|
|
15710
|
+
shellVersion: 32,
|
|
15711
|
+
engineVersion: 64,
|
|
15712
|
+
pythonVersion: 16,
|
|
15713
|
+
ffmpegVersion: 64,
|
|
15714
|
+
recentCalls: 10,
|
|
15715
|
+
repeats: 1e5
|
|
15716
|
+
};
|
|
15717
|
+
var CRASH_TOOL_NAME = /^[a-z_]{1,64}$/;
|
|
15718
|
+
var CRASH_FINGERPRINT = /^[0-9a-f]{16}$/;
|
|
15719
|
+
var text = (max) => external_exports.string().max(max);
|
|
15720
|
+
var CrashReportRequest = external_exports.object({
|
|
15721
|
+
contract: external_exports.literal(CRASH_CONTRACT),
|
|
15722
|
+
occurred_at: external_exports.string().datetime({ offset: true }),
|
|
15723
|
+
where: external_exports.enum(["tool", "job", "process"]),
|
|
15724
|
+
tool: external_exports.string().regex(CRASH_TOOL_NAME).nullable(),
|
|
15725
|
+
stage: text(CRASH_LIMITS.stage).nullable(),
|
|
15726
|
+
error_type: external_exports.string().min(1).max(CRASH_LIMITS.errorType),
|
|
15727
|
+
message: text(CRASH_LIMITS.message),
|
|
15728
|
+
trace: text(CRASH_LIMITS.trace),
|
|
15729
|
+
fingerprint: external_exports.string().regex(CRASH_FINGERPRINT),
|
|
15730
|
+
repeats: external_exports.number().int().min(0).max(CRASH_LIMITS.repeats),
|
|
15731
|
+
os: external_exports.object({
|
|
15732
|
+
platform: text(CRASH_LIMITS.osPlatform),
|
|
15733
|
+
release: text(CRASH_LIMITS.osRelease),
|
|
15734
|
+
arch: text(CRASH_LIMITS.osArch)
|
|
15735
|
+
}).strict(),
|
|
15736
|
+
host: external_exports.object({
|
|
15737
|
+
name: text(CRASH_LIMITS.hostName),
|
|
15738
|
+
version: text(CRASH_LIMITS.hostVersion)
|
|
15739
|
+
}).strict().nullable(),
|
|
15740
|
+
versions: external_exports.object({
|
|
15741
|
+
shell: text(CRASH_LIMITS.shellVersion),
|
|
15742
|
+
engine: text(CRASH_LIMITS.engineVersion).nullable(),
|
|
15743
|
+
python: text(CRASH_LIMITS.pythonVersion).nullable(),
|
|
15744
|
+
ffmpeg: text(CRASH_LIMITS.ffmpegVersion).nullable()
|
|
15745
|
+
}).strict(),
|
|
15746
|
+
recent_calls: external_exports.array(external_exports.string().regex(CRASH_TOOL_NAME)).max(CRASH_LIMITS.recentCalls)
|
|
15747
|
+
}).strict();
|
|
15748
|
+
var SECRET_MIN = 4;
|
|
15749
|
+
var HUMAN_FILE = /[^\s"'«»“”/\\<>()]{0,255}\.(?:mp4|mov|m4v|mkv|avi|webm|mts|wav|mp3|m4a|aac|flac|ogg|jpg|jpeg|png|heic|gif|srt|vtt)\b/gi;
|
|
15750
|
+
var PATH = /(?:<naparnik>|<shell>|~|[A-Za-z]:)?(?:[\\/][^\s"'«»“”<>|,;()[\]{}\\/]+)+[\\/]?/g;
|
|
15751
|
+
var QUOTED = /(["'])([^"'\n]*)\1|«([^»\n]*)»|“([^”\n]*)”/g;
|
|
15752
|
+
var KEY = /npk_[A-Za-z0-9_-]{6,}/g;
|
|
15753
|
+
function scrub(text2, context) {
|
|
15754
|
+
let out = text2.replace(KEY, "<key>");
|
|
15755
|
+
for (const secret of secretForms(context.secrets)) {
|
|
15756
|
+
out = replaceAll(out, secret, "<video>");
|
|
15757
|
+
}
|
|
15758
|
+
out = replaceAll(out, context.shellDir, "<shell>");
|
|
15759
|
+
out = replaceAll(out, context.naparnikHome, "<naparnik>");
|
|
15760
|
+
out = replaceAll(out, context.home, "~");
|
|
15761
|
+
out = out.replace(/(?:\/Users|\/home|[A-Za-z]:\\Users|[A-Za-z]:\/Users)[\\/][^\s"'«»“”\\/]+/g, "~");
|
|
15762
|
+
out = out.replace(QUOTED, (whole, _q, plain, fir, curly) => {
|
|
15763
|
+
const inside2 = plain ?? fir ?? curly ?? "";
|
|
15764
|
+
if (!looksHuman(inside2)) return whole;
|
|
15765
|
+
const [open, close] = plain !== void 0 ? [_q, _q] : fir !== void 0 ? ["\xAB", "\xBB"] : ["\u201C", "\u201D"];
|
|
15766
|
+
return `${open}${looksLikePath(inside2) ? pathOrMark(inside2) : "<text>"}${close}`;
|
|
15767
|
+
});
|
|
15768
|
+
out = out.replace(PATH, (found) => pathOrMark(found));
|
|
15769
|
+
out = out.replace(HUMAN_FILE, "<file>");
|
|
15770
|
+
out = swallowSpacedTails(out);
|
|
15771
|
+
if (context.user.length >= 3) out = replaceAll(out, context.user, "<user>");
|
|
15772
|
+
return out;
|
|
15773
|
+
}
|
|
15774
|
+
function swallowSpacedTails(text2) {
|
|
15775
|
+
return text2.replace(/<(?:path|file)>[^\n:<>"'«»“”]{0,512}<(?:path|file)>/g, "<path>").replace(/(<(?:path|file)>)([^\n:<>"'«»“”]{0,512})/g, (whole, mark, tail2) => /[^\x00-\x7F]/.test(tail2) ? mark : whole);
|
|
15776
|
+
}
|
|
15777
|
+
function secretForms(secrets) {
|
|
15778
|
+
const forms = /* @__PURE__ */ new Set();
|
|
15779
|
+
for (const raw of secrets) {
|
|
15780
|
+
const value = raw.trim();
|
|
15781
|
+
if (value.length < SECRET_MIN) continue;
|
|
15782
|
+
forms.add(value);
|
|
15783
|
+
if (!looksLikePath(value)) continue;
|
|
15784
|
+
if (isAbsolute(value)) forms.add(resolve(value));
|
|
15785
|
+
const name = basename(value);
|
|
15786
|
+
const stem = name.slice(0, name.length - extname(name).length);
|
|
15787
|
+
for (const one of [name, stem, `${stem}.montage`]) {
|
|
15788
|
+
if (one.length >= SECRET_MIN) forms.add(one);
|
|
15789
|
+
}
|
|
15790
|
+
}
|
|
15791
|
+
return [...forms].sort((a, b) => b.length - a.length);
|
|
15792
|
+
}
|
|
15793
|
+
function pathOrMark(found) {
|
|
15794
|
+
const flat = found.replace(/\\/g, "/");
|
|
15795
|
+
const ours = /^(?:<naparnik>|~\/\.naparnik)\/(?:engine|shell|bin)(?:\/|$)/.test(flat) || flat.startsWith("<shell>") || /\/(?:site-packages|dist-packages|node_modules)\//.test(flat) || /\/lib\/python\d/i.test(flat) || /\/Python\d+\/Lib\//i.test(flat);
|
|
15796
|
+
return ours ? found : "<path>";
|
|
15797
|
+
}
|
|
15798
|
+
var HUMAN_FILE_ONE = new RegExp(HUMAN_FILE.source, "i");
|
|
15799
|
+
function looksLikePath(value) {
|
|
15800
|
+
return /[\\/]/.test(value) || HUMAN_FILE_ONE.test(value);
|
|
15801
|
+
}
|
|
15802
|
+
function looksHuman(inside2) {
|
|
15803
|
+
return /[^\x00-\x7F]/.test(inside2) || /\s/.test(inside2) || looksLikePath(inside2);
|
|
15804
|
+
}
|
|
15805
|
+
function replaceAll(text2, what, by) {
|
|
15806
|
+
if (what === "") return text2;
|
|
15807
|
+
return text2.split(what).join(by);
|
|
15388
15808
|
}
|
|
15389
15809
|
|
|
15390
15810
|
// src/job-report.ts
|
|
@@ -15431,14 +15851,14 @@ var PLAN_HEAD = /^План:$/;
|
|
|
15431
15851
|
var PLAN_ROW = /^· (.+)$/;
|
|
15432
15852
|
var STYLE = /^Стиль: /;
|
|
15433
15853
|
var LEFT_TAIL = /\.\s+(Осталось .+)$/;
|
|
15434
|
-
function readJob(
|
|
15435
|
-
const lines =
|
|
15436
|
-
const
|
|
15437
|
-
if (
|
|
15854
|
+
function readJob(text2) {
|
|
15855
|
+
const lines = text2.split("\n").map((row) => row.trimEnd());
|
|
15856
|
+
const head2 = HEAD.exec(lines[0]?.trim() ?? "");
|
|
15857
|
+
if (head2 === null) return null;
|
|
15438
15858
|
const job = empty();
|
|
15439
|
-
job.id =
|
|
15440
|
-
job.what = (
|
|
15441
|
-
let
|
|
15859
|
+
job.id = head2[1] ?? "";
|
|
15860
|
+
job.what = (head2[2] ?? "").trim();
|
|
15861
|
+
let tail2 = null;
|
|
15442
15862
|
for (const row of lines.slice(1)) {
|
|
15443
15863
|
const line = row.trim();
|
|
15444
15864
|
if (line === "") continue;
|
|
@@ -15446,17 +15866,17 @@ function readJob(text) {
|
|
|
15446
15866
|
const complaint = COMPLAINT.exec(line);
|
|
15447
15867
|
if (complaint !== null) {
|
|
15448
15868
|
job.complaints.push(complaint[1] ?? "");
|
|
15449
|
-
|
|
15869
|
+
tail2 = null;
|
|
15450
15870
|
continue;
|
|
15451
15871
|
}
|
|
15452
15872
|
if (PLAN_HEAD.test(line)) {
|
|
15453
|
-
|
|
15873
|
+
tail2 = null;
|
|
15454
15874
|
continue;
|
|
15455
15875
|
}
|
|
15456
15876
|
const planRow = PLAN_ROW.exec(line);
|
|
15457
15877
|
if (planRow !== null) {
|
|
15458
15878
|
job.plan.push(planRow[1] ?? "");
|
|
15459
|
-
|
|
15879
|
+
tail2 = null;
|
|
15460
15880
|
continue;
|
|
15461
15881
|
}
|
|
15462
15882
|
const behind = BEHIND.exec(line);
|
|
@@ -15487,13 +15907,13 @@ function readJob(text) {
|
|
|
15487
15907
|
if (done !== null) {
|
|
15488
15908
|
job.status = "done";
|
|
15489
15909
|
job.sec = seconds(done[1]);
|
|
15490
|
-
|
|
15910
|
+
tail2 = [];
|
|
15491
15911
|
continue;
|
|
15492
15912
|
}
|
|
15493
15913
|
const file2 = FILE.exec(line);
|
|
15494
15914
|
if (file2 !== null && job.status === "done") {
|
|
15495
15915
|
job.file = file2[1] ?? "";
|
|
15496
|
-
|
|
15916
|
+
tail2 = null;
|
|
15497
15917
|
continue;
|
|
15498
15918
|
}
|
|
15499
15919
|
const failed = FAILED.exec(line);
|
|
@@ -15501,20 +15921,20 @@ function readJob(text) {
|
|
|
15501
15921
|
job.status = "error";
|
|
15502
15922
|
job.sec = seconds(failed[1]);
|
|
15503
15923
|
job.trouble = failed[2] ?? "";
|
|
15504
|
-
|
|
15924
|
+
tail2 = null;
|
|
15505
15925
|
continue;
|
|
15506
15926
|
}
|
|
15507
15927
|
if (ABORTED.test(line)) {
|
|
15508
15928
|
job.status = "aborted";
|
|
15509
15929
|
job.trouble = line;
|
|
15510
15930
|
job.sec = seconds(ABORTED_SEC.exec(line)?.[1]);
|
|
15511
|
-
|
|
15931
|
+
tail2 = null;
|
|
15512
15932
|
continue;
|
|
15513
15933
|
}
|
|
15514
15934
|
const advice = ADVICE.exec(line);
|
|
15515
15935
|
if (advice !== null) {
|
|
15516
15936
|
job.advice = advice[1] ?? "";
|
|
15517
|
-
|
|
15937
|
+
tail2 = null;
|
|
15518
15938
|
continue;
|
|
15519
15939
|
}
|
|
15520
15940
|
if (WAITING.test(line)) {
|
|
@@ -15528,82 +15948,560 @@ function readJob(text) {
|
|
|
15528
15948
|
job.sec = seconds(running[1]);
|
|
15529
15949
|
continue;
|
|
15530
15950
|
}
|
|
15531
|
-
if (
|
|
15532
|
-
|
|
15533
|
-
job.outcome =
|
|
15951
|
+
if (tail2 !== null) {
|
|
15952
|
+
tail2.push(line);
|
|
15953
|
+
job.outcome = tail2.join("\n");
|
|
15534
15954
|
continue;
|
|
15535
15955
|
}
|
|
15536
15956
|
if (job.status === "running" || job.status === "waiting") job.message = line;
|
|
15537
15957
|
}
|
|
15538
15958
|
return job;
|
|
15539
15959
|
}
|
|
15540
|
-
function seconds(
|
|
15541
|
-
if (
|
|
15542
|
-
const value = Number(
|
|
15960
|
+
function seconds(text2) {
|
|
15961
|
+
if (text2 === void 0) return 0;
|
|
15962
|
+
const value = Number(text2.replace(",", "."));
|
|
15543
15963
|
return Number.isFinite(value) ? value : 0;
|
|
15544
15964
|
}
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
|
|
15548
|
-
|
|
15549
|
-
var
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15965
|
+
|
|
15966
|
+
// src/crash-report.ts
|
|
15967
|
+
var RESEND_AFTER_MS = 30 * 6e4;
|
|
15968
|
+
var QUEUE_CAP = 20;
|
|
15969
|
+
var FLUSH_PER_PASS = 5;
|
|
15970
|
+
var FLUSH_EVERY_MS = 6e4;
|
|
15971
|
+
var SEND_TIMEOUT_MS = 3e3;
|
|
15972
|
+
var JOB_LOG_TAIL = 64 * 1024;
|
|
15973
|
+
var PYTHON_TRACEBACK = "Traceback (most recent call last):";
|
|
15974
|
+
var CrashReporter = class {
|
|
15975
|
+
#deps;
|
|
15976
|
+
#now;
|
|
15977
|
+
#inflight = /* @__PURE__ */ new Set();
|
|
15978
|
+
#lastFlush = Number.NEGATIVE_INFINITY;
|
|
15979
|
+
#host = null;
|
|
15980
|
+
/**
|
|
15981
|
+
* Строки из аргументов недавних вызовов — только в памяти процесса.
|
|
15982
|
+
*
|
|
15983
|
+
* ⚠ ЗАЧЕМ. Задание упало — отчёт о нём приходит на `wait`, а в аргументах
|
|
15984
|
+
* `wait` лишь номер задания; путь к ролику был в аргументах `render`,
|
|
15985
|
+
* который задание запустил. Без этой памяти путь с пробелами из трейса ffmpeg
|
|
15986
|
+
* вычищался бы только общими правилами, а они его режут на куски (ревью
|
|
15987
|
+
* безопасности 2026-09-24). На диск не пишется: это ровно то, что мы
|
|
15988
|
+
* обещали не хранить.
|
|
15989
|
+
*/
|
|
15990
|
+
#recentSecrets = [];
|
|
15991
|
+
#ffmpeg = null;
|
|
15992
|
+
constructor(deps) {
|
|
15993
|
+
this.#deps = deps;
|
|
15994
|
+
this.#now = deps.now ?? (() => Date.now());
|
|
15555
15995
|
}
|
|
15556
|
-
|
|
15557
|
-
|
|
15558
|
-
:root {
|
|
15559
|
-
--font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Icons", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
15996
|
+
get canSend() {
|
|
15997
|
+
return this.#deps.canSend;
|
|
15560
15998
|
}
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
|
|
15564
|
-
|
|
15565
|
-
|
|
15566
|
-
|
|
15567
|
-
|
|
15568
|
-
|
|
15569
|
-
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
15574
|
-
|
|
15575
|
-
|
|
15576
|
-
|
|
15577
|
-
|
|
15578
|
-
|
|
15579
|
-
|
|
15580
|
-
|
|
15581
|
-
|
|
15582
|
-
|
|
15583
|
-
|
|
15584
|
-
|
|
15585
|
-
|
|
15586
|
-
|
|
15587
|
-
|
|
15588
|
-
|
|
15589
|
-
|
|
15590
|
-
|
|
15591
|
-
|
|
15592
|
-
|
|
15593
|
-
|
|
15594
|
-
|
|
15595
|
-
|
|
15596
|
-
|
|
15597
|
-
|
|
15598
|
-
|
|
15599
|
-
|
|
15600
|
-
|
|
15601
|
-
|
|
15602
|
-
|
|
15603
|
-
|
|
15604
|
-
|
|
15605
|
-
|
|
15606
|
-
|
|
15999
|
+
get home() {
|
|
16000
|
+
return this.#deps.home;
|
|
16001
|
+
}
|
|
16002
|
+
/** Запомнить программу-хост: при падении всего процесса контекста вызова нет. */
|
|
16003
|
+
/** Запомнить строки аргументов вызова — чтобы вычеркнуть их из будущих отчётов. */
|
|
16004
|
+
noteSecrets(secrets) {
|
|
16005
|
+
const fresh = secrets.filter((one) => one.length >= 4);
|
|
16006
|
+
if (fresh.length === 0) return;
|
|
16007
|
+
this.#recentSecrets = [...this.#recentSecrets.filter((one) => !fresh.includes(one)), ...fresh].slice(-50);
|
|
16008
|
+
}
|
|
16009
|
+
noteHost(host) {
|
|
16010
|
+
if (host !== null) this.#host = host;
|
|
16011
|
+
}
|
|
16012
|
+
/** Отправить отчёт мимо ответа. Для тестов и смоука — `settled()`. */
|
|
16013
|
+
submit(crash) {
|
|
16014
|
+
this.#track(this.#deliver(crash));
|
|
16015
|
+
}
|
|
16016
|
+
/**
|
|
16017
|
+
* Процесс падает: отчёт кладётся на диск СИНХРОННО и уходит на следующем
|
|
16018
|
+
* запуске. Сеть здесь не трогаем — процессу осталось жить миллисекунды, и
|
|
16019
|
+
* недоставленный наполовину запрос хуже файла, который точно дойдёт.
|
|
16020
|
+
*/
|
|
16021
|
+
persist(crash) {
|
|
16022
|
+
try {
|
|
16023
|
+
const report = this.#build(crash);
|
|
16024
|
+
if (report !== null) this.#enqueue(report);
|
|
16025
|
+
} catch {
|
|
16026
|
+
}
|
|
16027
|
+
}
|
|
16028
|
+
/** Досылка очереди — не чаще раза в минуту. */
|
|
16029
|
+
flushSoon() {
|
|
16030
|
+
const now = this.#now();
|
|
16031
|
+
if (now - this.#lastFlush < FLUSH_EVERY_MS) return;
|
|
16032
|
+
this.#lastFlush = now;
|
|
16033
|
+
this.#track(this.#flush());
|
|
16034
|
+
}
|
|
16035
|
+
/** Дождаться всего, что ушло мимо ответа. Боевому пути не нужно. */
|
|
16036
|
+
async settled() {
|
|
16037
|
+
while (this.#inflight.size > 0) await Promise.allSettled([...this.#inflight]);
|
|
16038
|
+
}
|
|
16039
|
+
/** Задание уже разобрано: отчёт о нём ушёл раньше, в этом или прошлом запуске. */
|
|
16040
|
+
jobSeen(id) {
|
|
16041
|
+
return this.#state().jobs.includes(id);
|
|
16042
|
+
}
|
|
16043
|
+
rememberJob(id) {
|
|
16044
|
+
const state = this.#state();
|
|
16045
|
+
state.jobs = [...state.jobs.filter((one) => one !== id), id].slice(-50);
|
|
16046
|
+
this.#save(state);
|
|
16047
|
+
}
|
|
16048
|
+
scrubContext(secrets) {
|
|
16049
|
+
return {
|
|
16050
|
+
home: this.#deps.osHome ?? homedir(),
|
|
16051
|
+
user: this.#deps.osUser ?? safeUser(),
|
|
16052
|
+
naparnikHome: this.#deps.home,
|
|
16053
|
+
shellDir: this.#deps.shellDir ?? ownDir(),
|
|
16054
|
+
secrets
|
|
16055
|
+
};
|
|
16056
|
+
}
|
|
16057
|
+
#track(work) {
|
|
16058
|
+
const guarded = work.catch(() => void 0);
|
|
16059
|
+
this.#inflight.add(guarded);
|
|
16060
|
+
void guarded.finally(() => this.#inflight.delete(guarded));
|
|
16061
|
+
}
|
|
16062
|
+
async #deliver(crash) {
|
|
16063
|
+
const report = this.#build(crash);
|
|
16064
|
+
if (report === null) return;
|
|
16065
|
+
report.versions.ffmpeg = await this.#ffmpegVersion();
|
|
16066
|
+
const verdict = await this.#send(report);
|
|
16067
|
+
if (verdict === "retry") this.#enqueue(report);
|
|
16068
|
+
}
|
|
16069
|
+
async #flush() {
|
|
16070
|
+
const dir = this.#queueDir();
|
|
16071
|
+
let files;
|
|
16072
|
+
try {
|
|
16073
|
+
files = readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
|
|
16074
|
+
} catch {
|
|
16075
|
+
return;
|
|
16076
|
+
}
|
|
16077
|
+
for (const file2 of files.slice(0, FLUSH_PER_PASS)) {
|
|
16078
|
+
const path2 = join(dir, file2);
|
|
16079
|
+
let report;
|
|
16080
|
+
try {
|
|
16081
|
+
report = JSON.parse(readFileSync(path2, "utf8"));
|
|
16082
|
+
} catch {
|
|
16083
|
+
rmSync(path2, { force: true });
|
|
16084
|
+
continue;
|
|
16085
|
+
}
|
|
16086
|
+
const verdict = await this.#send(report);
|
|
16087
|
+
if (verdict === "retry") return;
|
|
16088
|
+
rmSync(path2, { force: true });
|
|
16089
|
+
}
|
|
16090
|
+
}
|
|
16091
|
+
/**
|
|
16092
|
+
* Отправить и решить, что делать с отчётом дальше.
|
|
16093
|
+
*
|
|
16094
|
+
* ⚠ В ОЧЕРЕДЬ ИДЁТ ТОЛЬКО ТО, ЧТО ПОВТОР ИСПРАВИТ: нет сети, таймаут, 5xx,
|
|
16095
|
+
* 429 и «ключа нет» (человек впишет его завтра). 400 и 413 — отчёт кривой,
|
|
16096
|
+
* 401 и 403 — ключ не наш: повтор даст тот же отказ, а очередь с потолком
|
|
16097
|
+
* вытесняла бы им живые отчёты.
|
|
16098
|
+
*/
|
|
16099
|
+
async #send(report) {
|
|
16100
|
+
if (!CrashReportRequest.safeParse(report).success) return "drop";
|
|
16101
|
+
try {
|
|
16102
|
+
await this.#deps.client.postMontage(CRASH_REPORT_PATH, report, {
|
|
16103
|
+
once: true,
|
|
16104
|
+
timeoutMs: this.#deps.timeoutMs ?? SEND_TIMEOUT_MS
|
|
16105
|
+
});
|
|
16106
|
+
return "sent";
|
|
16107
|
+
} catch (trouble) {
|
|
16108
|
+
if (trouble instanceof NaparnikAuthError || trouble instanceof NaparnikScopeError) return "drop";
|
|
16109
|
+
if (trouble instanceof NaparnikClientError) return trouble.status === 429 ? "retry" : "drop";
|
|
16110
|
+
return "retry";
|
|
16111
|
+
}
|
|
16112
|
+
}
|
|
16113
|
+
/**
|
|
16114
|
+
* Собрать отчёт: обезличить, обрезать, посчитать отпечаток и решить по
|
|
16115
|
+
* частоте. `null` — этот отпечаток уже уходил меньше получаса назад, и
|
|
16116
|
+
* повтор записан в счётчик.
|
|
16117
|
+
*/
|
|
16118
|
+
#build(crash) {
|
|
16119
|
+
const fingerprint = fingerprintOf2(crash.errorType, crash.frames);
|
|
16120
|
+
const state = this.#state();
|
|
16121
|
+
const now = this.#now();
|
|
16122
|
+
const seen = state.fingerprints[fingerprint];
|
|
16123
|
+
if (seen !== void 0 && now - seen.sentAt < RESEND_AFTER_MS) {
|
|
16124
|
+
seen.pending += 1;
|
|
16125
|
+
this.#save(state);
|
|
16126
|
+
return null;
|
|
16127
|
+
}
|
|
16128
|
+
const repeats = Math.min(seen?.pending ?? 0, CRASH_LIMITS.repeats);
|
|
16129
|
+
state.fingerprints[fingerprint] = { sentAt: now, pending: 0 };
|
|
16130
|
+
prune(state, now);
|
|
16131
|
+
this.#save(state);
|
|
16132
|
+
const context = this.scrubContext([...crash.secrets, ...this.#recentSecrets]);
|
|
16133
|
+
const clean = (text2) => scrub(text2, context);
|
|
16134
|
+
return {
|
|
16135
|
+
contract: CRASH_CONTRACT,
|
|
16136
|
+
occurred_at: new Date(now).toISOString(),
|
|
16137
|
+
where: crash.where,
|
|
16138
|
+
tool: crash.tool !== null && CRASH_TOOL_NAME.test(crash.tool) ? crash.tool : null,
|
|
16139
|
+
// ⚠ РЕЖЕМ ДО ОБЕЗЛИЧИВАНИЯ С ЗАПАСОМ И ЕЩЁ РАЗ ПОСЛЕ. Обезличивание идёт
|
|
16140
|
+
// синхронно, до ответа инструмента, а stderr движка бывает мегабайтами:
|
|
16141
|
+
// без первой резки длинный текст подвешивал бы ответ на секунды (ревью
|
|
16142
|
+
// безопасности 2026-09-24). Запас — вдвое: метки короче того, что заменяют.
|
|
16143
|
+
stage: crash.stage === null ? null : head(clean(head(crash.stage, 2 * CRASH_LIMITS.stage)), CRASH_LIMITS.stage),
|
|
16144
|
+
error_type: head(clean(head(crash.errorType, 2 * CRASH_LIMITS.errorType)), CRASH_LIMITS.errorType) || "Error",
|
|
16145
|
+
message: head(clean(head(crash.message, 2 * CRASH_LIMITS.message)), CRASH_LIMITS.message),
|
|
16146
|
+
trace: crash.keep === "tail" ? tail(clean(crash.trace.slice(-2 * CRASH_LIMITS.trace)), CRASH_LIMITS.trace) : head(clean(head(crash.trace, 2 * CRASH_LIMITS.trace)), CRASH_LIMITS.trace),
|
|
16147
|
+
fingerprint,
|
|
16148
|
+
repeats,
|
|
16149
|
+
os: {
|
|
16150
|
+
platform: head(platform(), CRASH_LIMITS.osPlatform),
|
|
16151
|
+
release: head(release(), CRASH_LIMITS.osRelease),
|
|
16152
|
+
arch: head(arch(), CRASH_LIMITS.osArch)
|
|
16153
|
+
},
|
|
16154
|
+
host: hostOf(crash.host ?? this.#host),
|
|
16155
|
+
versions: {
|
|
16156
|
+
shell: head(VERSION, CRASH_LIMITS.shellVersion),
|
|
16157
|
+
engine: orNull(this.#deps.engineVersion(), CRASH_LIMITS.engineVersion),
|
|
16158
|
+
python: orNull(crash.python, CRASH_LIMITS.pythonVersion),
|
|
16159
|
+
ffmpeg: null
|
|
16160
|
+
},
|
|
16161
|
+
recent_calls: recentCalls(this.#deps.home)
|
|
16162
|
+
};
|
|
16163
|
+
}
|
|
16164
|
+
#enqueue(report) {
|
|
16165
|
+
try {
|
|
16166
|
+
const dir = this.#queueDir();
|
|
16167
|
+
mkdirSync(dir, { recursive: true });
|
|
16168
|
+
const name = `${String(this.#now()).padStart(15, "0")}-${report.fingerprint}.json`;
|
|
16169
|
+
const temporary = join(dir, `${name}.tmp`);
|
|
16170
|
+
writeFileSync(temporary, JSON.stringify(report), { mode: 384 });
|
|
16171
|
+
renameSync(temporary, join(dir, name));
|
|
16172
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".json")).sort();
|
|
16173
|
+
for (const old of files.slice(0, Math.max(0, files.length - QUEUE_CAP))) {
|
|
16174
|
+
rmSync(join(dir, old), { force: true });
|
|
16175
|
+
}
|
|
16176
|
+
} catch {
|
|
16177
|
+
}
|
|
16178
|
+
}
|
|
16179
|
+
#queueDir() {
|
|
16180
|
+
return join(this.#deps.home, "crash-reports", "queue");
|
|
16181
|
+
}
|
|
16182
|
+
#stateFile() {
|
|
16183
|
+
return join(this.#deps.home, "crash-reports", "seen.json");
|
|
16184
|
+
}
|
|
16185
|
+
#state() {
|
|
16186
|
+
try {
|
|
16187
|
+
const parsed = JSON.parse(readFileSync(this.#stateFile(), "utf8"));
|
|
16188
|
+
return {
|
|
16189
|
+
fingerprints: typeof parsed.fingerprints === "object" && parsed.fingerprints !== null ? parsed.fingerprints : {},
|
|
16190
|
+
jobs: Array.isArray(parsed.jobs) ? parsed.jobs.filter((j) => typeof j === "string") : []
|
|
16191
|
+
};
|
|
16192
|
+
} catch {
|
|
16193
|
+
return { fingerprints: {}, jobs: [] };
|
|
16194
|
+
}
|
|
16195
|
+
}
|
|
16196
|
+
#save(state) {
|
|
16197
|
+
try {
|
|
16198
|
+
mkdirSync(dirname(this.#stateFile()), { recursive: true });
|
|
16199
|
+
writeFileSync(this.#stateFile(), JSON.stringify(state), { mode: 384 });
|
|
16200
|
+
} catch {
|
|
16201
|
+
}
|
|
16202
|
+
}
|
|
16203
|
+
#ffmpegVersion() {
|
|
16204
|
+
this.#ffmpeg ??= (this.#deps.ffmpegVersion ?? (() => probeFfmpeg(this.#deps.home)))().catch(() => null);
|
|
16205
|
+
return this.#ffmpeg.then((v) => orNull(v, CRASH_LIMITS.ffmpegVersion));
|
|
16206
|
+
}
|
|
16207
|
+
};
|
|
16208
|
+
function prune(state, now) {
|
|
16209
|
+
for (const [key, value] of Object.entries(state.fingerprints)) {
|
|
16210
|
+
if (now - value.sentAt > 24 * 36e5 && value.pending === 0) delete state.fingerprints[key];
|
|
16211
|
+
}
|
|
16212
|
+
}
|
|
16213
|
+
function withCrashReport(crashes) {
|
|
16214
|
+
return (tool) => {
|
|
16215
|
+
if (crashes === null) return tool;
|
|
16216
|
+
const original = tool.execute.bind(tool);
|
|
16217
|
+
return {
|
|
16218
|
+
...tool,
|
|
16219
|
+
async execute(input, ...rest) {
|
|
16220
|
+
crashes.flushSoon();
|
|
16221
|
+
const host = hostFromContext(rest[0]);
|
|
16222
|
+
crashes.noteHost(host);
|
|
16223
|
+
crashes.noteSecrets(secretsOf(input));
|
|
16224
|
+
let result;
|
|
16225
|
+
try {
|
|
16226
|
+
result = await original(input, ...rest);
|
|
16227
|
+
} catch (trouble) {
|
|
16228
|
+
const crash = fromThrown(trouble, "tool", tool.name, input, host);
|
|
16229
|
+
crashes.submit(crash);
|
|
16230
|
+
return toolError(brokenWords(crash, crashes));
|
|
16231
|
+
}
|
|
16232
|
+
return caught(result, tool.name, input, host, crashes);
|
|
16233
|
+
}
|
|
16234
|
+
};
|
|
16235
|
+
};
|
|
16236
|
+
}
|
|
16237
|
+
function caught(result, name, input, host, crashes) {
|
|
16238
|
+
if (result.type === "error") {
|
|
16239
|
+
const parsed2 = pythonCrash(result.error);
|
|
16240
|
+
if (parsed2 === null) return result;
|
|
16241
|
+
const crash2 = { ...parsed2, where: "tool", tool: name, stage: null, secrets: secretsOf(input), host };
|
|
16242
|
+
crashes.submit(crash2);
|
|
16243
|
+
return toolError(brokenWords(crash2, crashes));
|
|
16244
|
+
}
|
|
16245
|
+
const job = result.structured;
|
|
16246
|
+
if (job === void 0 || job["contract"] !== JOB_CONTRACT || job["status"] !== "error") return result;
|
|
16247
|
+
const id = typeof job["id"] === "string" ? job["id"] : "";
|
|
16248
|
+
if (!/^[\w.-]{1,80}$/.test(id) || crashes.jobSeen(id)) return result;
|
|
16249
|
+
const parsed = pythonCrash(jobLogTail(crashes.home, id));
|
|
16250
|
+
if (parsed === null) return result;
|
|
16251
|
+
crashes.rememberJob(id);
|
|
16252
|
+
const stage = typeof job["now"] === "string" && job["now"] !== "" ? job["now"] : null;
|
|
16253
|
+
const crash = { ...parsed, where: "job", tool: name, stage, secrets: secretsOf(input), host };
|
|
16254
|
+
crashes.submit(crash);
|
|
16255
|
+
const notice = `
|
|
16256
|
+
|
|
16257
|
+
${brokenWords(crash, crashes)}`;
|
|
16258
|
+
return typeof result.content === "string" ? { ...result, content: result.content + notice } : { ...result, content: [...result.content, { type: "text", text: notice.trim() }] };
|
|
16259
|
+
}
|
|
16260
|
+
function brokenWords(crash, crashes) {
|
|
16261
|
+
const essence = head(scrub(head(crash.essence, 600), crashes.scrubContext(crash.secrets)), 300);
|
|
16262
|
+
return [
|
|
16263
|
+
"\u0421\u043B\u043E\u043C\u0430\u043B\u043E\u0441\u044C \u043D\u0430 \u043D\u0430\u0448\u0435\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u0435, \u043D\u0435 \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430.",
|
|
16264
|
+
crashes.canSend ? `\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0441\u043A\u0430\u0436\u0438, \u0447\u0442\u043E \u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0439 \u043E\u0442\u0447\u0451\u0442 \u0443\u0445\u043E\u0434\u0438\u0442 \u043D\u0430\u043C \u0441\u0430\u043C \u0438 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0443\u0436\u043D\u043E, \u0438 \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439 \u0435\u0449\u0451 \u0440\u0430\u0437. \u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0441\u044F \u2014 \u043F\u0443\u0441\u0442\u044C \u043D\u0430\u043F\u0438\u0448\u0435\u0442 \u043D\u0430\u043C \u0432 \u0431\u043E\u0442 ${KEY_SOURCE_BOT}.` : `\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439 \u0435\u0449\u0451 \u0440\u0430\u0437. \u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0441\u044F \u2014 \u043F\u0443\u0441\u0442\u044C \u043D\u0430\u043F\u0438\u0448\u0435\u0442 \u043D\u0430\u043C \u0432 \u0431\u043E\u0442 ${KEY_SOURCE_BOT}.`,
|
|
16265
|
+
`\u0421\u0443\u0442\u044C \u0434\u043B\u044F \u0442\u0435\u0431\u044F, \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u043D\u0435 \u0437\u0430\u0447\u0438\u0442\u044B\u0432\u0430\u0439: ${essence}`
|
|
16266
|
+
].join("\n");
|
|
16267
|
+
}
|
|
16268
|
+
function watchProcessCrashes(crashes, proc = process, exit = (code) => process.exit(code)) {
|
|
16269
|
+
const fall = (trouble) => {
|
|
16270
|
+
crashes.persist(fromThrown(trouble, "process", null, {}, null));
|
|
16271
|
+
try {
|
|
16272
|
+
process.stderr.write(`naparnik-mcp: \u0443\u043F\u0430\u043B \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u2014 ${trouble instanceof Error ? trouble.stack ?? trouble.message : String(trouble)}
|
|
16273
|
+
`);
|
|
16274
|
+
} catch {
|
|
16275
|
+
}
|
|
16276
|
+
exit(1);
|
|
16277
|
+
};
|
|
16278
|
+
proc.on("uncaughtException", fall);
|
|
16279
|
+
proc.on("unhandledRejection", fall);
|
|
16280
|
+
crashes.flushSoon();
|
|
16281
|
+
}
|
|
16282
|
+
function fromThrown(trouble, where, tool, input, host) {
|
|
16283
|
+
const error40 = trouble instanceof Error ? trouble : new Error(String(trouble));
|
|
16284
|
+
const errorType = error40.name || error40.constructor.name || "Error";
|
|
16285
|
+
const trace = error40.stack ?? `${errorType}: ${error40.message}`;
|
|
16286
|
+
const frames = jsFrames(trace);
|
|
16287
|
+
return {
|
|
16288
|
+
where,
|
|
16289
|
+
tool,
|
|
16290
|
+
stage: null,
|
|
16291
|
+
errorType,
|
|
16292
|
+
message: error40.message,
|
|
16293
|
+
trace,
|
|
16294
|
+
keep: "head",
|
|
16295
|
+
frames: frames.slice(0, 3).map((f) => `${f.file}:${f.func}`),
|
|
16296
|
+
python: null,
|
|
16297
|
+
secrets: secretsOf(input),
|
|
16298
|
+
host,
|
|
16299
|
+
essence: `${errorType}: ${error40.message}${frames[0] ? ` \u2014 ${frames[0].file}` : ""}`
|
|
16300
|
+
};
|
|
16301
|
+
}
|
|
16302
|
+
function jsFrames(stack) {
|
|
16303
|
+
const frames = [];
|
|
16304
|
+
for (const line of stack.split("\n")) {
|
|
16305
|
+
const m = /^\s*at (?:(.+?) \()?(.+?):\d+:\d+\)?\s*$/.exec(line);
|
|
16306
|
+
if (m === null) continue;
|
|
16307
|
+
const file2 = basename(m[2] ?? "").replace(/-[A-Za-z0-9]{6,}(\.[cm]?js)$/, "$1");
|
|
16308
|
+
frames.push({ file: file2, func: m[1] ?? "<anonymous>" });
|
|
16309
|
+
}
|
|
16310
|
+
return frames;
|
|
16311
|
+
}
|
|
16312
|
+
function pythonCrash(text2) {
|
|
16313
|
+
const start = text2.lastIndexOf(PYTHON_TRACEBACK);
|
|
16314
|
+
if (start < 0) return null;
|
|
16315
|
+
const block = text2.slice(start).replace(/\s+$/, "");
|
|
16316
|
+
const lines = block.split("\n");
|
|
16317
|
+
const frames = [];
|
|
16318
|
+
let lastFrame = -1;
|
|
16319
|
+
lines.forEach((line, at2) => {
|
|
16320
|
+
const m2 = /^\s*File "(.+)", line (\d+), in (.+)$/.exec(line);
|
|
16321
|
+
if (m2 === null) return;
|
|
16322
|
+
frames.push({ file: m2[1] ?? "", line: m2[2] ?? "", func: (m2[3] ?? "").trim() });
|
|
16323
|
+
lastFrame = at2;
|
|
16324
|
+
});
|
|
16325
|
+
if (frames.length === 0) return null;
|
|
16326
|
+
if (frames.some((f) => /[\\/]mine[\\/]steps[\\/]/.test(f.file))) return null;
|
|
16327
|
+
const at = lines.findIndex((line, n) => n > lastFrame && line !== "" && !/^\s/.test(line));
|
|
16328
|
+
if (at < 0) return null;
|
|
16329
|
+
const m = /^([A-Za-z_][\w.]*)(?::\s?(.*))?$/.exec(lines[at] ?? "");
|
|
16330
|
+
if (m === null) return null;
|
|
16331
|
+
const errorType = m[1] ?? "Error";
|
|
16332
|
+
if (/(?:^|\.)(?:KeyboardInterrupt|SystemExit|Explained|Refusal)$/.test(errorType)) return null;
|
|
16333
|
+
const message = [m[2] ?? "", ...lines.slice(at + 1)].join("\n").trim();
|
|
16334
|
+
const innermost = frames[frames.length - 1];
|
|
16335
|
+
const firstLine = message.split("\n")[0] ?? "";
|
|
16336
|
+
return {
|
|
16337
|
+
errorType,
|
|
16338
|
+
message,
|
|
16339
|
+
trace: block,
|
|
16340
|
+
keep: "tail",
|
|
16341
|
+
frames: frames.slice(-3).map((f) => `${basename(f.file.replace(/\\/g, "/"))}:${f.func}`),
|
|
16342
|
+
python: pythonVersionIn(frames.map((f) => f.file)),
|
|
16343
|
+
essence: `${errorType}${firstLine === "" ? "" : `: ${firstLine}`}` + (innermost ? ` \u2014 ${basename(innermost.file.replace(/\\/g, "/"))}:${innermost.line}` : "")
|
|
16344
|
+
};
|
|
16345
|
+
}
|
|
16346
|
+
function pythonVersionIn(files) {
|
|
16347
|
+
for (const file2 of files) {
|
|
16348
|
+
const m = /python(\d)\.?(\d{1,2})[\\/]/i.exec(file2);
|
|
16349
|
+
if (m !== null) return `${m[1]}.${m[2]}`;
|
|
16350
|
+
}
|
|
16351
|
+
return null;
|
|
16352
|
+
}
|
|
16353
|
+
function jobLogTail(home, id) {
|
|
16354
|
+
const file2 = join(home, "logs", `${id}.log`);
|
|
16355
|
+
let fd = null;
|
|
16356
|
+
try {
|
|
16357
|
+
fd = openSync(file2, "r");
|
|
16358
|
+
const size = fstatSync(fd).size;
|
|
16359
|
+
const length = Math.min(size, JOB_LOG_TAIL);
|
|
16360
|
+
const buffer = Buffer.alloc(length);
|
|
16361
|
+
readSync(fd, buffer, 0, length, size - length);
|
|
16362
|
+
return buffer.toString("utf8");
|
|
16363
|
+
} catch {
|
|
16364
|
+
return "";
|
|
16365
|
+
} finally {
|
|
16366
|
+
if (fd !== null) try {
|
|
16367
|
+
closeSync(fd);
|
|
16368
|
+
} catch {
|
|
16369
|
+
}
|
|
16370
|
+
}
|
|
16371
|
+
}
|
|
16372
|
+
function fingerprintOf2(errorType, frames) {
|
|
16373
|
+
return createHash("sha256").update([errorType, ...frames].join("|")).digest("hex").slice(0, 16);
|
|
16374
|
+
}
|
|
16375
|
+
function secretsOf(input, depth = 0, out = []) {
|
|
16376
|
+
if (out.length >= 50 || depth > 4) return out;
|
|
16377
|
+
if (typeof input === "string") out.push(input);
|
|
16378
|
+
else if (Array.isArray(input)) for (const one of input) secretsOf(one, depth + 1, out);
|
|
16379
|
+
else if (typeof input === "object" && input !== null) {
|
|
16380
|
+
for (const one of Object.values(input)) secretsOf(one, depth + 1, out);
|
|
16381
|
+
}
|
|
16382
|
+
return out;
|
|
16383
|
+
}
|
|
16384
|
+
function recentCalls(home) {
|
|
16385
|
+
try {
|
|
16386
|
+
const text2 = readFileSync(join(home, CALLS_FILE), "utf8").slice(-8192);
|
|
16387
|
+
const names = [];
|
|
16388
|
+
for (const line of text2.split("\n")) {
|
|
16389
|
+
try {
|
|
16390
|
+
const tool = JSON.parse(line).tool;
|
|
16391
|
+
if (typeof tool === "string" && CRASH_TOOL_NAME.test(tool)) names.push(tool);
|
|
16392
|
+
} catch {
|
|
16393
|
+
}
|
|
16394
|
+
}
|
|
16395
|
+
return names.slice(-CRASH_LIMITS.recentCalls);
|
|
16396
|
+
} catch {
|
|
16397
|
+
return [];
|
|
16398
|
+
}
|
|
16399
|
+
}
|
|
16400
|
+
function hostFromContext(context) {
|
|
16401
|
+
const host = context?.host;
|
|
16402
|
+
return host !== void 0 && typeof host.name === "string" && typeof host.version === "string" ? host : null;
|
|
16403
|
+
}
|
|
16404
|
+
function hostOf(host) {
|
|
16405
|
+
return host === null ? null : { name: head(host.name, CRASH_LIMITS.hostName), version: head(host.version, CRASH_LIMITS.hostVersion) };
|
|
16406
|
+
}
|
|
16407
|
+
function probeFfmpeg(home) {
|
|
16408
|
+
const own = join(home, "bin", platform() === "win32" ? "ffmpeg.exe" : "ffmpeg");
|
|
16409
|
+
const program = existsSync(own) ? own : "ffmpeg";
|
|
16410
|
+
return new Promise((done) => {
|
|
16411
|
+
execFile(program, ["-version"], { timeout: 3e3, encoding: "utf8" }, (trouble, stdout) => {
|
|
16412
|
+
if (trouble !== null) return done(null);
|
|
16413
|
+
const m = /^ffmpeg version (\S+)/.exec(stdout);
|
|
16414
|
+
done(m?.[1] ?? null);
|
|
16415
|
+
});
|
|
16416
|
+
});
|
|
16417
|
+
}
|
|
16418
|
+
function ownDir() {
|
|
16419
|
+
try {
|
|
16420
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
16421
|
+
} catch {
|
|
16422
|
+
return "";
|
|
16423
|
+
}
|
|
16424
|
+
}
|
|
16425
|
+
function safeUser() {
|
|
16426
|
+
try {
|
|
16427
|
+
return userInfo().username;
|
|
16428
|
+
} catch {
|
|
16429
|
+
return "";
|
|
16430
|
+
}
|
|
16431
|
+
}
|
|
16432
|
+
function head(text2, max) {
|
|
16433
|
+
return text2.length <= max ? text2 : text2.slice(0, max);
|
|
16434
|
+
}
|
|
16435
|
+
function tail(text2, max) {
|
|
16436
|
+
if (text2.length <= max) return text2;
|
|
16437
|
+
const cut = "\u2026(\u043D\u0430\u0447\u0430\u043B\u043E \u043E\u0431\u0440\u0435\u0437\u0430\u043D\u043E)\n";
|
|
16438
|
+
return cut + text2.slice(text2.length - (max - cut.length));
|
|
16439
|
+
}
|
|
16440
|
+
function orNull(value, max) {
|
|
16441
|
+
return value === null || value === "" ? null : head(value, max);
|
|
16442
|
+
}
|
|
16443
|
+
var WIDGET_MIME = "text/html;profile=mcp-app";
|
|
16444
|
+
function widgetStamp(html) {
|
|
16445
|
+
return createHash("sha256").update(html).digest("hex").slice(0, 8);
|
|
16446
|
+
}
|
|
16447
|
+
var WIDGET_PLATE_CSS = `
|
|
16448
|
+
:root { --plate: #ffffff; --plate-end: #f5f5f7; }
|
|
16449
|
+
:root:has(> body.dark) { --plate: #1d1d1f; --plate-end: #000000; }
|
|
16450
|
+
:root:has(> body.full) { min-height: 100%; }
|
|
16451
|
+
html {
|
|
16452
|
+
background: var(--plate-end) linear-gradient(var(--plate) calc(100% - 197px), var(--plate-end)) no-repeat;
|
|
16453
|
+
}
|
|
16454
|
+
`;
|
|
16455
|
+
var WIDGET_HEADING_CSS = `
|
|
16456
|
+
:root {
|
|
16457
|
+
--font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Icons", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
16458
|
+
}
|
|
16459
|
+
h2, .end__t { font-family: var(--font-display); }
|
|
16460
|
+
`;
|
|
16461
|
+
|
|
16462
|
+
// src/runbar.ts
|
|
16463
|
+
var RUNBAR_RESOURCE_URI = `ui://naparnik/runbar-${widgetStamp(runbarWidgetHtml())}`;
|
|
16464
|
+
var RUNBAR_MIME = WIDGET_MIME;
|
|
16465
|
+
function runbarResource() {
|
|
16466
|
+
return {
|
|
16467
|
+
resource: {
|
|
16468
|
+
uri: RUNBAR_RESOURCE_URI,
|
|
16469
|
+
name: "\u0425\u043E\u0434 \u0440\u0430\u0431\u043E\u0442\u044B",
|
|
16470
|
+
description: "\u041F\u043E\u043B\u043E\u0441\u0430 \u044D\u0442\u0430\u043F\u043E\u0432: \u0447\u0442\u043E \u0434\u0435\u043B\u0430\u0435\u0442\u0441\u044F \u0441\u0435\u0439\u0447\u0430\u0441 \u0438 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0443\u0436\u0435 \u0438\u0434\u0451\u0442",
|
|
16471
|
+
mimeType: RUNBAR_MIME
|
|
16472
|
+
},
|
|
16473
|
+
contents: [{
|
|
16474
|
+
uri: RUNBAR_RESOURCE_URI,
|
|
16475
|
+
mimeType: RUNBAR_MIME,
|
|
16476
|
+
text: runbarWidgetHtml(),
|
|
16477
|
+
_meta: { ui: { prefersBorder: true } }
|
|
16478
|
+
}]
|
|
16479
|
+
};
|
|
16480
|
+
}
|
|
16481
|
+
function runbarWidgetHtml() {
|
|
16482
|
+
return `<!DOCTYPE html>
|
|
16483
|
+
<html lang="ru">
|
|
16484
|
+
<head>
|
|
16485
|
+
<meta charset="utf-8">
|
|
16486
|
+
<style>
|
|
16487
|
+
/* \u2500\u2500\u2500 \u041C\u0438\u0440 \u043F\u043E\u043B\u043E\u0441\u044B \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
16488
|
+
\u0426\u0432\u0435\u0442\u0430 \u0442\u0435 \u0436\u0435, \u0447\u0442\u043E \u0443 \u0444\u043E\u0440\u043C\u044B \u0432\u044B\u0431\u043E\u0440\u0430 \u0438 \u043D\u0430 \u043B\u0435\u043D\u0434\u0438\u043D\u0433\u0435: \u0436\u0451\u043B\u0442\u044B\u0439 \u0432\u0435\u0434\u0451\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u2014
|
|
16489
|
+
\u0437\u0434\u0435\u0441\u044C \u044D\u0442\u043E \u0438\u0434\u0443\u0449\u0438\u0439 \u044D\u0442\u0430\u043F, \u0433\u043E\u043B\u0443\u0431\u043E\u0439 \u0432\u0435\u0434\u0451\u0442 \u0433\u043E\u043B\u043E\u0441 \u2014 \u0441\u0442\u0440\u043E\u043A\u0443 \u043E \u0442\u043E\u043C, \u0447\u0442\u043E \u043F\u0440\u043E\u0438\u0441\u0445\u043E\u0434\u0438\u0442.
|
|
16490
|
+
|
|
16491
|
+
\u26A0 \u0421\u0412\u0415\u0422 \u2014 \u041E\u0421\u041D\u041E\u0412\u0410, \u0422\u0401\u041C\u041D\u0410\u042F \u0422\u0415\u041C\u0410 \u0422\u041E\u041B\u042C\u041A\u041E \u0414\u041E\u041F\u0418\u0421\u042B\u0412\u0410\u0415\u0422. \u041F\u0440\u0430\u0432\u0438\u043B\u043E \u043F\u0440\u043E\u0435\u043A\u0442\u0430: \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435
|
|
16492
|
+
\u0443 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 \u043E\u0434\u043D\u043E, \u0438 \u043F\u0440\u0430\u0432\u043A\u0430 \u0441\u0432\u0435\u0442\u043B\u043E\u0439 \u0442\u0435\u043C\u044B \u043D\u0435 \u043C\u043E\u0436\u0435\u0442 \u043C\u043E\u043B\u0447\u0430 \u043F\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0442\u0451\u043C\u043D\u0443\u044E.
|
|
16493
|
+
|
|
16494
|
+
\u26A0 \u041E \xABcolor-scheme\xBB: \u0435\u0433\u043E \u0437\u0434\u0435\u0441\u044C \u041D\u0415\u0422, \u0438 \u044D\u0442\u043E \u043D\u0435 \u0437\u0430\u0431\u044B\u0442\u043E. \u0421\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u043C
|
|
16495
|
+
\xABlight dark\xBB \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043F\u0435\u0440\u0435\u0441\u0442\u0430\u0451\u0442 \u043A\u043E\u043C\u043F\u043E\u0437\u0438\u0442\u0438\u0442\u044C iframe \u0441 \u043F\u043E\u0432\u0435\u0440\u0445\u043D\u043E\u0441\u0442\u044C\u044E \u0445\u043E\u0441\u0442\u0430 \u0438
|
|
16496
|
+
\u0437\u0430\u043B\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043E \u0441\u043E\u0431\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u043C \u0445\u043E\u043B\u0441\u0442\u043E\u043C \u043F\u043E \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0435 \u0421\u0418\u0421\u0422\u0415\u041C\u042B: \u043F\u0440\u0438 \u0441\u0432\u0435\u0442\u043B\u043E\u043C \u041A\u043B\u043E\u0434\u0435
|
|
16497
|
+
\u043D\u0430 \u0442\u0451\u043C\u043D\u043E\u0439 macOS \u043F\u043E\u043B\u043E\u0441\u0430 \u043F\u043E\u043B\u0443\u0447\u0430\u043B\u0430 \u0431\u044B \u0447\u0451\u0440\u043D\u044B\u0439 \u0445\u043E\u043B\u0441\u0442 \u043F\u043E\u0434 \u0442\u0451\u043C\u043D\u044B\u043C\u0438 \u0447\u0435\u0440\u043D\u0438\u043B\u0430\u043C\u0438.
|
|
16498
|
+
\u041E\u0448\u0438\u0431\u043A\u0430 \u043C\u043E\u043B\u0447\u0430\u043B\u0438\u0432\u0430\u044F, \u0432 \u043A\u043E\u043D\u0441\u043E\u043B\u0438 \u043F\u0443\u0441\u0442\u043E. \u041F\u0440\u043E\u0432\u0435\u0440\u0435\u043D\u043E \u043D\u0430 \u0444\u043E\u0440\u043C\u0435 \u0432\u044B\u0431\u043E\u0440\u0430 2026-09-10. */
|
|
16499
|
+
/* \u041F\u043E\u0434\u043B\u043E\u0436\u043A\u0430 \u043E\u0431\u0449\u0430\u044F \u0441 \u0444\u043E\u0440\u043C\u043E\u0439 \u0432\u044B\u0431\u043E\u0440\u0430 \u0438 \u043B\u0435\u0436\u0438\u0442 \u0432 widget.ts. */
|
|
16500
|
+
${WIDGET_PLATE_CSS}
|
|
16501
|
+
${WIDGET_HEADING_CSS}
|
|
16502
|
+
:root {
|
|
16503
|
+
--ink: #1d1d1f;
|
|
16504
|
+
--ink-soft: #5E5547;
|
|
15607
16505
|
--card: #F3EDDF;
|
|
15608
16506
|
--card-lift: #FBF7EC;
|
|
15609
16507
|
--edge: rgba(20, 17, 12, 0.10);
|
|
@@ -16233,121 +17131,6 @@ function runbarWidgetHtml() {
|
|
|
16233
17131
|
</html>`;
|
|
16234
17132
|
}
|
|
16235
17133
|
|
|
16236
|
-
// src/progress.ts
|
|
16237
|
-
var realPace = {
|
|
16238
|
-
now: () => Date.now(),
|
|
16239
|
-
rest: (ms) => new Promise((done) => {
|
|
16240
|
-
setTimeout(done, ms);
|
|
16241
|
-
})
|
|
16242
|
-
};
|
|
16243
|
-
var WAIT_LIMIT_SECONDS = 55;
|
|
16244
|
-
var POLL_EVERY_MS = 2e3;
|
|
16245
|
-
var JOB_STILL_COMPUTING = "\u0415\u0449\u0451 \u0441\u0447\u0438\u0442\u0430\u0435\u0442";
|
|
16246
|
-
var JOB_IN_QUEUE = "\u0416\u0434\u0451\u0442 \u043E\u0447\u0435\u0440\u0435\u0434\u0438";
|
|
16247
|
-
function stillWorking(text) {
|
|
16248
|
-
return text.includes(JOB_STILL_COMPUTING) || text.includes(JOB_IN_QUEUE);
|
|
16249
|
-
}
|
|
16250
|
-
function waitSeconds(asked) {
|
|
16251
|
-
if (asked === void 0 || !Number.isFinite(asked) || asked <= 0) return 0;
|
|
16252
|
-
return Math.min(Math.round(asked), WAIT_LIMIT_SECONDS);
|
|
16253
|
-
}
|
|
16254
|
-
function freshLines(text, told) {
|
|
16255
|
-
const news = [];
|
|
16256
|
-
for (const row of text.split("\n").slice(1)) {
|
|
16257
|
-
const line = row.trim();
|
|
16258
|
-
if (line.length === 0) continue;
|
|
16259
|
-
if (line.startsWith(JOB_STILL_COMPUTING)) continue;
|
|
16260
|
-
if (told.has(line)) continue;
|
|
16261
|
-
told.add(line);
|
|
16262
|
-
news.push(line);
|
|
16263
|
-
}
|
|
16264
|
-
return news;
|
|
16265
|
-
}
|
|
16266
|
-
async function followJob(opts) {
|
|
16267
|
-
const pace = opts.pace ?? realPace;
|
|
16268
|
-
const until = pace.now() + opts.seconds * 1e3;
|
|
16269
|
-
const told = /* @__PURE__ */ new Set();
|
|
16270
|
-
let state = await opts.ask();
|
|
16271
|
-
retell(state, told, opts.tell);
|
|
16272
|
-
while (state.ok && stillWorking(state.text) && pace.now() < until) {
|
|
16273
|
-
await pace.rest(POLL_EVERY_MS);
|
|
16274
|
-
try {
|
|
16275
|
-
state = await opts.ask();
|
|
16276
|
-
} catch {
|
|
16277
|
-
continue;
|
|
16278
|
-
}
|
|
16279
|
-
retell(state, told, opts.tell);
|
|
16280
|
-
}
|
|
16281
|
-
return state;
|
|
16282
|
-
}
|
|
16283
|
-
function retell(state, told, tell) {
|
|
16284
|
-
if (tell === void 0) return;
|
|
16285
|
-
for (const line of freshLines(state.text, told)) tell(line);
|
|
16286
|
-
}
|
|
16287
|
-
var STAGE_WORDS = {
|
|
16288
|
-
silence: "\u0443\u0431\u0435\u0440\u0443 \u043F\u0430\u0443\u0437\u044B",
|
|
16289
|
-
voice: "\u0432\u044B\u0440\u043E\u0432\u043D\u044F\u044E \u0433\u043E\u043B\u043E\u0441",
|
|
16290
|
-
speech: "\u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u044E \u0440\u0435\u0447\u044C",
|
|
16291
|
-
phrases: "\u0440\u0430\u0437\u043B\u043E\u0436\u0443 \u0440\u0435\u0447\u044C \u043D\u0430 \u0444\u0440\u0430\u0437\u044B",
|
|
16292
|
-
plan: "\u043F\u0440\u0438\u0434\u0443\u043C\u0430\u044E, \u0447\u0442\u043E \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0438 \u043A\u043E\u0433\u0434\u0430",
|
|
16293
|
-
world: "\u043D\u0430\u0440\u0438\u0441\u0443\u044E \u0444\u043E\u043D \u0437\u0430 \u0433\u0435\u0440\u043E\u0435\u043C",
|
|
16294
|
-
cutout: "\u043E\u0442\u0434\u0435\u043B\u044E \u0433\u0435\u0440\u043E\u044F \u043E\u0442 \u0444\u043E\u043D\u0430",
|
|
16295
|
-
"hero-on-world": "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u0433\u0435\u0440\u043E\u044F \u043D\u0430 \u0444\u043E\u043D",
|
|
16296
|
-
shots: "\u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043B\u044E \u043A\u0440\u0443\u043F\u043D\u043E\u0441\u0442\u0438 \u043F\u043E \u043F\u043B\u0430\u043D\u0443",
|
|
16297
|
-
screen: "\u0432\u0441\u0442\u0430\u0432\u043B\u044E \u0437\u0430\u043F\u0438\u0441\u044C \u044D\u043A\u0440\u0430\u043D\u0430",
|
|
16298
|
-
inserts: "\u043D\u0430\u0440\u0438\u0441\u0443\u044E \u0433\u0440\u0430\u0444\u0438\u043A\u0443 \u043F\u043E \u043F\u043B\u0430\u043D\u0443",
|
|
16299
|
-
subtitles: "\u043D\u0430\u0440\u0438\u0441\u0443\u044E \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B",
|
|
16300
|
-
layers: "\u043F\u043E\u043B\u043E\u0436\u0443 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u043F\u043E\u0432\u0435\u0440\u0445",
|
|
16301
|
-
accents: "\u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043B\u044E \u0437\u0432\u0443\u043A\u043E\u0432\u044B\u0435 \u0430\u043A\u0446\u0435\u043D\u0442\u044B",
|
|
16302
|
-
mix: "\u0441\u0432\u0435\u0434\u0443 \u0437\u0432\u0443\u043A",
|
|
16303
|
-
intro: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0443 \u0432 \u043D\u0430\u0447\u0430\u043B\u043E"
|
|
16304
|
-
};
|
|
16305
|
-
var NEAR_STEPS = 3;
|
|
16306
|
-
function montageLadder(stages) {
|
|
16307
|
-
const words = stages.map((stage) => STAGE_WORDS[stage]).filter((word) => word !== void 0);
|
|
16308
|
-
if (words.length === 0) return [];
|
|
16309
|
-
const near = words.slice(0, NEAR_STEPS);
|
|
16310
|
-
const far = words.slice(NEAR_STEPS);
|
|
16311
|
-
const lines = [`\u0421\u043D\u0430\u0447\u0430\u043B\u0430 ${near.join(", \u043F\u043E\u0442\u043E\u043C ")}.`];
|
|
16312
|
-
if (far.length > 0) {
|
|
16313
|
-
lines.push(
|
|
16314
|
-
`\u0414\u0430\u043B\u044C\u0448\u0435: ${far.join(", ")}. \u0428\u0430\u0433\u043E\u0432 \u0432\u0441\u0435\u0433\u043E \u0434\u043E ${stages.length} \u2014 \u0447\u0442\u043E \u043D\u0435 \u043F\u043E\u043D\u0430\u0434\u043E\u0431\u0438\u0442\u0441\u044F, \u043F\u0440\u043E\u043F\u0443\u0449\u0443.`
|
|
16315
|
-
);
|
|
16316
|
-
}
|
|
16317
|
-
return lines;
|
|
16318
|
-
}
|
|
16319
|
-
var PAUSES_LADDER = [
|
|
16320
|
-
"\u0423\u0431\u0435\u0440\u0443 \u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u0438 \u0437\u0430\u043F\u0438\u043D\u043A\u0438 \u2014 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0442\u0440\u043E\u0433\u0430\u044E.",
|
|
16321
|
-
"\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044B, \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u043F\u043E\u0432\u0435\u0440\u0445 \u0438 \u0437\u0432\u0443\u043A \u2014 \u044D\u0442\u043E \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u0430\u044F \u0440\u0430\u0431\u043E\u0442\u0430, \u0435\u0451 \u0437\u0434\u0435\u0441\u044C \u043D\u0435\u0442."
|
|
16322
|
-
];
|
|
16323
|
-
var PAYLOAD_LADDER = [
|
|
16324
|
-
"\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043F\u043E\u043B\u043E\u0436\u0443 \u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043E\u0434\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439 \u2014 \u0432 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F.",
|
|
16325
|
-
"\u041F\u043E\u0442\u043E\u043C ffmpeg, python \u0438 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430. \u0422\u044F\u0436\u0451\u043B\u043E\u0435 \u2014 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438, \u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F, \u0447\u0438\u0441\u0442\u043A\u0430 \u0433\u043E\u043B\u043E\u0441\u0430 \u2014 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435."
|
|
16326
|
-
];
|
|
16327
|
-
var INSTALL_WORDS = {
|
|
16328
|
-
ffmpeg: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E ffmpeg \u2014 \u0438\u043C \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0432\u0438\u0434\u0435\u043E",
|
|
16329
|
-
python: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E python",
|
|
16330
|
-
env: "\u0441\u043E\u0431\u0435\u0440\u0443 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
16331
|
-
model: "\u0441\u043A\u0430\u0447\u0430\u044E \u043C\u043E\u0434\u0435\u043B\u044C \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u044F \u0440\u0435\u0447\u0438 \u2014 \u043E\u043D\u0430 \u0438\u0437 \u0432\u0441\u0435\u0433\u043E \u0441\u0430\u043C\u0430\u044F \u0442\u044F\u0436\u0451\u043B\u0430\u044F",
|
|
16332
|
-
cutout: "\u0441\u043A\u0430\u0447\u0430\u044E \u0442\u043E, \u0447\u0435\u043C \u043E\u0442\u0434\u0435\u043B\u044F\u044E \u0433\u0435\u0440\u043E\u044F \u043E\u0442 \u0444\u043E\u043D\u0430",
|
|
16333
|
-
voice: "\u0441\u043A\u0430\u0447\u0430\u044E \u0442\u043E, \u0447\u0435\u043C \u0447\u0438\u0449\u0443 \u0433\u043E\u043B\u043E\u0441",
|
|
16334
|
-
browser: "\u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u0440\u0438\u0441\u0443\u044E \u0433\u0440\u0430\u0444\u0438\u043A\u0443"
|
|
16335
|
-
};
|
|
16336
|
-
function installLadder(step) {
|
|
16337
|
-
if (step === "all") {
|
|
16338
|
-
return [
|
|
16339
|
-
"\u041F\u0440\u043E\u0432\u0435\u0440\u044E, \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0438 \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u043F\u043E \u043E\u0447\u0435\u0440\u0435\u0434\u0438.",
|
|
16340
|
-
"\u0422\u044F\u0436\u0451\u043B\u043E\u0435 \u0441\u044E\u0434\u0430 \u043D\u0435 \u0432\u0445\u043E\u0434\u0438\u0442: \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438 \u0438 \u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F \u0441\u0442\u0430\u0432\u044F\u0442\u0441\u044F \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \xAB\u0434\u0430\xBB \u043E\u0442 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430."
|
|
16341
|
-
];
|
|
16342
|
-
}
|
|
16343
|
-
const word = INSTALL_WORDS[step];
|
|
16344
|
-
if (word === void 0) return [];
|
|
16345
|
-
return [
|
|
16346
|
-
`\u0421\u0435\u0439\u0447\u0430\u0441 ${word}.`,
|
|
16347
|
-
"\u0418\u0434\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0430\u043C\u0438. \u041E\u0431\u043E\u0440\u0432\u0451\u0442\u0441\u044F \u2014 \u043F\u043E\u0432\u0442\u043E\u0440\u0438 \u0442\u043E\u0442 \u0436\u0435 \u0448\u0430\u0433: \u0443\u0436\u0435 \u0441\u043A\u0430\u0447\u0430\u043D\u043D\u043E\u0435 \u043D\u0435 \u043F\u0440\u043E\u043F\u0430\u0434\u0451\u0442."
|
|
16348
|
-
];
|
|
16349
|
-
}
|
|
16350
|
-
|
|
16351
17134
|
// src/tool-kit.ts
|
|
16352
17135
|
function manifestUrl(engine, baseUrl) {
|
|
16353
17136
|
return engine.variable("NAPARNIK_UPDATE_MANIFEST") ?? manifestUrlFor(baseUrl);
|
|
@@ -16363,31 +17146,6 @@ function aboutModels(passport) {
|
|
|
16363
17146
|
function fromList(list, description) {
|
|
16364
17147
|
return list !== void 0 && list.length > 0 ? external_exports.enum([...list]).describe(description) : external_exports.string().describe(description);
|
|
16365
17148
|
}
|
|
16366
|
-
function capabilitiesToSchema(passport, taken = /* @__PURE__ */ new Set()) {
|
|
16367
|
-
const skills = passport?.["capabilities"];
|
|
16368
|
-
if (skills === void 0) return {};
|
|
16369
|
-
const schema = {};
|
|
16370
|
-
for (const [name, o] of Object.entries(skills)) {
|
|
16371
|
-
if (taken.has(name)) continue;
|
|
16372
|
-
schema[name] = o["kind"] === "yes-no" ? external_exports.boolean().describe(o["about"]).optional() : external_exports.string().describe(o["about"]).optional();
|
|
16373
|
-
}
|
|
16374
|
-
return schema;
|
|
16375
|
-
}
|
|
16376
|
-
function readCapabilities(args, passport) {
|
|
16377
|
-
const skills = passport?.["capabilities"];
|
|
16378
|
-
if (skills === void 0) return [];
|
|
16379
|
-
const line = [];
|
|
16380
|
-
for (const [name, o] of Object.entries(skills)) {
|
|
16381
|
-
const key = `--${name.split("_").join("-")}`;
|
|
16382
|
-
if (o["kind"] === "yes-no") {
|
|
16383
|
-
if (args[name] === true) line.push(key);
|
|
16384
|
-
continue;
|
|
16385
|
-
}
|
|
16386
|
-
const value = args[name];
|
|
16387
|
-
if (typeof value === "string") line.push(key, o["kind"] === "file" ? path(value) : value);
|
|
16388
|
-
}
|
|
16389
|
-
return line;
|
|
16390
|
-
}
|
|
16391
17149
|
function asToolResult(outcome) {
|
|
16392
17150
|
return outcome.ok ? toolSuccess(outcome.text) : toolError(outcome.text);
|
|
16393
17151
|
}
|
|
@@ -16409,7 +17167,6 @@ var KNOB_KIND = {
|
|
|
16409
17167
|
"yes-no": "\u0434\u0430/\u043D\u0435\u0442"
|
|
16410
17168
|
};
|
|
16411
17169
|
var FROM_MINE = "mine";
|
|
16412
|
-
var FROM_VENDOR = "vendor";
|
|
16413
17170
|
function catalogInWords(data) {
|
|
16414
17171
|
const lines = [];
|
|
16415
17172
|
const version2 = data.engine?.version;
|
|
@@ -16468,12 +17225,10 @@ function catalogInWords(data) {
|
|
|
16468
17225
|
const said = knobs.map((k) => `${k.name} (${k.kind !== void 0 ? KNOB_KIND[k.kind] ?? k.kind : "\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435"})`).join(", ");
|
|
16469
17226
|
lines.push(`\u0420\u0443\u0447\u043A\u0438 \u043C\u043E\u043D\u0442\u0430\u0436\u0430, \u0438\u0445 \u043F\u0435\u0440\u0435\u0434\u0430\u044E\u0442 \u0432 render: ${said}.`);
|
|
16470
17227
|
}
|
|
16471
|
-
const
|
|
16472
|
-
if (
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
`\u0421\u043A\u0438\u043B\u043B\u044B \u043D\u0430 \u0434\u0438\u0441\u043A\u0435, \u0447\u0438\u0442\u0430\u0442\u044C plan \u0441 read, \u0440\u043E\u043B\u0438\u043A \u0434\u043B\u044F \u044D\u0442\u043E\u0433\u043E \u043D\u0435 \u043D\u0443\u0436\u0435\u043D: ${said}. \u0413\u043E\u0434\u044F\u0442\u0441\u044F \u0438 \u043D\u0435 \u0434\u043B\u044F \u0440\u043E\u043B\u0438\u043A\u0430: \u043F\u0440\u0435\u0437\u0435\u043D\u0442\u0430\u0446\u0438\u044F, \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0430, \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430.`
|
|
16476
|
-
);
|
|
17228
|
+
const index = data.handbook?.index;
|
|
17229
|
+
if (index !== void 0 && index.trim() !== "") {
|
|
17230
|
+
lines.push(`\u0421\u041F\u0420\u0410\u0412\u041E\u0427\u041D\u0418\u041A \u041C\u041E\u041D\u0422\u0410\u0416\u0401\u0420\u0410 \u2014 \u043E\u0433\u043B\u0430\u0432\u043B\u0435\u043D\u0438\u0435, \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u0447\u0438\u0442\u0430\u0439 plan \u0441 read:
|
|
17231
|
+
${index.trim()}`);
|
|
16477
17232
|
}
|
|
16478
17233
|
const style = data.style;
|
|
16479
17234
|
if (style?.name !== void 0) {
|
|
@@ -16481,6 +17236,11 @@ function catalogInWords(data) {
|
|
|
16481
17236
|
style.own === true ? `\u0421\u0442\u0438\u043B\u044C: \u0441\u0432\u043E\u0439 \u043F\u0430\u043A \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \xAB${style.name}\xBB \u2014 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0435 \u0437\u0430\u043F\u043E\u043C\u0438\u043D\u0430\u0435\u0442\u0441\u044F \u0432 \u043D\u0435\u0433\u043E.` : `\u0421\u0442\u0438\u043B\u044C: \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 \xAB${style.name}\xBB, \u0441\u0432\u043E\u0435\u0433\u043E \u043F\u0430\u043A\u0430 \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0435\u0449\u0451 \u043D\u0435\u0442.`
|
|
16482
17237
|
);
|
|
16483
17238
|
}
|
|
17239
|
+
const mine = data.mine?.summary ?? [];
|
|
17240
|
+
if (mine.length > 0) {
|
|
17241
|
+
lines.push(`\u0421\u0432\u043E\u0451 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 (\u0437\u0430\u043F\u043E\u043C\u043D\u0435\u043D\u043E, \u0443\u0436\u0435 \u0432 \u043A\u0430\u0436\u0434\u043E\u043C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0435; \xAB\u0437\u0430\u0431\u0443\u0434\u044C\xBB \u2014 plan_edit forget):
|
|
17242
|
+
${mine.map((line) => `\u2014 ${line}`).join("\n")}`);
|
|
17243
|
+
}
|
|
16484
17244
|
for (const said of data.warnings ?? []) lines.push(said);
|
|
16485
17245
|
return lines.join("\n");
|
|
16486
17246
|
}
|
|
@@ -16497,73 +17257,19 @@ async function askCatalog(engine, pack, video) {
|
|
|
16497
17257
|
if (!answer.ok) return `\u0421\u043F\u0438\u0441\u043E\u043A \u0442\u043E\u0433\u043E, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436, \u043D\u0435 \u043F\u0440\u0438\u0448\u0451\u043B: ${answer.text}`;
|
|
16498
17258
|
let data;
|
|
16499
17259
|
try {
|
|
16500
|
-
data = JSON.parse(answer.text);
|
|
16501
|
-
} catch {
|
|
16502
|
-
return `\u0421\u043F\u0438\u0441\u043E\u043A \u0442\u043E\u0433\u043E, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436, \u043D\u0435 \u043F\u0440\u0438\u0448\u0451\u043B: ${NOT_JSON}`;
|
|
16503
|
-
}
|
|
16504
|
-
if (data.contract !== CAPABILITIES_CONTRACT) {
|
|
16505
|
-
return `\u0414\u0432\u0438\u0436\u043E\u043A \u0433\u043E\u0432\u043E\u0440\u0438\u0442 \u043D\u0430 \u0434\u043E\u0433\u043E\u0432\u043E\u0440\u0435 \xAB${String(data.contract)}\xBB, \u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 \u043F\u043E\u043D\u0438\u043C\u0430\u0435\u0442 \xAB${CAPABILITIES_CONTRACT}\xBB, \u0438 \u0441\u043F\u0438\u0441\u043E\u043A \u0442\u043E\u0433\u043E, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436, \u043D\u0435 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D. \u041E\u0431\u043D\u043E\u0432\u0438 \u0442\u043E, \u0447\u0442\u043E \u0441\u0442\u0430\u0440\u0435\u0435: setup \u0441 what=engine \u0434\u043B\u044F \u0434\u0432\u0438\u0436\u043A\u0430, what=shell \u0434\u043B\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.`;
|
|
16506
|
-
}
|
|
16507
|
-
return catalogInWords(data);
|
|
16508
|
-
}
|
|
16509
|
-
async function startMontage(engine, opts) {
|
|
16510
|
-
const trouble = await engine.pythonTrouble();
|
|
16511
|
-
if (trouble !== null) return toolError(trouble);
|
|
16512
|
-
const python = engine.packPython();
|
|
16513
|
-
if (python === null) {
|
|
16514
|
-
return toolError(
|
|
16515
|
-
"\u041E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E \u2014 \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C.\n\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 setup, \u043E\u043D \u0441\u043A\u0430\u0436\u0435\u0442, \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0430 \u0441 what \u043E\u043D \u044D\u0442\u043E \u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442."
|
|
16516
|
-
);
|
|
16517
|
-
}
|
|
16518
|
-
const passport = await engine.passport();
|
|
16519
|
-
if (passport === null) {
|
|
16520
|
-
return toolError(
|
|
16521
|
-
// ⚠ ВТОРАЯ ПРИЧИНА НАЗВАНА С 2026-09-09, И ОНА ТЕПЕРЬ ЧАСТАЯ. Пак
|
|
16522
|
-
// переименован (`first-montage` → `montage`), а начинка живёт версионными
|
|
16523
|
-
// папками: у того, чья начинка старее оболочки, пака по новому имени
|
|
16524
|
-
// просто нет. `check_setup` про это не скажет ничего внятного — лечит
|
|
16525
|
-
// обновление начинки, и назвать его надо здесь.
|
|
16526
|
-
"\u041D\u0435 \u0441\u043C\u043E\u0433 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u043F\u0430\u0441\u043F\u043E\u0440\u0442 \u043F\u0430\u043A\u0430 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 (pack.json).\n\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 setup \u2014 \u043E\u043D \u0441\u043A\u0430\u0436\u0435\u0442, \u0447\u0442\u043E \u0441 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u043E\u0439 \u043D\u0435 \u0442\u0430\u043A. \u0415\u0441\u043B\u0438 \u043D\u0430\u0447\u0438\u043D\u043A\u0430 \u0441\u0442\u0430\u0432\u0438\u043B\u0430\u0441\u044C \u0434\u0430\u0432\u043D\u043E, \u0434\u0435\u043B\u043E \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u0432 \u043D\u0435\u0439: \u043F\u0430\u043A \u043F\u0435\u0440\u0435\u0435\u0445\u0430\u043B, \u0438 \u0441\u0442\u0430\u0440\u0430\u044F \u043D\u0430\u0447\u0438\u043D\u043A\u0430 \u0435\u0433\u043E \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 \u2014 \u0442\u043E\u0433\u0434\u0430 \u043F\u043E\u043C\u043E\u0433\u0430\u0435\u0442 setup \u0441 what=engine."
|
|
16527
|
-
);
|
|
16528
|
-
}
|
|
16529
|
-
if (opts.tell !== void 0) {
|
|
16530
|
-
for (const line of opts.ladder ?? montageLadder(passport["stages"])) opts.tell(line);
|
|
16531
|
-
opts.tell(opts.hint);
|
|
16532
|
-
}
|
|
16533
|
-
const launch = await engine.background({
|
|
16534
|
-
place: opts.place,
|
|
16535
|
-
executable: python,
|
|
16536
|
-
key: opts.key,
|
|
16537
|
-
startJob: [
|
|
16538
|
-
"job-create",
|
|
16539
|
-
"--video",
|
|
16540
|
-
opts.video,
|
|
16541
|
-
"--what",
|
|
16542
|
-
opts.what,
|
|
16543
|
-
"--command",
|
|
16544
|
-
JSON.stringify(opts.command),
|
|
16545
|
-
...opts.style !== void 0 ? ["--style", opts.style] : []
|
|
16546
|
-
],
|
|
16547
|
-
args: (id) => [passport["entry"], opts.video, "--job", id, ...opts.args],
|
|
16548
|
-
advice: "\u043F\u043E\u0437\u043E\u0432\u0438 setup \u2014 \u0441\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043D\u0435\u043F\u043E\u043B\u043D\u043E\u0435"
|
|
16549
|
-
});
|
|
16550
|
-
if ("refusal" in launch) return toolError(launch.refusal);
|
|
16551
|
-
return toolSuccess(
|
|
16552
|
-
`\u0417\u0430\u0434\u0430\u0447\u0430 ${launch.id}: ${opts.what}
|
|
16553
|
-
\u0412\u0441\u0451 \u0434\u0435\u043B\u0430\u0435\u0442\u0441\u044F \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F. ${opts.hint}
|
|
16554
|
-
\u0420\u0430\u0431\u043E\u0442\u0430 \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B: \u043D\u043E\u043C\u0435\u0440 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\u043F\u043E\u043C\u043D\u0438 \u0438 \u043F\u043E\u0437\u043E\u0432\u0438 wait \u0441 job "${launch.id}" \u2014 \u043E\u043D \u043F\u043E\u0434\u043E\u0436\u0434\u0451\u0442 \u0438 \u0440\u0430\u0441\u0441\u043A\u0430\u0436\u0435\u0442 \u0445\u043E\u0434 \u043F\u043E \u0448\u0430\u0433\u0430\u043C, \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439 \u0435\u0433\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0441\u0440\u0430\u0437\u0443.`,
|
|
16555
|
-
startedJob({
|
|
16556
|
-
id: launch.id,
|
|
16557
|
-
what: opts.what,
|
|
16558
|
-
ahead: (opts.ladder ?? montageLadder(passport["stages"])).join(" "),
|
|
16559
|
-
message: opts.hint
|
|
16560
|
-
})
|
|
16561
|
-
);
|
|
17260
|
+
data = JSON.parse(answer.text);
|
|
17261
|
+
} catch {
|
|
17262
|
+
return `\u0421\u043F\u0438\u0441\u043E\u043A \u0442\u043E\u0433\u043E, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436, \u043D\u0435 \u043F\u0440\u0438\u0448\u0451\u043B: ${NOT_JSON}`;
|
|
17263
|
+
}
|
|
17264
|
+
if (data.contract !== CAPABILITIES_CONTRACT) {
|
|
17265
|
+
return `\u0414\u0432\u0438\u0436\u043E\u043A \u0433\u043E\u0432\u043E\u0440\u0438\u0442 \u043D\u0430 \u0434\u043E\u0433\u043E\u0432\u043E\u0440\u0435 \xAB${String(data.contract)}\xBB, \u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 \u043F\u043E\u043D\u0438\u043C\u0430\u0435\u0442 \xAB${CAPABILITIES_CONTRACT}\xBB, \u0438 \u0441\u043F\u0438\u0441\u043E\u043A \u0442\u043E\u0433\u043E, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436, \u043D\u0435 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D. \u041E\u0431\u043D\u043E\u0432\u0438 \u0442\u043E, \u0447\u0442\u043E \u0441\u0442\u0430\u0440\u0435\u0435: setup \u0441 what=engine \u0434\u043B\u044F \u0434\u0432\u0438\u0436\u043A\u0430, what=shell \u0434\u043B\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.`;
|
|
17266
|
+
}
|
|
17267
|
+
return catalogInWords(data);
|
|
16562
17268
|
}
|
|
16563
|
-
function fromWords(
|
|
17269
|
+
function fromWords(text2, contract) {
|
|
16564
17270
|
let data;
|
|
16565
17271
|
try {
|
|
16566
|
-
data = JSON.parse(
|
|
17272
|
+
data = JSON.parse(text2);
|
|
16567
17273
|
} catch {
|
|
16568
17274
|
return { refusal: NOT_JSON };
|
|
16569
17275
|
}
|
|
@@ -16573,13 +17279,54 @@ function fromWords(text, contract) {
|
|
|
16573
17279
|
if (typeof data.words !== "string" || data.words === "") return { refusal: NOT_JSON };
|
|
16574
17280
|
return { words: data.words, data };
|
|
16575
17281
|
}
|
|
16576
|
-
function folderAnswer(
|
|
16577
|
-
const read = fromWords(
|
|
17282
|
+
function folderAnswer(text2) {
|
|
17283
|
+
const read = fromWords(text2);
|
|
16578
17284
|
return "refusal" in read ? toolError(read.refusal) : toolSuccess(read.words, read.data);
|
|
16579
17285
|
}
|
|
17286
|
+
var DRAFT_CONTRACT = "naparnik-draft/1";
|
|
17287
|
+
var VIEW_CONTRACT = "naparnik-view/1";
|
|
17288
|
+
var EDIT_CONTRACT = "naparnik-edit/1";
|
|
17289
|
+
function answerOrRefusal(text2, contract) {
|
|
17290
|
+
const read = fromWords(text2, contract);
|
|
17291
|
+
if ("refusal" in read) {
|
|
17292
|
+
const plain = text2.trim();
|
|
17293
|
+
return { refusal: plain.startsWith("{") || plain === "" ? read.refusal : plain };
|
|
17294
|
+
}
|
|
17295
|
+
return read.data["ok"] === false ? { refusal: read.words } : read;
|
|
17296
|
+
}
|
|
17297
|
+
async function draftDocument(engine, place, asked, key) {
|
|
17298
|
+
const answer = await engine.command([
|
|
17299
|
+
"document-draft",
|
|
17300
|
+
"--video",
|
|
17301
|
+
asked.video,
|
|
17302
|
+
"--pack",
|
|
17303
|
+
place.pack,
|
|
17304
|
+
...asked.style !== void 0 ? ["--style", path(asked.style)] : [],
|
|
17305
|
+
...(asked.also ?? []).flatMap((one) => ["--also", path(one)]),
|
|
17306
|
+
...asked.ask !== void 0 ? ["--ask", JSON.stringify(asked.ask)] : [],
|
|
17307
|
+
"--json"
|
|
17308
|
+
], key !== void 0 ? { key } : {});
|
|
17309
|
+
return answer.ok ? answerOrRefusal(answer.text, DRAFT_CONTRACT) : { refusal: answer.text };
|
|
17310
|
+
}
|
|
17311
|
+
async function editOperations(engine, place, asked, key) {
|
|
17312
|
+
const answer = await engine.command([
|
|
17313
|
+
"document-edit",
|
|
17314
|
+
"--project",
|
|
17315
|
+
path(asked.reel),
|
|
17316
|
+
"--ops",
|
|
17317
|
+
JSON.stringify(asked.ops),
|
|
17318
|
+
...asked.stamps !== void 0 ? ["--stamps", JSON.stringify(asked.stamps)] : [],
|
|
17319
|
+
"--by",
|
|
17320
|
+
asked.by ?? "model",
|
|
17321
|
+
"--pack",
|
|
17322
|
+
place.pack,
|
|
17323
|
+
"--json"
|
|
17324
|
+
], key !== void 0 ? { key } : {});
|
|
17325
|
+
return answer.ok ? answerOrRefusal(answer.text, EDIT_CONTRACT) : { refusal: answer.text };
|
|
17326
|
+
}
|
|
16580
17327
|
function nameOrRefusal(candidate) {
|
|
16581
|
-
const
|
|
16582
|
-
if (!
|
|
17328
|
+
const looksLikePath2 = candidate.includes("/") || candidate.includes("\\") || candidate.startsWith("~") || candidate.startsWith(".") || candidate.length > 1 && candidate[1] === ":";
|
|
17329
|
+
if (!looksLikePath2) return { name: candidate };
|
|
16583
17330
|
return {
|
|
16584
17331
|
refusal: `\u0417\u0434\u0435\u0441\u044C \u0436\u0434\u0443\u0442 \u0418\u041C\u042F \u0448\u0430\u0433\u0430, \u0430 \u043F\u0440\u0438\u0448\u0451\u043B \u043F\u0443\u0442\u044C: ${candidate}
|
|
16585
17332
|
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043D\u0430\u0437\u043E\u0432\u0438 \u0448\u0430\u0433 \u043E\u0434\u043D\u0438\u043C \u0441\u043B\u043E\u0432\u043E\u043C \u2014 \u0442\u0430\u043A, \u043A\u0430\u043A \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u0435\u0433\u043E \u043F\u0430\u043F\u043A\u0430. \u0421\u0432\u043E\u0439 \u0448\u0430\u0433 \u043B\u0435\u0436\u0438\u0442 \u0432 \`mine/steps/<\u0438\u043C\u044F>\` \u0432 \u0434\u043E\u043C\u0435 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430, \u043D\u0430\u0448\u0438 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u044F\u0435\u0442 setup, \u0438\u043C\u044F \u0443 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0441\u0442\u043E\u0438\u0442 \u0432 \u0441\u043A\u043E\u0431\u043A\u0430\u0445.`
|
|
@@ -16706,7 +17453,7 @@ ${EXTRAS_LATER}`), later]);
|
|
|
16706
17453
|
if ("refusal" in launch) return toolError(launch.refusal);
|
|
16707
17454
|
return toolSuccess(
|
|
16708
17455
|
`\u0417\u0430\u0434\u0430\u0447\u0430 ${launch.id}: \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430, \u0448\u0430\u0433 \xAB${step}\xBB.
|
|
16709
|
-
\u0418\u0434\u0451\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0438 \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B. \u041F\u043E\u0437\u043E\u0432\u0438 wait \u0441 job "${launch.id}" \u2014 \u043E\u043D \u043F\u043E\u0434\u043E\u0436\u0434\u0451\u0442 \u0438 \u043F\u043E \u0445\u043E\u0434\u0443 \u0440\u0430\u0441\u0441\u043A\u0430\u0436\u0435\u0442, \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u043A\u0430\u0447\u0430\u043D\u043E \u0438 \u043E \u0447\u0451\u043C \u043D\u0430\u0434\u043E \u0441\u043F\u0440\u043E\u0441\u0438\u0442\u044C \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430. \u041F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043D\u0435 \u0432 \u043A\u043E\u043D\u0446\u0435
|
|
17456
|
+
\u0418\u0434\u0451\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0438 \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B. \u041F\u043E\u0437\u043E\u0432\u0438 wait \u0441 job "${launch.id}" \u2014 \u043E\u043D \u043F\u043E\u0434\u043E\u0436\u0434\u0451\u0442 \u0438 \u043F\u043E \u0445\u043E\u0434\u0443 \u0440\u0430\u0441\u0441\u043A\u0430\u0436\u0435\u0442, \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u043A\u0430\u0447\u0430\u043D\u043E \u0438 \u043E \u0447\u0451\u043C \u043D\u0430\u0434\u043E \u0441\u043F\u0440\u043E\u0441\u0438\u0442\u044C \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430. \u041F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0441\u0440\u0430\u0437\u0443, \u0430 \u043D\u0435 \u0432 \u043A\u043E\u043D\u0446\u0435. ${AWAY_NOTE}`,
|
|
16710
17457
|
startedJob({
|
|
16711
17458
|
id: launch.id,
|
|
16712
17459
|
what: `\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430, \u0448\u0430\u0433 \xAB${step}\xBB`,
|
|
@@ -16729,9 +17476,9 @@ async function updateEngine(engine, consent, key, baseUrl, timeoutMs = ASKED_POI
|
|
|
16729
17476
|
const outcome = await fetchManifest(manifestUrl(engine, baseUrl), timeoutMs, key);
|
|
16730
17477
|
const decision = decide(engine.freshVersion(), outcome.ok ? outcome.manifest : null);
|
|
16731
17478
|
if (decision.what === "nothing") {
|
|
16732
|
-
const
|
|
17479
|
+
const ownDir2 = engine.freshVersion();
|
|
16733
17480
|
return toolSuccess(
|
|
16734
|
-
!outcome.ok ? `\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043F\u0440\u043E\u0441\u0438\u0442\u044C, \u0435\u0441\u0442\u044C \u043B\u0438 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u043D\u0430\u0447\u0438\u043D\u043A\u0438: ${outcome.why}. \u042D\u0442\u043E \u043D\u0435 \u043F\u043E\u043B\u043E\u043C\u043A\u0430: \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F (${
|
|
17481
|
+
!outcome.ok ? `\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043F\u0440\u043E\u0441\u0438\u0442\u044C, \u0435\u0441\u0442\u044C \u043B\u0438 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u043D\u0430\u0447\u0438\u043D\u043A\u0438: ${outcome.why}. \u042D\u0442\u043E \u043D\u0435 \u043F\u043E\u043B\u043E\u043C\u043A\u0430: \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F (${ownDir2 ?? "\u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430"}) \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043A\u0430\u043A \u0440\u0430\u0431\u043E\u0442\u0430\u043B\u0430.` : `\u041D\u0430\u0447\u0438\u043D\u043A\u0430 \u0441\u0432\u0435\u0436\u0430\u044F: \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430 ${ownDir2 ?? "\u043D\u0435\u0442"}, \u043D\u043E\u0432\u0435\u0435 \u043D\u0435 \u0432\u044B\u0448\u043B\u043E.`
|
|
16735
17482
|
);
|
|
16736
17483
|
}
|
|
16737
17484
|
if (decision.what === "shell_too_old") {
|
|
@@ -16925,16 +17672,228 @@ async function askBeforeHeavy(engine, step, model, key, baseUrl) {
|
|
|
16925
17672
|
]));
|
|
16926
17673
|
}
|
|
16927
17674
|
function together(results) {
|
|
16928
|
-
const
|
|
17675
|
+
const text2 = results.map((one) => one.type === "success" ? wordsOf(one.content) : one.error).filter((words) => words !== "").join("\n\n");
|
|
16929
17676
|
for (const one of results) {
|
|
16930
|
-
if (one.type === "success" && one.structured !== void 0) return toolSuccess(
|
|
17677
|
+
if (one.type === "success" && one.structured !== void 0) return toolSuccess(text2, one.structured);
|
|
16931
17678
|
}
|
|
16932
|
-
return results.some((one) => one.type === "error") ? toolError(
|
|
17679
|
+
return results.some((one) => one.type === "error") ? toolError(text2) : toolSuccess(text2);
|
|
16933
17680
|
}
|
|
16934
17681
|
function wordsOf(content) {
|
|
16935
17682
|
if (typeof content === "string") return content;
|
|
16936
17683
|
return content.map((block) => block.type === "text" ? block.text : "").join("\n");
|
|
16937
17684
|
}
|
|
17685
|
+
async function startRender(engine, asked, key, tell) {
|
|
17686
|
+
const place = engine.place();
|
|
17687
|
+
if (place === null) return toolError(engine.whyNoEngine());
|
|
17688
|
+
const where = fileOrRefusal(asked.video);
|
|
17689
|
+
if ("refusal" in where) return toolError(where.refusal);
|
|
17690
|
+
if (asked.onlyPauses !== true) return startDocumentRender(engine, where.path, key, tell);
|
|
17691
|
+
if (tell !== void 0) for (const line of PAUSES_LADDER) tell(line);
|
|
17692
|
+
const ask2 = { pauses: {} };
|
|
17693
|
+
if (asked.tempo !== void 0 && asked.tempo !== 1) ask2["tempo"] = asked.tempo;
|
|
17694
|
+
const draft = await draftDocument(engine, place, { video: where.path, style: asked.style, ask: ask2 }, key);
|
|
17695
|
+
if ("refusal" in draft) return toolError(draft.refusal);
|
|
17696
|
+
const reel = String(draft.data["project"] ?? where.path);
|
|
17697
|
+
const agreement = await editOperations(engine, place, { reel, ops: [{ op: "agree" }] }, key);
|
|
17698
|
+
if ("refusal" in agreement) return toolError(agreement.refusal);
|
|
17699
|
+
return startDocumentRender(engine, reel, key, tell);
|
|
17700
|
+
}
|
|
17701
|
+
async function startDocumentRender(engine, reel, key, tell) {
|
|
17702
|
+
const place = engine.place();
|
|
17703
|
+
if (place === null) return toolError(engine.whyNoEngine());
|
|
17704
|
+
const trouble = await engine.pythonTrouble();
|
|
17705
|
+
if (trouble !== null) return toolError(trouble);
|
|
17706
|
+
const python = engine.packPython();
|
|
17707
|
+
if (python === null) {
|
|
17708
|
+
return toolError("\u041E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 setup.");
|
|
17709
|
+
}
|
|
17710
|
+
if (tell !== void 0) for (const line of RENDER_LADDER) tell(line);
|
|
17711
|
+
const what = `\u043C\u043E\u043D\u0442\u0430\u0436 ${basename(reel)}`;
|
|
17712
|
+
const launch = await engine.background({
|
|
17713
|
+
place,
|
|
17714
|
+
executable: python,
|
|
17715
|
+
key,
|
|
17716
|
+
startJob: [
|
|
17717
|
+
"job-create",
|
|
17718
|
+
"--video",
|
|
17719
|
+
reel,
|
|
17720
|
+
"--what",
|
|
17721
|
+
what,
|
|
17722
|
+
"--command",
|
|
17723
|
+
JSON.stringify({ tool: "render", args: {} })
|
|
17724
|
+
],
|
|
17725
|
+
args: (id) => [
|
|
17726
|
+
place.consolePy,
|
|
17727
|
+
"document-render",
|
|
17728
|
+
"--project",
|
|
17729
|
+
reel,
|
|
17730
|
+
"--pack",
|
|
17731
|
+
place.pack,
|
|
17732
|
+
"--job",
|
|
17733
|
+
id
|
|
17734
|
+
],
|
|
17735
|
+
advice: "\u043F\u043E\u0437\u043E\u0432\u0438 setup \u2014 \u0441\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043D\u0435\u043F\u043E\u043B\u043D\u043E\u0435"
|
|
17736
|
+
});
|
|
17737
|
+
if ("refusal" in launch) return toolError(launch.refusal);
|
|
17738
|
+
return toolSuccess(
|
|
17739
|
+
`\u0417\u0430\u0434\u0430\u0447\u0430 ${launch.id}: ${what}
|
|
17740
|
+
\u0414\u0430\u043B\u044C\u0448\u0435 \u043F\u043E\u0437\u043E\u0432\u0438 wait \u0441 \u044D\u0442\u0438\u043C \u043D\u043E\u043C\u0435\u0440\u043E\u043C. ${AWAY_NOTE}`,
|
|
17741
|
+
startedJob({
|
|
17742
|
+
id: launch.id,
|
|
17743
|
+
what,
|
|
17744
|
+
ahead: RENDER_LADDER.join(" "),
|
|
17745
|
+
message: "\u0420\u043E\u043B\u0438\u043A \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F."
|
|
17746
|
+
})
|
|
17747
|
+
);
|
|
17748
|
+
}
|
|
17749
|
+
var RENDER_LADDER = [
|
|
17750
|
+
"\u041F\u0440\u043E\u0432\u0435\u0440\u044E, \u0447\u0442\u043E \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D \u0438 \u043D\u0435 \u043F\u0440\u0430\u0432\u043B\u0435\u043D \u043C\u0438\u043C\u043E plan_edit.",
|
|
17751
|
+
"\u041F\u043E\u0441\u0447\u0438\u0442\u0430\u044E \u044D\u0444\u0444\u0435\u043A\u0442\u044B \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0430 (\u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F, \u0448\u0443\u043C\u043E\u0434\u0430\u0432) \u0442\u0430\u043C, \u0433\u0434\u0435 \u0438\u0445 \u0432\u0438\u0434\u043D\u043E, \u2014 \u043F\u043E\u0442\u043E\u043C \u0441\u043E\u0431\u0435\u0440\u0443 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0443 \u0438 \u0437\u0432\u0443\u043A."
|
|
17752
|
+
];
|
|
17753
|
+
async function followWork(engine, asked, pace = realPace, tell) {
|
|
17754
|
+
const ask2 = () => engine.command(["job", asked.job]);
|
|
17755
|
+
const seconds2 = waitSeconds(asked.seconds ?? WAIT_LIMIT_SECONDS);
|
|
17756
|
+
if (seconds2 === 0) return asJobResult(await ask2());
|
|
17757
|
+
const state = await followJob({
|
|
17758
|
+
ask: ask2,
|
|
17759
|
+
seconds: seconds2,
|
|
17760
|
+
pace,
|
|
17761
|
+
// ⚠ Рассказ есть только если КЛИЕНТ его попросил (токен хода работы в
|
|
17762
|
+
// `_meta`). Нет — ждём молча и отвечаем итогом: ждать всё равно дешевле
|
|
17763
|
+
// пяти кругов переписки «спроси ещё раз».
|
|
17764
|
+
...tell !== void 0 ? { tell } : {}
|
|
17765
|
+
});
|
|
17766
|
+
if (state.ok && stillWorking(state.text)) {
|
|
17767
|
+
const words = `${state.text}
|
|
17768
|
+
\u0416\u0434\u0430\u043B ${seconds2} \u0441, \u0440\u0430\u0431\u043E\u0442\u0430 \u0435\u0449\u0451 \u0438\u0434\u0451\u0442. \u0421\u043A\u0430\u0436\u0438 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0438 \u043F\u043E\u0437\u043E\u0432\u0438 wait \u0435\u0449\u0451 \u0440\u0430\u0437 \u2014 \u0442\u0430\u043A \u043E\u043D \u0443\u0441\u043B\u044B\u0448\u0438\u0442 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0435 \u0448\u0430\u0433\u0438.`;
|
|
17769
|
+
const job = readJob(state.text);
|
|
17770
|
+
return job === null ? toolSuccess(words) : toolSuccess(words, job);
|
|
17771
|
+
}
|
|
17772
|
+
return asJobResult(state);
|
|
17773
|
+
}
|
|
17774
|
+
async function listJobs(engine, asked) {
|
|
17775
|
+
return asToolResult(
|
|
17776
|
+
await engine.command([
|
|
17777
|
+
"jobs",
|
|
17778
|
+
...asked.video !== void 0 ? ["--video", path(asked.video)] : [],
|
|
17779
|
+
...asked.limit !== void 0 ? ["--count", String(asked.limit)] : []
|
|
17780
|
+
])
|
|
17781
|
+
);
|
|
17782
|
+
}
|
|
17783
|
+
function renderTool(engine, _passport, key) {
|
|
17784
|
+
return defineTool({
|
|
17785
|
+
name: "render",
|
|
17786
|
+
title: "\u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0440\u043E\u043B\u0438\u043A",
|
|
17787
|
+
description: '\u0421\u043E\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0440\u043E\u043B\u0438\u043A\u0430 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430: \u044D\u0444\u0444\u0435\u043A\u0442\u044B \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0430 (\u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F, \u0448\u0443\u043C\u043E\u0434\u0430\u0432), \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0443, \u0437\u0432\u0443\u043A, \u0433\u043E\u0442\u043E\u0432\u044B\u0439 \u0444\u0430\u0439\u043B. \u0417\u043E\u0432\u0438 \u041F\u041E\u0421\u041B\u0415 \u0442\u043E\u0433\u043E, \u043A\u0430\u043A \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0441\u043A\u0430\u0437\u0430\u043B \xAB\u0434\u0430\xBB \u043D\u0430 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0438\u0437 plan \u0438 \u0442\u044B \u0437\u0430\u043F\u0438\u0441\u0430\u043B \u044D\u0442\u043E plan_edit \u0441 {"op": "agree"}. \u0421\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0422\u041E\u041B\u042C\u041A\u041E \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442, \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u043F\u0438\u0441\u0430\u043D\u043D\u044B\u0439 \u0447\u0435\u0440\u0435\u0437 plan_edit: \u0444\u0430\u0439\u043B, \u043F\u043E\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043D\u044B\u0439 \u043C\u0438\u043C\u043E \u043D\u0435\u0433\u043E, \u0434\u0432\u0438\u0436\u043E\u043A \u043D\u0435 \u0441\u043E\u0431\u0435\u0440\u0451\u0442 \u2014 \xAB\u043F\u0440\u0438\u0448\u043B\u0438 \u043F\u0440\u0430\u0432\u043A\u0443 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F\u043C\u0438\xBB.\n\u041E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0434\u0430\u043B\u044C\u0448\u0435 wait, \u043E\u043D \u043F\u043E\u0434\u043E\u0436\u0434\u0451\u0442 \u0438 \u0440\u0430\u0441\u0441\u043A\u0430\u0436\u0435\u0442 \u0445\u043E\u0434. \u041F\u043E\u0432\u0442\u043E\u0440 \u0431\u0435\u0437 \u043F\u0440\u0430\u0432\u043E\u043A \u043E\u0442\u0434\u0430\u0451\u0442 \u0433\u043E\u0442\u043E\u0432\u043E\u0435 \u0441\u0440\u0430\u0437\u0443.\n\u041F\u0440\u043E\u0441\u044F\u0442 \xAB\u043F\u0440\u043E\u0441\u0442\u043E \u0443\u0431\u0435\u0440\u0438 \u043F\u0430\u0443\u0437\u044B\xBB \u2014 only_pauses=true \u0441 video: \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0441 \u043E\u0434\u043D\u0438\u043C\u0438 \u043F\u0430\u0443\u0437\u0430\u043C\u0438, \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0438 \u0441\u0431\u043E\u0440\u043A\u0430 \u043E\u0434\u043D\u0438\u043C \u0432\u044B\u0437\u043E\u0432\u043E\u043C; tempo \u0440\u044F\u0434\u043E\u043C \u2014 \xAB\u0438 \u0443\u0441\u043A\u043E\u0440\u044C\xBB. \u041F\u0430\u0443\u0437\u044B \u0443\u0431\u0438\u0440\u0430\u044E\u0442\u0441\u044F \u043F\u043E \u0441\u043B\u043E\u0432\u0430\u043C, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043D\u0443\u0436\u043D\u0430 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u043D\u043D\u0430\u044F \u0440\u0435\u0447\u044C.\n\u0420\u0430\u0431\u043E\u0442\u0430 \u0438\u0434\u0451\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430, \u043A \u043D\u0430\u043C \u0432\u0438\u0434\u0435\u043E \u043D\u0435 \u0443\u0445\u043E\u0434\u0438\u0442 \u2014 \u043D\u0430\u0432\u0435\u0440\u0445 \u0438\u0434\u0451\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u043F\u043E \u043A\u043B\u044E\u0447\u0443.',
|
|
17788
|
+
// Полоса хода работы: монтаж идёт минутами, и всё это время в ленте не
|
|
17789
|
+
// происходило бы ничего. ⚠ Ожидание — у `wait`, и полосы там нет: иначе
|
|
17790
|
+
// каждая проверка рисовала бы новую поверх этой.
|
|
17791
|
+
ui: { resourceUri: RUNBAR_RESOURCE_URI },
|
|
17792
|
+
args: external_exports.object({
|
|
17793
|
+
video: external_exports.string().describe(
|
|
17794
|
+
"\u041F\u0443\u0442\u044C \u043A \u0432\u0438\u0434\u0435\u043E\u0444\u0430\u0439\u043B\u0443 \u0440\u043E\u043B\u0438\u043A\u0430. \u0417\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u044B\u0439 \u0440\u043E\u043B\u0438\u043A \u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0437\u0432\u0430\u0442\u044C \u0438 \u043F\u0430\u043F\u043A\u043E\u0439 \u2014 \u043A\u043B\u044E\u0447\u043E\u043C reel"
|
|
17795
|
+
).optional(),
|
|
17796
|
+
reel: external_exports.string().describe(
|
|
17797
|
+
"\u041F\u0430\u043F\u043A\u0430 \u0440\u043E\u043B\u0438\u043A\u0430: \u0441\u043E\u0431\u0435\u0440\u0443 \u0435\u0433\u043E \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 reel.json"
|
|
17798
|
+
).optional(),
|
|
17799
|
+
only_pauses: external_exports.boolean().describe(
|
|
17800
|
+
"\u0422\u043E\u043B\u044C\u043A\u043E \u0443\u0431\u0440\u0430\u0442\u044C \u043F\u0430\u0443\u0437\u044B: \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0441 \u043E\u0434\u043D\u0438\u043C \u0440\u0430\u0437\u0434\u0435\u043B\u043E\u043C pauses, \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0438 \u0441\u0431\u043E\u0440\u043A\u0430 \u0440\u0430\u0437\u043E\u043C"
|
|
17801
|
+
).optional(),
|
|
17802
|
+
tempo: external_exports.number().describe(
|
|
17803
|
+
"\u0422\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 only_pauses: \u0443\u0441\u043A\u043E\u0440\u0438\u0442\u044C \u0440\u0435\u0447\u044C, 1.0 \u2014 \u0431\u0435\u0437 \u0443\u0441\u043A\u043E\u0440\u0435\u043D\u0438\u044F"
|
|
17804
|
+
).optional(),
|
|
17805
|
+
style: external_exports.string().describe(
|
|
17806
|
+
"\u0422\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 only_pauses: \u043F\u0430\u043F\u043A\u0430 \u043F\u0430\u043A\u0430 \u0444\u0438\u0440\u043C\u0435\u043D\u043D\u043E\u0433\u043E \u0441\u0442\u0438\u043B\u044F"
|
|
17807
|
+
).optional()
|
|
17808
|
+
}).check((ctx) => {
|
|
17809
|
+
const asked = ctx.value;
|
|
17810
|
+
const say = (message, where) => {
|
|
17811
|
+
ctx.issues.push({ code: "custom", message, input: asked, path: [where] });
|
|
17812
|
+
};
|
|
17813
|
+
if (asked.video === void 0 && asked.reel === void 0) {
|
|
17814
|
+
say(
|
|
17815
|
+
"\u041D\u0435 \u0441\u043A\u0430\u0437\u0430\u043D\u043E, \u0447\u0442\u043E \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C: \u043D\u0430\u0437\u043E\u0432\u0438 video (\u0444\u0430\u0439\u043B) \u0438\u043B\u0438 reel (\u043F\u0430\u043F\u043A\u0443 \u0437\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430). \u0427\u0442\u043E \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0435\u0441\u0442\u044C, \u043F\u043E\u043A\u0430\u0436\u0435\u0442 plan \u0431\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432",
|
|
17816
|
+
"video"
|
|
17817
|
+
);
|
|
17818
|
+
}
|
|
17819
|
+
if (asked.video !== void 0 && asked.reel !== void 0) {
|
|
17820
|
+
say("\xABvideo\xBB \u0438 \xABreel\xBB \u2014 \u044D\u0442\u043E \u043E\u0434\u043D\u043E \u0438 \u0442\u043E \u0436\u0435 \u043C\u0435\u0441\u0442\u043E, \u043D\u0430\u0437\u0432\u0430\u043D\u043D\u043E\u0435 \u0434\u0432\u0430\u0436\u0434\u044B. \u041E\u0441\u0442\u0430\u0432\u044C \u043E\u0434\u043D\u043E", "reel");
|
|
17821
|
+
}
|
|
17822
|
+
if (asked.only_pauses === true) return;
|
|
17823
|
+
const extra = ["tempo", "style"].filter((name) => asked[name] !== void 0);
|
|
17824
|
+
if (extra.length > 0) {
|
|
17825
|
+
say(
|
|
17826
|
+
`${extra.join(", ")} \u2014 \u0447\u0430\u0441\u0442\u044C \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430, \u0430 \u043D\u0435 \u0441\u0431\u043E\u0440\u043A\u0438: \u0442\u0435\u043C\u043F \u2014 plan \u0441 ask {"tempo": \u2026} \u0438\u043B\u0438 plan_edit, \u0441\u0442\u0438\u043B\u044C \u2014 plan \u0441\u043E style. \u0417\u0434\u0435\u0441\u044C \u043E\u043D\u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 only_pauses`,
|
|
17827
|
+
extra[0] ?? "tempo"
|
|
17828
|
+
);
|
|
17829
|
+
}
|
|
17830
|
+
}),
|
|
17831
|
+
async execute(args, ctx) {
|
|
17832
|
+
return startRender(
|
|
17833
|
+
engine,
|
|
17834
|
+
{
|
|
17835
|
+
video: args.video ?? args.reel ?? "",
|
|
17836
|
+
onlyPauses: args.only_pauses,
|
|
17837
|
+
tempo: args.tempo,
|
|
17838
|
+
style: args.style
|
|
17839
|
+
},
|
|
17840
|
+
key,
|
|
17841
|
+
ctx?.emitProgress
|
|
17842
|
+
);
|
|
17843
|
+
}
|
|
17844
|
+
});
|
|
17845
|
+
}
|
|
17846
|
+
function waitTool(engine, pace = realPace) {
|
|
17847
|
+
return defineTool({
|
|
17848
|
+
name: "wait",
|
|
17849
|
+
title: "\u0414\u043E\u0436\u0434\u0430\u0442\u044C\u0441\u044F \u0440\u0430\u0431\u043E\u0442\u044B",
|
|
17850
|
+
description: `\u0416\u0434\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u043F\u043E \u0445\u043E\u0434\u0443 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442, \u043A\u0430\u043A\u043E\u0439 \u0448\u0430\u0433 \u043F\u043E\u0448\u0451\u043B \u0438 \u043A\u0430\u043A\u043E\u0439 \u0437\u0430\u043A\u043E\u043D\u0447\u0438\u043B\u0441\u044F \u2014 \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0441\u0440\u0430\u0437\u0443, \u043D\u0435 \u0434\u043E\u0436\u0438\u0434\u0430\u044F\u0441\u044C \u043A\u043E\u043D\u0446\u0430. \u0422\u0430\u043A \u0438 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0439: \u043E\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044C \u043F\u043E \u043A\u0440\u0443\u0433\u0443 \u043D\u0435 \u043D\u0430\u0434\u043E, \u0436\u0434\u0451\u0442 \u043E\u043D \u0434\u043E ${WAIT_LIMIT_SECONDS} \u0441\u0435\u043A\u0443\u043D\u0434 \u0438 \u0432\u0435\u0440\u043D\u0451\u0442\u0441\u044F \u0440\u0430\u043D\u044C\u0448\u0435, \u0435\u0441\u043B\u0438 \u0440\u0430\u0431\u043E\u0442\u0430 \u043A\u043E\u043D\u0447\u0438\u0442\u0441\u044F.
|
|
17851
|
+
\u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u043D\u043E\u043C\u0435\u0440, \u0440\u043E\u043B\u0438\u043A, \u0447\u0435\u043C \u043A\u043E\u043D\u0447\u0438\u043B\u043E\u0441\u044C. \u0417\u043E\u0432\u0438, \u043A\u043E\u0433\u0434\u0430 \u043D\u043E\u043C\u0435\u0440 \u043F\u043E\u0442\u0435\u0440\u044F\u043B\u0441\u044F: \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, \u043F\u043E\u0441\u043B\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u0438\u043B\u0438 \u043A\u043E\u0433\u0434\u0430 \u0432\u044B\u0437\u043E\u0432 \u043E\u0431\u043E\u0440\u0432\u0430\u043B\u0441\u044F \u043F\u043E\u0441\u0440\u0435\u0434\u0438 \u0440\u0430\u0431\u043E\u0442\u044B. \u0421 video \u2014 \u0437\u0430\u0434\u0430\u0447\u0438 \u043E\u0434\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430.
|
|
17852
|
+
\u0417\u0430\u0434\u0430\u0447\u0438 \u043B\u0435\u0436\u0430\u0442 \u043D\u0430 \u0434\u0438\u0441\u043A\u0435 \u0438 \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u044E\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B. \u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u043D\u0435 \u043D\u0443\u0436\u043D\u0430: \u0437\u0430\u0431\u0440\u0430\u0442\u044C \u0443\u0436\u0435 \u0441\u0434\u0435\u043B\u0430\u043D\u043D\u043E\u0435 \u043C\u043E\u0436\u043D\u043E \u0432\u0441\u0435\u0433\u0434\u0430.`,
|
|
17853
|
+
args: external_exports.object({
|
|
17854
|
+
job: external_exports.string().describe(
|
|
17855
|
+
"\u041D\u043E\u043C\u0435\u0440 \u0437\u0430\u0434\u0430\u0447\u0438, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 2026-08-19T14-03-12Z-a3f1. \u0415\u0433\u043E \u043D\u0430\u0437\u0432\u0430\u043B \u0442\u043E\u0442 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442, \u0447\u0442\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u043B \u0440\u0430\u0431\u043E\u0442\u0443"
|
|
17856
|
+
).optional(),
|
|
17857
|
+
seconds: external_exports.number().describe(
|
|
17858
|
+
`\u0421\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0435\u043A\u0443\u043D\u0434 \u0436\u0434\u0430\u0442\u044C. \u041F\u043E\u0442\u043E\u043B\u043E\u043A ${WAIT_LIMIT_SECONDS}: \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u0431\u043E\u043B\u044C\u0448\u0435 \u043C\u043E\u043B\u0447\u0430 \u043E\u0431\u0440\u0435\u0436\u0435\u0442\u0441\u044F. \u0411\u0435\u0437 \u043D\u0435\u0433\u043E \u0436\u0434\u0451\u0442 \u0441\u0442\u043E\u043B\u044C\u043A\u043E, \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043C\u043E\u0436\u043D\u043E`
|
|
17859
|
+
).optional(),
|
|
17860
|
+
video: external_exports.string().describe("\u0422\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u0434\u0430\u0447\u0438 \u044D\u0442\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430 (\u0431\u0435\u0437 job)").optional(),
|
|
17861
|
+
limit: external_exports.number().describe("\u0421\u043A\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u0434\u0430\u0447 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C, \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E 15").optional()
|
|
17862
|
+
}).check((ctx) => {
|
|
17863
|
+
const asked = ctx.value;
|
|
17864
|
+
if (asked.job === void 0) {
|
|
17865
|
+
if (asked.seconds !== void 0) {
|
|
17866
|
+
ctx.issues.push({
|
|
17867
|
+
code: "custom",
|
|
17868
|
+
message: "\xABseconds\xBB \u2014 \u044D\u0442\u043E \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0436\u0434\u0430\u0442\u044C \u041E\u0414\u041D\u0423 \u0437\u0430\u0434\u0430\u0447\u0443: \u043D\u0430\u0437\u043E\u0432\u0438 \u0435\u0451 \u043D\u043E\u043C\u0435\u0440 \u0432 \xABjob\xBB",
|
|
17869
|
+
input: asked,
|
|
17870
|
+
path: ["seconds"]
|
|
17871
|
+
});
|
|
17872
|
+
}
|
|
17873
|
+
return;
|
|
17874
|
+
}
|
|
17875
|
+
for (const key of ["video", "limit"]) {
|
|
17876
|
+
if (asked[key] !== void 0) {
|
|
17877
|
+
ctx.issues.push({
|
|
17878
|
+
code: "custom",
|
|
17879
|
+
message: `\xAB${key}\xBB \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0441\u044F \u043A \u0421\u041F\u0418\u0421\u041A\u0423 \u0437\u0430\u0434\u0430\u0447, \u0430 \u0441 \xABjob\xBB \u0436\u0434\u0443\u0442 \u043E\u0434\u043D\u0443. \u041F\u043E\u0437\u043E\u0432\u0438 \u0431\u0435\u0437 \xABjob\xBB, \u0447\u0442\u043E\u0431\u044B \u0443\u0432\u0438\u0434\u0435\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A`,
|
|
17880
|
+
input: asked,
|
|
17881
|
+
path: [key]
|
|
17882
|
+
});
|
|
17883
|
+
}
|
|
17884
|
+
}
|
|
17885
|
+
}),
|
|
17886
|
+
readOnly: true,
|
|
17887
|
+
async execute(args, ctx) {
|
|
17888
|
+
const place = engine.place();
|
|
17889
|
+
if (place === null) return toolError(engine.whyNoEngine());
|
|
17890
|
+
if (args.job === void 0) {
|
|
17891
|
+
return listJobs(engine, { video: args.video, limit: args.limit });
|
|
17892
|
+
}
|
|
17893
|
+
return followWork(engine, { job: args.job, seconds: args.seconds }, pace, ctx?.emitProgress);
|
|
17894
|
+
}
|
|
17895
|
+
});
|
|
17896
|
+
}
|
|
16938
17897
|
async function listReels(engine, workspace) {
|
|
16939
17898
|
const place = engine.place();
|
|
16940
17899
|
if (place === null) return toolError(engine.whyNoEngine());
|
|
@@ -16970,18 +17929,7 @@ async function openReel(engine, asked) {
|
|
|
16970
17929
|
if (!answer.ok) return toolError(answer.text);
|
|
16971
17930
|
return folderAnswer(answer.text);
|
|
16972
17931
|
}
|
|
16973
|
-
var PLAN_DRAFT = "naparnik-plan-draft/1";
|
|
16974
|
-
var COMPOSITION_VIEW = "naparnik-composition-view/1";
|
|
16975
17932
|
var SKILLS_READ = "naparnik-skills-read/1";
|
|
16976
|
-
function answerOrRefusal(text, contract) {
|
|
16977
|
-
const read = fromWords(text, contract);
|
|
16978
|
-
if ("refusal" in read) {
|
|
16979
|
-
const plain = text.trim();
|
|
16980
|
-
return { refusal: plain.startsWith("{") || plain === "" ? read.refusal : plain };
|
|
16981
|
-
}
|
|
16982
|
-
const said = read.data;
|
|
16983
|
-
return said.ok === false ? { refusal: read.words } : read;
|
|
16984
|
-
}
|
|
16985
17933
|
async function readSkills(engine, asked) {
|
|
16986
17934
|
const place = engine.place();
|
|
16987
17935
|
if (place === null) return toolError(engine.whyNoEngine());
|
|
@@ -16997,19 +17945,21 @@ async function readSkills(engine, asked) {
|
|
|
16997
17945
|
const read = answerOrRefusal(answer.text, SKILLS_READ);
|
|
16998
17946
|
return "refusal" in read ? toolError(read.refusal) : toolSuccess(read.words, read.data);
|
|
16999
17947
|
}
|
|
17000
|
-
async function
|
|
17948
|
+
async function viewDocument(engine, reel) {
|
|
17001
17949
|
const place = engine.place();
|
|
17002
17950
|
if (place === null) return toolError(engine.whyNoEngine());
|
|
17003
17951
|
const where = fileOrRefusal(reel);
|
|
17004
17952
|
if ("refusal" in where) return toolError(where.refusal);
|
|
17005
17953
|
const answer = await engine.command([
|
|
17006
|
-
"
|
|
17954
|
+
"document-view",
|
|
17007
17955
|
"--project",
|
|
17008
17956
|
path(where.path),
|
|
17957
|
+
"--pack",
|
|
17958
|
+
place.pack,
|
|
17009
17959
|
"--json"
|
|
17010
17960
|
]);
|
|
17011
17961
|
if (!answer.ok) return toolError(answer.text);
|
|
17012
|
-
const read = answerOrRefusal(answer.text,
|
|
17962
|
+
const read = answerOrRefusal(answer.text, VIEW_CONTRACT);
|
|
17013
17963
|
return "refusal" in read ? toolError(read.refusal) : toolSuccess(read.words, read.data);
|
|
17014
17964
|
}
|
|
17015
17965
|
async function whereToDraft(engine, video, also, workspace) {
|
|
@@ -17076,95 +18026,55 @@ async function planDraft(engine, asked, key, tell) {
|
|
|
17076
18026
|
}
|
|
17077
18027
|
}
|
|
17078
18028
|
if (tell !== void 0) for (const line of DRAFT_LADDER) tell(line);
|
|
17079
|
-
const
|
|
18029
|
+
const head2 = opened !== null && opened.type === "success" && typeof opened.content === "string" ? `${opened.content}
|
|
17080
18030
|
|
|
17081
18031
|
` : "";
|
|
17082
|
-
const withHead = (
|
|
17083
|
-
const
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
|
|
17090
|
-
"--json"
|
|
17091
|
-
], key !== void 0 ? { key } : {});
|
|
17092
|
-
if (!answer.ok) return toolError(withHead(answer.text));
|
|
17093
|
-
const read = answerOrRefusal(answer.text, PLAN_DRAFT);
|
|
18032
|
+
const withHead = (text2) => `${head2}${text2}`;
|
|
18033
|
+
const also = plan.toOpen.length > 0 ? [] : asked.also ?? [];
|
|
18034
|
+
const read = await draftDocument(
|
|
18035
|
+
engine,
|
|
18036
|
+
place,
|
|
18037
|
+
{ video: plan.speech, style: asked.style, ask: asked.ask, also },
|
|
18038
|
+
key
|
|
18039
|
+
);
|
|
17094
18040
|
if ("refusal" in read) return toolError(withHead(read.refusal));
|
|
17095
|
-
return
|
|
18041
|
+
return withSheets(withHead(read.words), read.data);
|
|
18042
|
+
}
|
|
18043
|
+
async function withSheets(text2, data) {
|
|
18044
|
+
const material = data["material"];
|
|
18045
|
+
const images = Array.isArray(material?.images) ? material.images.filter((one) => typeof one === "string") : [];
|
|
18046
|
+
if (images.length === 0) return toolSuccess(text2, data);
|
|
18047
|
+
const pictures = [];
|
|
18048
|
+
const lost = [];
|
|
18049
|
+
for (const file2 of images) {
|
|
18050
|
+
try {
|
|
18051
|
+
pictures.push({ type: "image", base64: (await readFile(file2)).toString("base64"), mediaType: "image/jpeg" });
|
|
18052
|
+
} catch {
|
|
18053
|
+
lost.push(basename(file2));
|
|
18054
|
+
}
|
|
18055
|
+
}
|
|
18056
|
+
const told = lost.length === 0 ? text2 : `${text2}
|
|
18057
|
+
\u26A0 \u0421\u0435\u0442\u043A\u0430 \u0440\u0430\u0441\u043A\u0430\u0434\u0440\u043E\u0432\u043A\u0438 \u043D\u0435 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043B\u0430\u0441\u044C: ${lost.join(", ")}. \u041A\u0430\u0434\u0440 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0430 \u043F\u043E\u043A\u0430\u0436\u0435\u0442 preview \u0441 video, moment \u0438 from_where=source.`;
|
|
18058
|
+
return toolMixed([{ type: "text", text: told }, ...pictures], data);
|
|
17096
18059
|
}
|
|
17097
18060
|
var DRAFT_LADDER = [
|
|
17098
|
-
"\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0440\u0430\u0437\
|
|
17099
|
-
"\u041F\u043E\u0442\u043E\u043C \
|
|
17100
|
-
"\u041F\u0435\u0440\u0432\u044B\u0439 \u0440\u0430\u0437 \u0438\u0434\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0430\u043C\u0438: \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438 \u0441\u0430\u043C\u043E\u0435 \u0434\u043E\u043B\u0433\u043E\u0435. \u041E\u0431\u043E\u0440\u0432\u0451\u0442\u0441\u044F \u2014 \u043F\u043E\u0437\u043E\u0432\u0438 wait, \u0440\u0430\u0431\u043E\u0442\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u0435\u0442\u0441\u044F, \u0430 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u044B\u0439 \
|
|
18061
|
+
"\u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u044E \u0440\u0435\u0447\u044C \u2014 \u0435\u0441\u043B\u0438 \u043F\u0440\u043E\u0441\u044C\u0431\u0435 \u043E\u043D\u0430 \u043D\u0443\u0436\u043D\u0430.",
|
|
18062
|
+
"\u041F\u043E\u0442\u043E\u043C \u0441\u043E\u0431\u0435\u0440\u0443 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430: \u043F\u0430\u0443\u0437\u044B, \u043F\u043E\u0434\u043F\u0438\u0441\u0438, \u043A\u0440\u0443\u043F\u043D\u043E\u0441\u0442\u0438, \u0437\u0432\u0443\u043A \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0442\u043E, \u0447\u0442\u043E \u043F\u0440\u043E\u0441\u0438\u043B\u0438.",
|
|
18063
|
+
"\u041F\u0435\u0440\u0432\u044B\u0439 \u0440\u0430\u0437 \u0438\u0434\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0430\u043C\u0438: \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438 \u0441\u0430\u043C\u043E\u0435 \u0434\u043E\u043B\u0433\u043E\u0435. \u041E\u0431\u043E\u0440\u0432\u0451\u0442\u0441\u044F \u2014 \u043F\u043E\u0437\u043E\u0432\u0438 wait, \u0440\u0430\u0431\u043E\u0442\u0430 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u0435\u0442\u0441\u044F, \u0430 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u044B\u0439 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0441\u0442\u043E\u0438\u0442 \u0441\u0435\u043A\u0443\u043D\u0434."
|
|
17101
18064
|
];
|
|
17102
|
-
function
|
|
17103
|
-
const lines = [];
|
|
17104
|
-
if (said.agreed === true) lines.push("\u041F\u043B\u0430\u043D \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D \u2014 \u043C\u043E\u0436\u043D\u043E \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C.");
|
|
17105
|
-
if (said.agreed === false) {
|
|
17106
|
-
lines.push(
|
|
17107
|
-
"\u0421\u043E\u0433\u043B\u0430\u0441\u0438\u044F \u043D\u0435\u0442: \u044D\u0442\u043E\u0439 \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0435\u0449\u0451 \u043D\u0435 \u0432\u0438\u0434\u0435\u043B. \u041F\u0435\u0440\u0435\u0441\u043A\u0430\u0436\u0438 \u0435\u043C\u0443, \u0447\u0442\u043E \u0432\u044B\u0448\u043B\u043E, \u0438 \u043D\u0430 \xAB\u0434\u0430\xBB \u043F\u043E\u0437\u043E\u0432\u0438 plan_edit \u0441 confirm \u2014 \u043C\u043E\u0436\u043D\u043E \u0442\u0435\u043C \u0436\u0435 \u0432\u044B\u0437\u043E\u0432\u043E\u043C, \u0447\u0442\u043E \u0438 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0443\u044E \u043F\u0440\u0430\u0432\u043A\u0443."
|
|
17108
|
-
);
|
|
17109
|
-
}
|
|
17110
|
-
if (said.plan_mine === true) {
|
|
17111
|
-
lines.push(
|
|
17112
|
-
"\u041F\u043B\u0430\u043D \u0440\u043E\u043B\u0438\u043A\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u0422\u0412\u041E\u0419: \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C\u0441\u044F \u0431\u0443\u0434\u0435\u0442 \u043E\u043D, \u043D\u0430\u0448 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F. \u0412\u0435\u0440\u043D\u0443\u0442\u044C \u043D\u0430\u0448 \u2014 plan_edit \u0441 draft."
|
|
17113
|
-
);
|
|
17114
|
-
}
|
|
17115
|
-
return lines;
|
|
17116
|
-
}
|
|
17117
|
-
async function editPlan(engine, asked, key, tell) {
|
|
18065
|
+
async function editDocument(engine, asked, key, tell) {
|
|
17118
18066
|
const place = engine.place();
|
|
17119
18067
|
if (place === null) return toolError(engine.whyNoEngine());
|
|
17120
|
-
const
|
|
17121
|
-
|
|
17122
|
-
|
|
17123
|
-
|
|
17124
|
-
|
|
17125
|
-
|
|
17126
|
-
|
|
17127
|
-
|
|
17128
|
-
|
|
17129
|
-
|
|
17130
|
-
asked.by ?? "model",
|
|
17131
|
-
"--json"
|
|
17132
|
-
], key !== void 0 ? { key } : {});
|
|
17133
|
-
if (!asked_.ok) return toolError(asked_.text);
|
|
17134
|
-
let said;
|
|
17135
|
-
try {
|
|
17136
|
-
said = JSON.parse(lastLine(asked_.text));
|
|
17137
|
-
} catch {
|
|
17138
|
-
return toolSuccess(asked_.text);
|
|
17139
|
-
}
|
|
17140
|
-
const many = (said.overrides ?? []).length;
|
|
17141
|
-
const done = typeof said.words === "string" && said.words !== "" ? said.words : [
|
|
17142
|
-
`\u041F\u0440\u0430\u0432\u043E\u043A \u0432 \u043F\u043B\u0430\u043D\u0435 \u0440\u043E\u043B\u0438\u043A\u0430: ${many}. \u0420\u043E\u043B\u0438\u043A: ${said.project ?? asked.reel}`,
|
|
17143
|
-
...aboutAgreement(said)
|
|
17144
|
-
].join("\n");
|
|
17145
|
-
if (asked.rebuild !== true) {
|
|
17146
|
-
return toolSuccess(
|
|
17147
|
-
`${done}
|
|
17148
|
-
\u0427\u0442\u043E\u0431\u044B \u0443\u0432\u0438\u0434\u0435\u0442\u044C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442, \u043F\u043E\u0437\u043E\u0432\u0438 plan_edit \u0435\u0449\u0451 \u0440\u0430\u0437 \u0441 rebuild \u0438\u043B\u0438 \u0441\u043E\u0431\u0435\u0440\u0438 render \u2014 \u043F\u0435\u0440\u0435\u0441\u0431\u043E\u0440\u043A\u0430 \u0438\u0437 \u043A\u044D\u0448\u0430 \u0441\u0442\u043E\u0438\u0442 \u0441\u0435\u043A\u0443\u043D\u0434.`
|
|
17149
|
-
);
|
|
17150
|
-
}
|
|
17151
|
-
if (said.video === null || said.video === void 0) {
|
|
17152
|
-
return toolError(
|
|
17153
|
-
`${done}
|
|
17154
|
-
\u0410 \u043F\u0435\u0440\u0435\u0441\u043E\u0431\u0440\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C: \u0432 \u0431\u0440\u0438\u0444\u0435 \u0440\u043E\u043B\u0438\u043A\u0430 \u043D\u0435 \u0437\u0430\u043F\u0438\u0441\u0430\u043D \u0444\u0430\u0439\u043B \u0441 \u0440\u0435\u0447\u044C\u044E.
|
|
17155
|
-
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 render \u0441 \u043F\u0443\u0442\u0451\u043C \u043A \u0432\u0438\u0434\u0435\u043E \u2014 \u043E\u043D \u0438 \u0437\u0430\u043F\u0438\u0448\u0435\u0442 \u0444\u0430\u0439\u043B \u0432 \u0431\u0440\u0438\u0444.`
|
|
17156
|
-
);
|
|
17157
|
-
}
|
|
17158
|
-
return startMontage(engine, {
|
|
17159
|
-
key,
|
|
17160
|
-
place,
|
|
17161
|
-
...tell !== void 0 ? { tell } : {},
|
|
17162
|
-
video: said.video,
|
|
17163
|
-
what: `\u043F\u0440\u0430\u0432\u043A\u0430 ${basename(said.video)}`,
|
|
17164
|
-
command: { "tool": "montage", "args": {} },
|
|
17165
|
-
args: [],
|
|
17166
|
-
hint: "\u041F\u0440\u0430\u0432\u043A\u0430 \u043F\u043B\u0430\u043D\u0430: \u0437\u0430\u043D\u043E\u0432\u043E \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u0442\u0440\u043E\u043D\u0443\u0442\u043E\u0435, \u043E\u0431\u044B\u0447\u043D\u043E \u0441\u0435\u043A\u0443\u043D\u0434\u044B."
|
|
17167
|
-
});
|
|
18068
|
+
const read = await editOperations(engine, place, asked, key);
|
|
18069
|
+
if ("refusal" in read) return toolError(read.refusal);
|
|
18070
|
+
if (asked.rebuild !== true) return toolSuccess(read.words, read.data);
|
|
18071
|
+
const project = typeof read.data["project"] === "string" ? read.data["project"] : asked.reel;
|
|
18072
|
+
const started = await startDocumentRender(engine, project, key, tell);
|
|
18073
|
+
if (started.type === "error") return started;
|
|
18074
|
+
const text2 = typeof started.content === "string" ? started.content : "";
|
|
18075
|
+
return toolSuccess(`${read.words}
|
|
18076
|
+
|
|
18077
|
+
${text2}`, started.structured);
|
|
17168
18078
|
}
|
|
17169
18079
|
var RECIPE_CONTRACT = "naparnik-recipe-view/1";
|
|
17170
18080
|
var STEP_NEEDS = {
|
|
@@ -17234,7 +18144,11 @@ function planTool(engine, key) {
|
|
|
17234
18144
|
return defineTool({
|
|
17235
18145
|
name: "plan",
|
|
17236
18146
|
title: "\u0427\u0442\u043E \u043F\u043E\u043A\u0430\u0436\u0435\u043C \u0432 \u0440\u043E\u043B\u0438\u043A\u0435",
|
|
17237
|
-
description:
|
|
18147
|
+
description: `\u0427\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0440\u043E\u043B\u0438\u043A\u0430 \u2014 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 reel.json \u0438 \u0435\u0433\u043E \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437 \u0441\u043B\u043E\u0432\u0430\u043C\u0438, \u0434\u043E \u0441\u0431\u043E\u0440\u043A\u0438. \u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442, \u0447\u0442\u043E \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0432 \u043F\u0430\u043F\u043A\u0435: \u0440\u043E\u043B\u0438\u043A\u0438 \u0441 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u043C \u0438 \u0444\u0430\u0439\u043B\u044B, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0440\u043E\u043B\u0438\u043A\u043E\u043C \u0435\u0449\u0451 \u043D\u0435 \u0441\u0442\u0430\u043B\u0438. \u0417\u043E\u0432\u0438 \u043F\u0435\u0440\u0432\u044B\u043C, \u043A\u043E\u0433\u0434\u0430 \u043D\u0435 \u0437\u043D\u0430\u0435\u0448\u044C, \u043E \u043A\u0430\u043A\u043E\u043C \u0440\u043E\u043B\u0438\u043A\u0435 \u0440\u0435\u0447\u044C.
|
|
18148
|
+
\u0421 video \u0437\u0430\u0432\u043E\u0434\u0438\u0442 \u0440\u043E\u043B\u0438\u043A (\u0435\u0441\u043B\u0438 \u0444\u0430\u0439\u043B \u0435\u0449\u0451 \u043D\u0435 \u0432 \u0440\u043E\u043B\u0438\u043A\u0435) \u0438 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A: \u043F\u043E\u0441\u0442\u0430\u0432\u0449\u0438\u043A\u0438 \u043A\u043B\u0430\u0434\u0443\u0442 \u043A\u043B\u0438\u043F\u044B \u043F\u043E \u0440\u0430\u0437\u0434\u0435\u043B\u0430\u043C \u043F\u0440\u043E\u0441\u044C\u0431\u044B. \u0423\u0437\u043A\u0430\u044F \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u2014 ask \u0441 \u0435\u0451 \u0440\u0430\u0437\u0434\u0435\u043B\u0430\u043C\u0438: {"tempo": 1.2} \u2014 \xAB\u0443\u0441\u043A\u043E\u0440\u044C \u0432 1,2 \u0440\u0430\u0437\u0430\xBB (\u0447\u0438\u0441\u043B\u043E \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0447\u0435\u043B\u043E\u0432\u0435\u043A), {"loudness": {}, "voice": {}} \u2014 \xAB\u043F\u043E\u0434\u043D\u0438\u043C\u0438 \u0433\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0438 \u0443\u0431\u0435\u0440\u0438 \u0448\u0443\u043C\xBB; \u0440\u0430\u0437\u0434\u0435\u043B \u0441\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u043C true \u2014 \xAB\u043A\u0430\u043A \u0440\u0435\u0448\u0438\u0442 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\xBB. ask \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D: \xAB\u0441\u043C\u043E\u043D\u0442\u0438\u0440\u0443\u0439\xBB \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u2014 ${FULL_WORDS}. \u041F\u043E\u043B\u043D\u044B\u0439 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0438 \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u043F\u0440\u043E \u043A\u0430\u0434\u0440 \u043F\u0440\u0438\u043D\u043E\u0441\u044F\u0442 \u043C\u0430\u0442\u0435\u0440\u0438\u0430\u043B: \u0444\u0430\u0439\u043B\u044B \u0441\u043B\u043E\u0432\u0430\u043C\u0438 \u0438 \u0440\u0430\u0441\u043A\u0430\u0434\u0440\u043E\u0432\u043A\u0443 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0430\u043C\u0438 \u2014 \u043F\u043E\u0441\u043C\u043E\u0442\u0440\u0438 \u0434\u043E \u043F\u043B\u0430\u043D\u0430. \u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u043C \u0431\u043B\u043E\u043A\u043E\u043C \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442 2\u20134 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430: \u043F\u0440\u043E\u0447\u0442\u0438 \u0438\u0445 (plan \u0441 read), \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0436\u0438 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u043F\u043E\u0441\u0442\u0440\u043E\u0447\u043D\u043E, \u043F\u043E\u043F\u0440\u0430\u0432\u044C plan_edit \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F\u043C\u0438 \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \u0435\u0433\u043E \xAB\u0434\u0430\xBB \u0437\u043E\u0432\u0438 render.
|
|
18149
|
+
\u041F\u0435\u0440\u0432\u044B\u0439 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0441 \u0440\u0435\u0447\u044C\u044E \u0438\u0434\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0430\u043C\u0438. \u041E\u0431\u043E\u0440\u0432\u0430\u043B\u0441\u044F \u0432\u044B\u0437\u043E\u0432 \u2014 \u0440\u0430\u0431\u043E\u0442\u0430 \u043D\u0435 \u043F\u0440\u043E\u043F\u0430\u043B\u0430: \u043F\u043E\u0437\u043E\u0432\u0438 wait, \u0430 \u043F\u043E\u0442\u043E\u043C plan \u043F\u043E \u0442\u043E\u043C\u0443 \u0436\u0435 \u0440\u043E\u043B\u0438\u043A\u0443 \u0435\u0449\u0451 \u0440\u0430\u0437, \u0432\u0442\u043E\u0440\u043E\u0439 \u0440\u0430\u0437 \u044D\u0442\u043E \u0441\u0435\u043A\u0443\u043D\u0434\u044B.
|
|
18150
|
+
\u0421 reel \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0440\u043E\u043B\u0438\u043A\u0430: \u0434\u043E\u0440\u043E\u0436\u043A\u0438, \u043A\u043B\u0438\u043F\u044B \u043F\u043E id, \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D \u043B\u0438 \u043E\u043D.
|
|
18151
|
+
\u0421 read \u043E\u0442\u0434\u0430\u0451\u0442 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u0421\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430 \u043C\u043E\u043D\u0442\u0430\u0436\u0451\u0440\u0430 (\u043F\u0435\u0447\u0430\u0442\u044C \u043F\u0435\u0440\u0432\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u043E\u0439), \u0442\u0430\u0431\u043B\u0438\u0446\u044B \u0432\u043A\u0443\u0441\u0430 \u0438 \u0447\u0443\u0436\u0438\u0435 \u0444\u0430\u0439\u043B\u044B \u2014 \u043F\u0443\u0442\u0438 \u0438\u0437 \u043E\u0433\u043B\u0430\u0432\u043B\u0435\u043D\u0438\u044F (\u0435\u0433\u043E \u0434\u0430\u0451\u0442 setup), \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0430 \u0438\u043B\u0438 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B. \u0427\u0438\u0442\u0430\u0439 2\u20134 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u043E\u0434\u043D\u0438\u043C \u0432\u044B\u0437\u043E\u0432\u043E\u043C \u0438 \u043D\u0435 \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u043F\u0443\u0442\u0435\u0439.`,
|
|
17238
18152
|
// Полоса хода работы в ленте: черновик считается минутами, и всё это время
|
|
17239
18153
|
// в ленте не происходило бы ничего. ⚠ Ожидание задачи — у `wait`, и полосы
|
|
17240
18154
|
// у него нет: она объявлена на инструменте, и каждый вызов ожидания рисовал
|
|
@@ -17245,7 +18159,14 @@ function planTool(engine, key) {
|
|
|
17245
18159
|
"\u041F\u0443\u0442\u044C \u043A \u0432\u0438\u0434\u0435\u043E\u0444\u0430\u0439\u043B\u0443 \u0441 \u0440\u0435\u0447\u044C\u044E \u2014 \u043F\u043E \u043D\u0435\u043C\u0443 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044F \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A. \u0424\u0430\u0439\u043B \u043B\u0435\u0436\u0438\u0442 \u0432 \u043F\u0430\u043F\u043A\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0438 \u0440\u043E\u043B\u0438\u043A\u043E\u043C \u0435\u0449\u0451 \u043D\u0435 \u0441\u0442\u0430\u043B \u2014 \u0437\u0430\u0432\u0435\u0434\u0443 \u0440\u043E\u043B\u0438\u043A \u0441\u0430\u043C"
|
|
17246
18160
|
).optional(),
|
|
17247
18161
|
reel: external_exports.string().describe(
|
|
17248
|
-
"\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430 \
|
|
18162
|
+
"\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430: \u043F\u043E\u043A\u0430\u0436\u0443 \u0435\u0433\u043E \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 reel.json \u2014 \u0434\u043E\u0440\u043E\u0436\u043A\u0438, \u043A\u043B\u0438\u043F\u044B \u043F\u043E id \u0438 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D \u043B\u0438 \u043E\u043D; \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044B\u0432\u0430\u044E"
|
|
18163
|
+
).optional(),
|
|
18164
|
+
// ⚠ ПОЛЯ РАЗДЕЛОВ СВОБОДНЫЕ, И ЭТО НЕ ЛЕНЬ: дом просьбы — поставщики пака
|
|
18165
|
+
// (`SECTIONS` шагов и их `supply`), судья — движок, и отказ приходит его
|
|
18166
|
+
// словами. Имена разделов описание повторяет, потому что его читает
|
|
18167
|
+
// модель; сторож копии — `plan-tools.test.ts`, сверка с `SECTIONS` пака.
|
|
18168
|
+
ask: external_exports.looseObject({}).describe(
|
|
18169
|
+
`\u0423\u0437\u043A\u0430\u044F \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u0440\u0430\u0437\u0434\u0435\u043B\u0430\u043C\u0438 \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 video: ${ASK_SECTIONS.join(", ")}; tempo \u2014 \u0432\u043E \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0440\u0430\u0437 \u0443\u0441\u043A\u043E\u0440\u0438\u0442\u044C, \u0447\u0438\u0441\u043B\u043E \u043E\u0442 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430. \u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 true \u2014 \xAB\u043A\u0430\u043A \u0440\u0435\u0448\u0438\u0442 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\xBB. {} \u2014 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A \u043A\u0430\u043A \u0441\u043D\u044F\u0442 (\u0446\u0432\u0435\u0442, \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0430); {"speech": {}} \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0441\u043B\u043E\u0432\u0430 \u0441 \u043D\u043E\u043C\u0435\u0440\u0430\u043C\u0438 (fix_word, \u043A\u0443\u0441\u043E\u043A \u0441\u043E \u0441\u043B\u043E\u0432\u0430). ${FULL_WORDS} \u2014 \u043F\u043E\u043B\u043D\u044B\u0439 \u043C\u043E\u043D\u0442\u0430\u0436, \u0442\u043E\u043B\u044C\u043A\u043E \u043D\u0430 \xAB\u0441\u043C\u043E\u043D\u0442\u0438\u0440\u0443\u0439\xBB \u0446\u0435\u043B\u0438\u043A\u043E\u043C. \u0421 video \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u0435\u043D: \u0431\u0435\u0437 \u043D\u0435\u0433\u043E \u2014 \u043E\u0442\u043A\u0430\u0437`
|
|
17249
18170
|
).optional(),
|
|
17250
18171
|
also: external_exports.array(external_exports.string()).describe(
|
|
17251
18172
|
"\u0427\u0442\u043E \u0435\u0449\u0451 \u0438\u0434\u0451\u0442 \u0432 \u042D\u0422\u041E\u0422 \u0440\u043E\u043B\u0438\u043A: \u0437\u0430\u043F\u0438\u0441\u044C \u044D\u043A\u0440\u0430\u043D\u0430, \u043C\u0443\u0437\u044B\u043A\u0430, \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438. \u0420\u043E\u043B\u0438 \u0440\u0435\u0448\u0430\u0435\u0442 \u0437\u0430\u043C\u0435\u0440, \u0430 \u043D\u0435 \u0438\u043C\u044F \u0444\u0430\u0439\u043B\u0430. \u0422\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 video \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u0438 \u0437\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u0438 \u0440\u043E\u043B\u0438\u043A\u0430"
|
|
@@ -17259,15 +18180,12 @@ function planTool(engine, key) {
|
|
|
17259
18180
|
style: external_exports.string().describe(
|
|
17260
18181
|
"\u041F\u0430\u043F\u043A\u0430 \u043F\u0430\u043A\u0430 \u0444\u0438\u0440\u043C\u0435\u043D\u043D\u043E\u0433\u043E \u0441\u0442\u0438\u043B\u044F: \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044F \u0442\u0430\u043A, \u043A\u0430\u043A \u0435\u0433\u043E \u043F\u043E\u0442\u043E\u043C \u0441\u043E\u0431\u0435\u0440\u0443\u0442"
|
|
17261
18182
|
).optional(),
|
|
17262
|
-
// ⚠
|
|
17263
|
-
//
|
|
17264
|
-
//
|
|
17265
|
-
//
|
|
17266
|
-
// наших замеров, а не из головы. Про «по одной-две за вызов» сказано тут
|
|
17267
|
-
// же: таблицы тяжёлые, а ответ движка обрезан 48 КБ, и вызов на шесть
|
|
17268
|
-
// таблиц вернулся бы частями, то есть лишними ходами.
|
|
18183
|
+
// ⚠ ПУТИ — КАК ИХ ПЕЧАТАЕТ ОГЛАВЛЕНИЕ СПРАВОЧНИКА (пакет Б1.14): без
|
|
18184
|
+
// приставки — страница `handbook/`, `taste/…` — таблица вкуса, `vendor/…` —
|
|
18185
|
+
// чужой файл. Заслоны чтения живут в движке (`engine/handbook/reader.py`).
|
|
18186
|
+
// Таблицы вкуса тяжёлые, а ответ движка обрезан 48 КБ: по одной-две.
|
|
17269
18187
|
read: external_exports.array(external_exports.string()).describe(
|
|
17270
|
-
`\
|
|
18188
|
+
`\u041F\u0443\u0442\u0438 \u043A\u0430\u043A \u0438\u0445 \u043D\u0430\u043F\u0435\u0447\u0430\u0442\u0430\u043B\u0438 \u043E\u0433\u043B\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430, \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0438\u043B\u0438 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430: \xABdocument/clips.md\xBB, \xABtaste/rhythm.json\xBB, \xABvendor/taste-skill/SKILL.md\xBB. \u0414\u043E ${FILES_PER_READ} \u0437\u0430 \u0432\u044B\u0437\u043E\u0432, \u0431\u0435\u0437 \xAB../\xBB \u0438 \u0431\u0435\u0437 \u0441\u0432\u043E\u0438\u0445 \u043F\u0443\u0442\u0435\u0439. \u0422\u0430\u0431\u043B\u0438\u0446\u044B \u0432\u043A\u0443\u0441\u0430 \u0442\u044F\u0436\u0451\u043B\u044B\u0435: \u043F\u043E \u043E\u0434\u043D\u043E\u0439-\u0434\u0432\u0435 \u0437\u0430 \u0432\u044B\u0437\u043E\u0432, \u0438\u043D\u0430\u0447\u0435 \u043E\u0442\u0432\u0435\u0442 \u043F\u0440\u0438\u0434\u0451\u0442 \u0447\u0430\u0441\u0442\u044F\u043C\u0438`
|
|
17271
18189
|
).optional(),
|
|
17272
18190
|
part: external_exports.number().describe(
|
|
17273
18191
|
"\u041A\u0430\u043A\u0430\u044F \u0447\u0430\u0441\u0442\u044C \u043E\u0442\u0432\u0435\u0442\u0430 \u043D\u0443\u0436\u043D\u0430, \u0435\u0441\u043B\u0438 \u0444\u0430\u0439\u043B \u0434\u043B\u0438\u043D\u043D\u044B\u0439: \u0441\u0447\u0451\u0442 \u0441 \u0435\u0434\u0438\u043D\u0438\u0446\u044B. \u0421\u043A\u043E\u043B\u044C\u043A\u043E \u0438\u0445 \u0432\u0441\u0435\u0433\u043E, \u0441\u043A\u0430\u0436\u0435\u0442 \u0441\u0430\u043C \u043E\u0442\u0432\u0435\u0442"
|
|
@@ -17296,7 +18214,13 @@ function planTool(engine, key) {
|
|
|
17296
18214
|
if (asked.part !== void 0 && asked.read === void 0) {
|
|
17297
18215
|
say("\xABpart\xBB \u2014 \u044D\u0442\u043E \u0447\u0430\u0441\u0442\u044C \u043E\u0442\u0432\u0435\u0442\u0430 \u0447\u0442\u0435\u043D\u0438\u044F: \u043E\u043D \u0431\u044B\u0432\u0430\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 \xABread\xBB", "part");
|
|
17298
18216
|
}
|
|
17299
|
-
|
|
18217
|
+
if (asked.video !== void 0 && asked.ask === void 0) {
|
|
18218
|
+
say(
|
|
18219
|
+
`\u041D\u0430\u0437\u043E\u0432\u0438 \u043F\u0440\u043E\u0441\u044C\u0431\u0443: ask \u2014 \u0442\u043E\u043B\u044C\u043A\u043E \u0442\u043E, \u0447\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u043F\u043E\u043F\u0440\u043E\u0441\u0438\u043B ({"tempo": <\u0432\u043E \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0440\u0430\u0437 \u043E\u043D \u0441\u043A\u0430\u0437\u0430\u043B>}, {"pauses": {}}, {"subtitles": {}}); \u0446\u0432\u0435\u0442, \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u0430, split-screen \u2014 {}; \u0438\u0441\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0441\u043B\u043E\u0432\u043E \u2014 {"speech": {}}. \xAB\u0421\u043C\u043E\u043D\u0442\u0438\u0440\u0443\u0439\xBB \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u2014 ${FULL_WORDS}`,
|
|
18220
|
+
"ask"
|
|
18221
|
+
);
|
|
18222
|
+
}
|
|
18223
|
+
for (const key2 of ["also", "together", "ask"]) {
|
|
17300
18224
|
if (asked[key2] !== void 0 && asked.video === void 0) {
|
|
17301
18225
|
say(`\xAB${key2}\xBB \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0441\u044F \u043A \u0437\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u044E \u0440\u043E\u043B\u0438\u043A\u0430 \u0438 \u0431\u044B\u0432\u0430\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 \xABvideo\xBB`, key2);
|
|
17302
18226
|
}
|
|
@@ -17306,7 +18230,7 @@ function planTool(engine, key) {
|
|
|
17306
18230
|
if (args.read !== void 0) {
|
|
17307
18231
|
return readSkills(engine, { files: args.read, part: args.part });
|
|
17308
18232
|
}
|
|
17309
|
-
if (args.reel !== void 0) return
|
|
18233
|
+
if (args.reel !== void 0) return viewDocument(engine, args.reel);
|
|
17310
18234
|
if (args.video === void 0) return listReels(engine, args.workspace);
|
|
17311
18235
|
return planDraft(
|
|
17312
18236
|
engine,
|
|
@@ -17315,7 +18239,8 @@ function planTool(engine, key) {
|
|
|
17315
18239
|
also: args.also,
|
|
17316
18240
|
together: args.together,
|
|
17317
18241
|
workspace: args.workspace,
|
|
17318
|
-
style: args.style
|
|
18242
|
+
style: args.style,
|
|
18243
|
+
ask: args.ask
|
|
17319
18244
|
},
|
|
17320
18245
|
key,
|
|
17321
18246
|
ctx?.emitProgress
|
|
@@ -17323,127 +18248,74 @@ function planTool(engine, key) {
|
|
|
17323
18248
|
}
|
|
17324
18249
|
});
|
|
17325
18250
|
}
|
|
17326
|
-
var
|
|
17327
|
-
var
|
|
17328
|
-
var
|
|
17329
|
-
|
|
18251
|
+
var FULL_ASK = "all";
|
|
18252
|
+
var FULL_WORDS = `{"${FULL_ASK}": true}`;
|
|
18253
|
+
var ASK_SECTIONS = [
|
|
18254
|
+
"tempo",
|
|
18255
|
+
"pauses",
|
|
18256
|
+
"loudness",
|
|
18257
|
+
"voice",
|
|
18258
|
+
"music",
|
|
18259
|
+
"subtitles",
|
|
18260
|
+
"shots",
|
|
18261
|
+
"world",
|
|
18262
|
+
"inserts",
|
|
18263
|
+
"accents",
|
|
18264
|
+
"intro",
|
|
18265
|
+
"screen",
|
|
18266
|
+
"zoom",
|
|
18267
|
+
"webcam",
|
|
18268
|
+
"regions"
|
|
18269
|
+
];
|
|
18270
|
+
var OPS = [
|
|
18271
|
+
"set",
|
|
18272
|
+
"unset",
|
|
18273
|
+
"add",
|
|
18274
|
+
"remove",
|
|
18275
|
+
"add_track",
|
|
18276
|
+
"add_group",
|
|
18277
|
+
"fix_word",
|
|
18278
|
+
"add_source",
|
|
18279
|
+
"add_package",
|
|
18280
|
+
"repin",
|
|
18281
|
+
"agree",
|
|
18282
|
+
"remember",
|
|
18283
|
+
"forget"
|
|
18284
|
+
];
|
|
17330
18285
|
function opSchema() {
|
|
17331
|
-
return external_exports.
|
|
17332
|
-
op: external_exports.string().describe(
|
|
17333
|
-
"hero | remove | add | move | text | accent | word | world | motion | intro | part"
|
|
17334
|
-
),
|
|
17335
|
-
from_word: external_exports.number().describe("hero: \u043F\u0435\u0440\u0432\u043E\u0435 \u0441\u043B\u043E\u0432\u043E \u043E\u0442\u0440\u0435\u0437\u043A\u0430").optional(),
|
|
17336
|
-
// ⚠ ВТОРОЕ ЧИСЛО — СЛЕДУЮЩЕЕ ЗА ОТРЕЗКОМ, А НЕ ПОСЛЕДНЕЕ В НЁМ. Так их
|
|
17337
|
-
// считает план (`lib/draft/build.py`: время конца берётся у слова `to_word - 1`),
|
|
17338
|
-
// так же они печатаются в черновике словами, и так же их ждёт правка.
|
|
17339
|
-
// До 2026-09-18 здесь стояло «последнее слово отрезка» — и модель, списав
|
|
17340
|
-
// число из черновика, промахивалась на одно слово на каждой границе.
|
|
17341
|
-
to_word: external_exports.number().describe(
|
|
17342
|
-
"hero: \u0441\u043B\u043E\u0432\u043E \u0421\u041B\u0415\u0414\u0423\u042E\u0429\u0415\u0415 \u0437\u0430 \u043E\u0442\u0440\u0435\u0437\u043A\u043E\u043C \u2014 \u043E\u043D\u043E \u0441\u0430\u043C\u043E \u0432 \u043E\u0442\u0440\u0435\u0437\u043E\u043A \u043D\u0435 \u0432\u0445\u043E\u0434\u0438\u0442. \u0420\u043E\u0432\u043D\u043E \u0442\u043E \u0447\u0438\u0441\u043B\u043E, \u0447\u0442\u043E \u043D\u0430\u043F\u0435\u0447\u0430\u0442\u0430\u043D\u043E \u0432 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0435"
|
|
17343
|
-
).optional(),
|
|
17344
|
-
at_word: external_exports.number().describe("add, move: \u043D\u0430 \u043A\u0430\u043A\u043E\u043C \u0441\u043B\u043E\u0432\u0435").optional(),
|
|
17345
|
-
until_word: external_exports.number().describe(
|
|
17346
|
-
"add: \u0441\u043B\u043E\u0432\u043E \u0421\u041B\u0415\u0414\u0423\u042E\u0429\u0415\u0415 \u0437\u0430 \u043E\u0442\u0440\u0435\u0437\u043A\u043E\u043C \u2014 \u043E\u043D\u043E \u0441\u0430\u043C\u043E \u043D\u0435 \u0432\u0445\u043E\u0434\u0438\u0442"
|
|
17347
|
-
).optional(),
|
|
17348
|
-
word: external_exports.number().describe("accent, word: \u043D\u043E\u043C\u0435\u0440 \u0441\u043B\u043E\u0432\u0430").optional(),
|
|
17349
|
-
insert: external_exports.string().describe(
|
|
17350
|
-
"remove, move, text, motion: \u0438\u043C\u044F \u0432\u0441\u0442\u0430\u0432\u043A\u0438 \u0438\u0437 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0430, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 chips-1"
|
|
17351
|
-
).optional(),
|
|
17352
|
-
item: external_exports.number().describe("text: \u043D\u043E\u043C\u0435\u0440 \u043F\u0443\u043D\u043A\u0442\u0430 \u0441\u043F\u0438\u0441\u043A\u0430, \u0441 \u0435\u0434\u0438\u043D\u0438\u0446\u044B").optional(),
|
|
17353
|
-
template: external_exports.string().describe("add: \u0448\u0430\u0431\u043B\u043E\u043D \u0432\u0441\u0442\u0430\u0432\u043A\u0438").optional(),
|
|
17354
|
-
text: external_exports.string().describe(
|
|
17355
|
-
"add: \u043F\u043E\u0434\u043F\u0438\u0441\u044C \u043D\u043E\u0432\u043E\u0439 \u0432\u0441\u0442\u0430\u0432\u043A\u0438; intro: \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438 \u2014 \u0443 \u043D\u0435\u0451 \u044D\u0442\u043E \u043F\u043E\u043B\u0435 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E"
|
|
17356
|
-
).optional(),
|
|
17357
|
-
// ⚠ СЕКУНДА САМОЙ ЗАПИСИ, А НЕ СЕКУНДА РОЛИКА, И ПОЛЕ У НЕЁ СВОЁ. Окон
|
|
17358
|
-
// записи экрана в плане бывает несколько, и каждое следующее продолжает
|
|
17359
|
-
// предыдущее само (решение владельца 2026-09-18). Поле нужно там, где
|
|
17360
|
-
// продолжение не годится: «а тут покажи с середины». Имя то же, что у
|
|
17361
|
-
// слоя в плане наложений, — это одна и та же мысль, и второго имени для
|
|
17362
|
-
// неё быть не должно.
|
|
17363
|
-
file_start: external_exports.number().describe(
|
|
17364
|
-
"add: \u0441 \u043A\u0430\u043A\u043E\u0439 \u0441\u0435\u043A\u0443\u043D\u0434\u044B \u0421\u0410\u041C\u041E\u0419 \u0437\u0430\u043F\u0438\u0441\u0438 \u044D\u043A\u0440\u0430\u043D\u0430 \u0438\u0433\u0440\u0430\u0442\u044C \u044D\u0442\u043E \u043E\u043A\u043D\u043E. \u041D\u0435 \u043F\u0438\u0448\u0435\u0448\u044C \u2014 \u043E\u043A\u043D\u043E \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u0435\u0442 \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0435\u0435 \u0441 \u0442\u043E\u0433\u043E \u043C\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u043E\u043D\u043E \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u043B\u043E\u0441\u044C"
|
|
17365
|
-
).optional(),
|
|
17366
|
-
value: external_exports.string().describe(
|
|
17367
|
-
"hero: full|window|close-up|none; accent: accent|normal; text: \u043F\u043E\u0434\u043F\u0438\u0441\u044C; word: \u043A\u0430\u043A \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E; world: grid|file|none; part: on|off"
|
|
17368
|
-
).optional(),
|
|
17369
|
-
// ⚠ У ЭТИХ ДВУХ СТРОК ПЛАНА НЕТ ИМЕНИ ВСТАВКИ, ПОЭТОМУ И ПОЯВИЛОСЬ ОТДЕЛЬНОЕ
|
|
17370
|
-
// ПОЛЕ. Вставку человек убирает по её имени (`remove`, `chips-1`), а
|
|
17371
|
-
// субтитры и звуковые удары — это сами себе строка плана, целиком
|
|
17372
|
-
// (`engine/brief.py`, `PARTS`).
|
|
17373
|
-
what: external_exports.string().describe(
|
|
17374
|
-
"part: \u043A\u0430\u043A\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443 \u043F\u043B\u0430\u043D\u0430 \u0432\u044B\u0447\u0435\u0440\u043A\u043D\u0443\u0442\u044C \u0438\u043B\u0438 \u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u2014 subtitles | sfx"
|
|
17375
|
-
).optional(),
|
|
17376
|
-
// Движение вставки словами: канвы модель не знает, а движок знает — в
|
|
17377
|
-
// пиксели и секунды слова переводит шаг вставок по таблицам вкуса.
|
|
17378
|
-
enter: external_exports.string().describe(
|
|
17379
|
-
`motion, intro: \u043A\u0430\u043A \u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u0438\u043B\u0438 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u043F\u0440\u0438\u0445\u043E\u0434\u0438\u0442 \u2014 ${MOVES.join(" | ")}. fade \u2014 \u043F\u0440\u043E\u044F\u0432\u043B\u044F\u0435\u0442\u0441\u044F; up/down/left/right \u2014 \u0432\u044A\u0435\u0437\u0436\u0430\u0435\u0442 \u0441 \u044D\u0442\u043E\u0439 \u0441\u0442\u043E\u0440\u043E\u043D\u044B; pop \u2014 \u0432\u044B\u0441\u043A\u0430\u043A\u0438\u0432\u0430\u0435\u0442; cut \u2014 \u0440\u0435\u0437\u043E\u043C`
|
|
17380
|
-
).optional(),
|
|
17381
|
-
exit: external_exports.string().describe(
|
|
17382
|
-
`motion, intro: \u043A\u0430\u043A \u0443\u0445\u043E\u0434\u0438\u0442 \u2014 ${MOVES.join(" | ")}. \u0421\u0442\u043E\u0440\u043E\u043D\u0430 \u0442\u0443\u0442 \u0437\u043D\u0430\u0447\u0438\u0442, \u041A\u0423\u0414\u0410 \u0443\u0435\u0437\u0436\u0430\u0435\u0442: left \u2014 \u0432\u043B\u0435\u0432\u043E`
|
|
17383
|
-
).optional(),
|
|
17384
|
-
drift: external_exports.string().describe(
|
|
17385
|
-
`motion, intro: \u043C\u0435\u0434\u043B\u0435\u043D\u043D\u043E\u0435 \u0441\u043C\u0435\u0449\u0435\u043D\u0438\u0435 \u0437\u0430 \u0436\u0438\u0437\u043D\u044C \u0432\u0441\u0442\u0430\u0432\u043A\u0438 \u2014 ${DRIFTS.join(" | ")}; none \u2014 \u0441\u0442\u043E\u0438\u0442 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435`
|
|
17386
|
-
).optional(),
|
|
17387
|
-
speed: external_exports.string().describe(
|
|
17388
|
-
`motion, intro: \u0441\u043A\u043E\u0440\u043E\u0441\u0442\u044C \u0432\u0445\u043E\u0434\u0430 \u0438 \u0443\u0445\u043E\u0434\u0430 \u2014 ${SPEEDS.join(" | ")}. normal \u2014 \u043A\u0430\u043A \u0437\u0430\u043C\u0435\u0440\u0435\u043D\u043E`
|
|
17389
|
-
).optional(),
|
|
17390
|
-
slot: external_exports.string().describe(
|
|
17391
|
-
`motion, intro: \u0433\u0434\u0435 \u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u0441\u0442\u043E\u0438\u0442 \u043F\u043E \u0432\u0435\u0440\u0442\u0438\u043A\u0430\u043B\u0438 \u0432\u043D\u0443\u0442\u0440\u0438 \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0439 \u0440\u0430\u043C\u043A\u0438 \u2014 ${SLOTS.join(" | ")}`
|
|
17392
|
-
).optional(),
|
|
17393
|
-
// Карточка в начале ролика: её вторая строка, длительность и снятие.
|
|
17394
|
-
// ⚠ «text» СЛУЖИТ ДВУМ ОПЕРАЦИЯМ, и это не путаница: у `add` это подпись
|
|
17395
|
-
// новой вставки, у `intro` — заголовок карточки. Развести их вторым именем
|
|
17396
|
-
// значило бы завести модели два слова на одно и то же — «что написать».
|
|
17397
|
-
note: external_exports.string().describe(
|
|
17398
|
-
"intro: \u0432\u0442\u043E\u0440\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0438, \u043F\u043E\u043C\u0435\u043B\u044C\u0447\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430"
|
|
17399
|
-
).optional(),
|
|
17400
|
-
// ⚠ ЧИСЛО УМОЛЧАНИЯ ЗДЕСЬ НЕ НАЗЫВАЕТСЯ НАРОЧНО. Его дом один — «params»
|
|
17401
|
-
// паспорта шага (`steps/intro/step.json`), и покупатель вправе поправить
|
|
17402
|
-
// его в своей копии шага. Назови мы семёрку здесь — модель обещала бы её
|
|
17403
|
-
// тому, у кого стоит другое число.
|
|
17404
|
-
seconds: external_exports.number().describe(
|
|
17405
|
-
"intro: \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0435\u043A\u0443\u043D\u0434 \u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430. \u041D\u0435 \u043D\u0430\u0437\u0432\u0430\u043B \u2014 \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u0448\u0430\u0433\u0430"
|
|
17406
|
-
).optional(),
|
|
17407
|
-
off: external_exports.boolean().describe("intro: \u0443\u0431\u0440\u0430\u0442\u044C \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0443 \u0438\u0437 \u043D\u0430\u0447\u0430\u043B\u0430 \u0440\u043E\u043B\u0438\u043A\u0430").optional()
|
|
18286
|
+
return external_exports.looseObject({
|
|
18287
|
+
op: external_exports.string().describe(OPS.join(" | "))
|
|
17408
18288
|
});
|
|
17409
18289
|
}
|
|
17410
18290
|
function planEditTool(engine, key) {
|
|
17411
18291
|
return defineTool({
|
|
17412
18292
|
name: "plan_edit",
|
|
17413
|
-
title: "\u041F\u043E\u043F\u0440\u0430\u0432\u0438\u0442\u044C \
|
|
17414
|
-
description: "\u041F\u0440\u0430\u0432\u043A\u0430 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0430 \u0438 \u0443\u0436\u0435 \u0441\u043E\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E: \xAB\u043F\u043E\u043A\u0430\u0436\u0438 \u043C\u0435\u043D\u044F \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u0432\u043E\u0442 \u0442\u0443\u0442\xBB, \xAB\u0443\u0431\u0435\u0440\u0438 \u0441\u043F\u0438\u0441\u043E\u043A\xBB, \xAB\u0432 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0435 \u043D\u0435 \u0442\u043E \u0441\u043B\u043E\u0432\u043E\xBB, \xAB\u043F\u0443\u0441\u0442\u044C \u0432\u044B\u0435\u0437\u0436\u0430\u0435\u0442 \u0441\u043B\u0435\u0432\u0430\xBB, \xAB\u043F\u043E\u0434\u043F\u0438\u0448\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043F\u0443\u043D\u043A\u0442\xBB. \u041E\u0434\u043D\u0430 \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u2014 \u043E\u0434\u043D\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F; \u0441 rebuild \u0441\u0440\u0430\u0437\u0443 \u043F\u0435\u0440\u0435\u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442, \u0438 \u044D\u0442\u043E \u0441\u0442\u043E\u0438\u0442 \u0441\u0435\u043A\u0443\u043D\u0434, \u0430 \u043D\u0435 \u043C\u0438\u043D\u0443\u0442: \u0437\u0430\u043D\u043E\u0432\u043E \u0434\u0435\u043B\u0430\u0435\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u0442\u0440\u043E\u043D\u0443\u0442\u043E\u0435.\n\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438: hero (\u043A\u0440\u0443\u043F\u043D\u043E\u0441\u0442\u044C \u043D\u0430 \u043E\u0442\u0440\u0435\u0437\u043A\u0435 \u0441\u043B\u043E\u0432), remove, add, move, text (\u043F\u043E\u0434\u043F\u0438\u0441\u044C \u0432\u0441\u0442\u0430\u0432\u043A\u0438 \u0438\u043B\u0438 \u0435\u0451 \u043F\u0443\u043D\u043A\u0442\u0430), accent (\u0441\u043B\u043E\u0432\u043E \u043A\u0440\u0443\u043F\u043D\u0435\u0435 \u0432 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u0430\u0445), word (\u0438\u0441\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u043D\u043D\u043E\u0435 \u0441\u043B\u043E\u0432\u043E), world (\u0444\u043E\u043D \u0437\u0430 \u0433\u0435\u0440\u043E\u0435\u043C), motion (\u043A\u0430\u043A \u0432\u0441\u0442\u0430\u0432\u043A\u0430 \u043F\u0440\u0438\u0445\u043E\u0434\u0438\u0442, \u0443\u0445\u043E\u0434\u0438\u0442 \u0438 \u0433\u0434\u0435 \u0441\u0442\u043E\u0438\u0442), intro (\u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0432 \u043D\u0430\u0447\u0430\u043B\u0435 \u0440\u043E\u043B\u0438\u043A\u0430: text, note, seconds; \u0443\u0431\u0440\u0430\u0442\u044C \u2014 off; \u0441\u043B\u043E\u0432\u0430 \u0434\u0432\u0438\u0436\u0435\u043D\u0438\u044F \u0443 \u043D\u0435\u0451 \u0442\u0435 \u0436\u0435 \u2014 enter, exit, drift, speed, slot), part (\u0432\u044B\u0447\u0435\u0440\u043A\u043D\u0443\u0442\u044C \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u0441\u0442\u0440\u043E\u043A\u0443 \u043F\u043B\u0430\u043D\u0430, \u0443 \u043A\u043E\u0442\u043E\u0440\u043E\u0439 \u043D\u0435\u0442 \u0438\u043C\u0435\u043D\u0438 \u0432\u0441\u0442\u0430\u0432\u043A\u0438: what=subtitles|sfx, value=on|off \u2014 \xAB\u0431\u0435\u0437 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043E\u0432\xBB, \xAB\u0431\u0435\u0437 \u0437\u0432\u0443\u043A\u043E\u0432\u044B\u0445 \u0443\u0434\u0430\u0440\u043E\u0432\xBB).\nintro \u2014 \u0435\u0434\u0438\u043D\u0441\u0442\u0432\u0435\u043D\u043D\u0430\u044F \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F, \u043A\u043E\u0442\u043E\u0440\u0430\u044F \u041C\u0415\u041D\u042F\u0415\u0422 \u0414\u041B\u0418\u041D\u0423 \u0440\u043E\u043B\u0438\u043A\u0430: \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0432\u0441\u0442\u0430\u0451\u0442 \u041F\u0415\u0420\u0415\u0414 \u043D\u0438\u043C, \u0430 \u0441\u0430\u043C \u0440\u043E\u043B\u0438\u043A \u043E\u0441\u0442\u0430\u0451\u0442\u0441\u044F \u043A\u0430\u0434\u0440 \u0432 \u043A\u0430\u0434\u0440 \u043F\u0440\u0435\u0436\u043D\u0438\u043C. \u0420\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u0438 \u0432 \xAB\u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0430\u0443\u0437\u044B\xBB.\n\u041D\u043E\u043C\u0435\u0440\u0430 \u0441\u043B\u043E\u0432 \u0438 \u0438\u043C\u0435\u043D\u0430 \u0432\u0441\u0442\u0430\u0432\u043E\u043A \u0431\u0435\u0440\u0438 \u0418\u0417 \u0427\u0415\u0420\u041D\u041E\u0412\u0418\u041A\u0410 (plan \u0441 video). \u041D\u0435 \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u0438\u0445: \u043F\u0440\u0430\u0432\u043A\u0430 \u043C\u0438\u043C\u043E \u0446\u0435\u043B\u0438 \u0431\u0443\u0434\u0435\u0442 \u043E\u0442\u043A\u043B\u043E\u043D\u0435\u043D\u0430 \u0441\u043B\u043E\u0432\u0430\u043C\u0438.\nconfirm \u2014 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0441\u043A\u0430\u0437\u0430\u043B \xAB\u0434\u0430\xBB \u043D\u0430 \u043D\u044B\u043D\u0435\u0448\u043D\u044E\u044E \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u044E; \u0431\u0435\u0437 \u044D\u0442\u043E\u0433\u043E \u0441\u0431\u043E\u0440\u043A\u0430 \u043F\u043B\u0430\u043D \u043D\u0435 \u0432\u043E\u0437\u044C\u043C\u0451\u0442. \u041B\u042E\u0411\u0410\u042F \u043F\u0440\u0430\u0432\u043A\u0430 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0441\u043D\u0438\u043C\u0430\u0435\u0442, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 confirm \u0448\u043B\u0451\u0442\u0441\u044F \u0442\u0435\u043C \u0436\u0435 \u0432\u044B\u0437\u043E\u0432\u043E\u043C, \u0447\u0442\u043E \u0438 \u043F\u0440\u0430\u0432\u043A\u0430, \u2014 \u043F\u043E\u0441\u043B\u0435 \u0442\u043E\u0433\u043E \u043A\u0430\u043A \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0443\u0441\u043B\u044B\u0448\u0430\u043B, \u0447\u0442\u043E \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u043E\u0441\u044C.\nplan \u2014 \u0432\u0435\u0441\u044C \u043F\u043B\u0430\u043D \u0440\u043E\u043B\u0438\u043A\u0430 \u0446\u0435\u043B\u0438\u043A\u043E\u043C, \u043D\u0430\u043F\u0438\u0441\u0430\u043D\u043D\u044B\u0439 \u0442\u043E\u0431\u043E\u0439: \u0434\u0432\u0438\u0436\u043E\u043A \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442 \u0435\u0433\u043E \u043F\u043E \u0441\u0445\u0435\u043C\u0435 \u0438 \u043F\u043E \u043F\u043E\u0440\u043E\u0433\u0430\u043C \u0432\u043A\u0443\u0441\u0430 \u0438 \u043F\u0440\u0438 \u043D\u0430\u0440\u0443\u0448\u0435\u043D\u0438\u0438 \u043E\u0442\u043A\u0430\u0436\u0435\u0442 \u0441\u043B\u043E\u0432\u0430\u043C\u0438. \u0422\u0430\u043A \u0434\u0435\u043B\u0430\u044E\u0442, \u043A\u043E\u0433\u0434\u0430 \u043F\u0440\u0430\u0432\u043A\u0430\u043C\u0438 \u0443\u0436\u0435 \u043D\u0435 \u043E\u0431\u043E\u0439\u0442\u0438\u0441\u044C. draft \u2014 \u043E\u0431\u0440\u0430\u0442\u043D\u043E\u0435: \u0437\u0430\u0431\u044B\u0442\u044C \u0442\u0432\u043E\u0439 \u043F\u043B\u0430\u043D \u0438 \u0432\u0435\u0440\u043D\u0443\u0442\u044C\u0441\u044F \u043A \u043D\u0430\u0448\u0435\u043C\u0443 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0443. \u041F\u0440\u043E\u0441\u044C\u0431\u0430 \u0443\u0437\u043A\u0430\u044F (\xAB\u043F\u0440\u043E\u0441\u0442\u043E \u0443\u0441\u043A\u043E\u0440\u044C\xBB) \u2014 \u043F\u043B\u0430\u043D\u0430 \u043D\u0435 \u043F\u0438\u0448\u0438 \u0432\u043E\u0432\u0441\u0435, \u0438\u043D\u0430\u0447\u0435 \u0432 \u0440\u043E\u043B\u0438\u043A\u0435 \u043F\u043E\u044F\u0432\u0438\u0442\u0441\u044F \u0442\u043E, \u043E \u0447\u0451\u043C \u043D\u0438\u043A\u0442\u043E \u043D\u0435 \u043F\u0440\u043E\u0441\u0438\u043B.\nproject \u2014 \u0432\u0435\u0441\u044C \u043E\u0431\u0449\u0438\u0439 naparnik-project/1 \u0446\u0435\u043B\u0438\u043A\u043E\u043C. \u0414\u0432\u0438\u0436\u043E\u043A \u0441\u0430\u043C \u0438\u0437\u043C\u0435\u0440\u044F\u0435\u0442 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0438 \u0438 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442; \u043F\u043E\u0441\u043B\u0435 \u043F\u043E\u043A\u0430\u0437\u0430 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 confirm \u043F\u0440\u0438\u0432\u044F\u0437\u044B\u0432\u0430\u0435\u0442 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u043A \u0442\u043E\u0447\u043D\u043E\u0439 \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u0438 \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043C\u043E\u0441\u0442\u044F\u043C.\n\u0421\u043E step \u043F\u0440\u0430\u0432\u0438\u0442 \u043D\u0435 \u043F\u043B\u0430\u043D, \u0430 \u041F\u041E\u0420\u042F\u0414\u041E\u041A \u0428\u0410\u0413\u041E\u0412 \u043C\u043E\u043D\u0442\u0430\u0436\u0430: show \u2014 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0439, mine \u2014 \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0441\u0432\u043E\u044E \u043A\u043E\u043F\u0438\u044E \u043D\u0430\u0448\u0435\u0433\u043E, insert \u2014 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0441\u0432\u043E\u0439 \u0448\u0430\u0433 \u0434\u043E \u0438\u043B\u0438 \u043F\u043E\u0441\u043B\u0435 \u044D\u0442\u0430\u043F\u0430, replace \u2014 \u043F\u043E\u0434\u043C\u0435\u043D\u0438\u0442\u044C \u0448\u0430\u0433 \u0443 \u044D\u0442\u0430\u043F\u0430, remove \u2014 \u0443\u0431\u0440\u0430\u0442\u044C \u044D\u0442\u0430\u043F. \u041F\u0438\u0448\u0435\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u0432 \u043F\u0430\u043F\u043A\u0443 mine \u0434\u043E\u043C\u0430 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430: \u043D\u0430\u0448 \u043F\u043E\u0440\u044F\u0434\u043E\u043A \u043D\u0435 \u0442\u0440\u043E\u0433\u0430\u0435\u0442\u0441\u044F \u043D\u0438\u043A\u043E\u0433\u0434\u0430, \u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0434\u0432\u0438\u0436\u043A\u0430 \u0442\u0432\u043E\u044E \u043A\u043E\u043F\u0438\u044E \u043D\u0435 \u0437\u0430\u043C\u0435\u043D\u044F\u0435\u0442. \u0421\u0432\u043E\u0439 \u0448\u0430\u0433 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442\u0441\u044F \u043F\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043A\u0435 \u2014 \u0447\u0442\u043E \u0432 \u043D\u0451\u043C \u0447\u0438\u043D\u0438\u0442\u044C, \u0441\u043A\u0430\u0436\u0443\u0442 \u0441\u043B\u043E\u0432\u0430\u043C\u0438.",
|
|
18293
|
+
title: "\u041F\u043E\u043F\u0440\u0430\u0432\u0438\u0442\u044C \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0440\u043E\u043B\u0438\u043A\u0430",
|
|
18294
|
+
description: `\u041F\u0440\u0430\u0432\u043A\u0430 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0440\u043E\u043B\u0438\u043A\u0430 reel.json \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F\u043C\u0438 \u043F\u043E id \u2014 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u043D\u0435 \u043F\u0435\u0440\u0435\u043F\u0438\u0441\u044B\u0432\u0430\u0435\u0442\u0441\u044F. \u041E\u0434\u043D\u0430 \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u2014 \u043E\u0434\u043D\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F: \xAB\u0437\u0432\u0443\u043A\u0438 \u0433\u0440\u043E\u043C\u0447\u0435\xBB \u2014 \u043E\u0434\u043D\u0430 \u0441\u0442\u0440\u043E\u043A\u0430 {"op": "set", "target": "defaults", "path": "sound.gain", "value": 7}. \u041F\u0430\u0447\u043A\u0430 \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F \u0446\u0435\u043B\u0438\u043A\u043E\u043C \u0438\u043B\u0438 \u043D\u0438\u043A\u0430\u043A. \u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u2014 document/edits.md \u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430: ${OPS.join(", ")}.
|
|
18295
|
+
stamps \u2014 \u043F\u0435\u0447\u0430\u0442\u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0445 \u0441\u0442\u0440\u0430\u043D\u0438\u0446 (\xABdocument/clips.md@1a2b3c4d\xBB \u2014 \u043F\u0435\u0440\u0432\u0430\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u0432 \u043E\u0442\u0432\u0435\u0442\u0435 plan \u0441 read). \u041F\u0440\u0430\u0432\u043A\u0430 \u043A\u043B\u0438\u043F\u043E\u0432, \u043A\u043E\u0440\u043D\u044F, \u043E\u0431\u0449\u0435\u0433\u043E, \u0441\u0432\u043E\u0435\u0433\u043E \u043F\u0430\u043A\u0435\u0442\u0430 \u0438\u043B\u0438 \u0448\u0430\u0433\u0430 \u0431\u0435\u0437 \u043F\u0435\u0447\u0430\u0442\u0438 \u043E\u0442\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0438 \u043F\u0440\u0438\u043D\u043E\u0441\u0438\u0442 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0446\u0435\u043B\u0438\u043A\u043E\u043C: \u043F\u0440\u043E\u0447\u0442\u0438 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438 \u0432\u044B\u0437\u043E\u0432.
|
|
18296
|
+
\xAB\u0417\u0430\u043F\u043E\u043C\u043D\u0438\xBB, \xAB\u0432\u0441\u0435\u0433\u0434\u0430 \u0442\u0430\u043A\xBB \u2014 remember (\u0441\u0432\u043E\u0451 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430, work/remember.md): \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u043D\u0435 \u043C\u0435\u043D\u044F\u0435\u0442, \u043B\u043E\u0436\u0438\u0442\u0441\u044F \u0432 \u043A\u0430\u0436\u0434\u044B\u0439 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A; \u043F\u0435\u0447\u0430\u0442\u0438 \u043D\u0435 \u043D\u0443\u0436\u043D\u043E.
|
|
18297
|
+
\xAB\u0414\u0430\xBB \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u2014 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F {"op": "agree"}: \u0442\u0435\u043C \u0436\u0435 \u0432\u044B\u0437\u043E\u0432\u043E\u043C, \u0447\u0442\u043E \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043F\u0440\u0430\u0432\u043A\u0430, \u0438\u043B\u0438 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E; \u043F\u0435\u0447\u0430\u0442\u0438 \u0435\u0439 \u043D\u0435 \u043D\u0443\u0436\u043D\u043E. \u041B\u044E\u0431\u0430\u044F \u043F\u0440\u0430\u0432\u043A\u0430 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0441\u043D\u0438\u043C\u0430\u0435\u0442. \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u043F\u0440\u0430\u0432\u0438\u0442\u0441\u044F \u0422\u041E\u041B\u042C\u041A\u041E \u0437\u0434\u0435\u0441\u044C: \u0444\u0430\u0439\u043B, \u043F\u043E\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043D\u044B\u0439 \u043C\u0438\u043C\u043E plan_edit, \u043D\u0435 \u0441\u043E\u0433\u043B\u0430\u0441\u0443\u0435\u0442\u0441\u044F \u0438 \u043D\u0435 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F.
|
|
18298
|
+
rebuild \u2014 \u0441\u0440\u0430\u0437\u0443 \u0441\u043E\u0431\u0440\u0430\u0442\u044C \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442: \u043E\u0442\u0432\u0435\u0447\u0443 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438, \u0434\u0430\u043B\u044C\u0448\u0435 wait.
|
|
18299
|
+
\u0421\u043E step \u043F\u0440\u0430\u0432\u0438\u0442 \u043D\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442, \u0430 \u041F\u041E\u0420\u042F\u0414\u041E\u041A \u0428\u0410\u0413\u041E\u0412 \u0441\u0442\u0430\u0440\u043E\u0433\u043E \u043C\u043E\u043D\u0442\u0430\u0436\u0430: show, mine, insert, replace, remove. render \u043F\u043E \u044D\u0442\u043E\u043C\u0443 \u043F\u043E\u0440\u044F\u0434\u043A\u0443 \u041D\u0415 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442, \u0438 \u0440\u043E\u043B\u0438\u043A \u043E\u0442 step \u043D\u0435 \u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F. \u0421\u0432\u043E\u0439 \u044D\u0444\u0444\u0435\u043A\u0442 \u0432 \u0440\u043E\u043B\u0438\u043A\u0435 \u2014 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0435\u0439 set \u0441 uses: "mine:<\u0438\u043C\u044F>".`,
|
|
17415
18300
|
ui: { resourceUri: RUNBAR_RESOURCE_URI },
|
|
17416
18301
|
args: external_exports.object({
|
|
17417
18302
|
reel: external_exports.string().describe(
|
|
17418
18303
|
"\u041F\u0430\u043F\u043A\u0430 \u0440\u043E\u043B\u0438\u043A\u0430 \u0438\u043B\u0438 \u043F\u0443\u0442\u044C \u043A \u0432\u0438\u0434\u0435\u043E\u0444\u0430\u0439\u043B\u0443 \u2014 \u0447\u0442\u043E \u0435\u0441\u0442\u044C \u043F\u043E\u0434 \u0440\u0443\u043A\u043E\u0439"
|
|
17419
18304
|
).optional(),
|
|
17420
|
-
ops: external_exports.array(opSchema()).describe(
|
|
17421
|
-
|
|
17422
|
-
"\u041A\u0442\u043E \u0432\u043F\u0438\u0441\u0430\u043B \u043F\u0440\u0430\u0432\u043A\u0443. \xABmodel\xBB \u2014 \u0442\u044B \u0441\u0430\u043C \u0437\u0430\u043A\u0440\u044B\u043B \u043F\u0443\u0441\u0442\u043E\u0439 \u0441\u043B\u043E\u0442 \u043F\u043E\u0434\u043F\u0438\u0441\u0438; \xABhuman\xBB \u2014 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u043F\u043E\u043F\u0440\u043E\u0441\u0438\u043B \u0441\u043B\u043E\u0432\u0430\u043C\u0438. \u0423\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u2014 model"
|
|
17423
|
-
).optional(),
|
|
17424
|
-
rebuild: external_exports.boolean().describe(
|
|
17425
|
-
"\u0421\u0440\u0430\u0437\u0443 \u043F\u0435\u0440\u0435\u0441\u043E\u0431\u0440\u0430\u0442\u044C \u0440\u043E\u043B\u0438\u043A. \u041E\u0442\u0432\u0435\u0447\u0443 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438, \u0434\u0430\u043B\u044C\u0448\u0435 wait"
|
|
17426
|
-
).optional(),
|
|
17427
|
-
confirm: external_exports.boolean().describe(
|
|
17428
|
-
"\u0427\u0435\u043B\u043E\u0432\u0435\u043A \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043B \u043D\u044B\u043D\u0435\u0448\u043D\u044E\u044E \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u044E \u043F\u043B\u0430\u043D\u0430. \u041B\u044E\u0431\u0430\u044F \u043F\u0440\u0430\u0432\u043A\u0430 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0441\u043D\u0438\u043C\u0430\u0435\u0442 \u2014 \u0448\u043B\u0438 \u044D\u0442\u0438\u043C \u0436\u0435 \u0432\u044B\u0437\u043E\u0432\u043E\u043C, \u0447\u0442\u043E \u0438 \u043F\u0440\u0430\u0432\u043A\u0443"
|
|
18305
|
+
ops: external_exports.array(opSchema()).describe(
|
|
18306
|
+
'\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0438 \u043F\u043E \u043F\u043E\u0440\u044F\u0434\u043A\u0443; \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u2014 {"op": "agree"}'
|
|
17429
18307
|
).optional(),
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
// единственный судья: проверяет по схеме и по порогам брака таблиц вкуса.
|
|
17433
|
-
// Перепиши мы состав плана сюда — у договора появилась бы вторая правда,
|
|
17434
|
-
// которая расходится с первой молча, а узнаёт об этом человек собранным
|
|
17435
|
-
// роликом. Поля свободные, а отказ приходит от того, кто план исполняет.
|
|
17436
|
-
plan: external_exports.looseObject({}).describe(
|
|
17437
|
-
"\u0412\u0415\u0421\u042C \u043F\u043B\u0430\u043D \u0440\u043E\u043B\u0438\u043A\u0430 \u0446\u0435\u043B\u0438\u043A\u043E\u043C, \u043D\u0430\u043F\u0438\u0441\u0430\u043D\u043D\u044B\u0439 \u0442\u043E\u0431\u043E\u0439, \u2014 \u0434\u043E\u0433\u043E\u0432\u043E\u0440 naparnik-plan/1. \u0427\u0438\u0441\u043B\u0430 \u0431\u0435\u0440\u0438 \u0438\u0437 \u0442\u0430\u0431\u043B\u0438\u0446 \u0432\u043A\u0443\u0441\u0430 (plan \u0441 read), \u0430 \u043D\u0435 \u0438\u0437 \u0433\u043E\u043B\u043E\u0432\u044B: \u0434\u0432\u0438\u0436\u043E\u043A \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442 \u043F\u043B\u0430\u043D \u0438 \u043E\u0442\u043A\u0430\u0436\u0435\u0442 \u0441\u043B\u043E\u0432\u0430\u043C\u0438, \u043D\u0430\u0437\u0432\u0430\u0432, \u0447\u0442\u043E \u043D\u0430\u0440\u0443\u0448\u0435\u043D\u043E \u0438 \u043A\u0430\u043A\u0430\u044F \u043D\u043E\u0440\u043C\u0430"
|
|
18308
|
+
stamps: external_exports.array(external_exports.string()).describe(
|
|
18309
|
+
"\u041F\u0435\u0447\u0430\u0442\u0438 \u0441\u0442\u0440\u0430\u043D\u0438\u0446 \u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430, \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u043D\u043D\u044B\u0445 \u0432 \u044D\u0442\u043E\u043C \u0440\u0430\u0437\u0433\u043E\u0432\u043E\u0440\u0435: \xAB\u043F\u0443\u0442\u044C@\u043A\u043E\u0434\xBB"
|
|
17438
18310
|
).optional(),
|
|
17439
|
-
|
|
17440
|
-
"\
|
|
18311
|
+
by: external_exports.enum(["model", "human"]).describe(
|
|
18312
|
+
"\u041A\u0442\u043E \u043F\u0440\u0430\u0432\u0438\u0442 \u0438 \u043A\u0442\u043E \u0441\u043A\u0430\u0437\u0430\u043B \xAB\u0434\u0430\xBB: model \u2014 \u0442\u044B \u0441 \u0435\u0433\u043E \u0441\u043B\u043E\u0432, human \u2014 \u043E\u043D \u0441\u0430\u043C. \u0423\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u2014 model"
|
|
17441
18313
|
).optional(),
|
|
17442
|
-
|
|
17443
|
-
"\
|
|
18314
|
+
rebuild: external_exports.boolean().describe(
|
|
18315
|
+
"\u0421\u0440\u0430\u0437\u0443 \u0441\u043E\u0431\u0440\u0430\u0442\u044C \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u043F\u043E\u0441\u043B\u0435 \u043F\u0440\u0430\u0432\u043A\u0438. \u041E\u0442\u0432\u0435\u0447\u0443 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438, \u0434\u0430\u043B\u044C\u0448\u0435 wait"
|
|
17444
18316
|
).optional(),
|
|
17445
18317
|
step: external_exports.enum(["show", "mine", "insert", "remove", "replace"]).describe(
|
|
17446
|
-
"\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u041F\u041E\u0420\u042F\u0414\u041A\u041E\u041C \u0428\u0410\u0413\u041E\u0412 \u043C\u043E\u043D\u0442\u0430\u0436\u0430, \u0430 \u043D\u0435 \u0441 \
|
|
18318
|
+
"\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u041F\u041E\u0420\u042F\u0414\u041A\u041E\u041C \u0428\u0410\u0413\u041E\u0412 \u043C\u043E\u043D\u0442\u0430\u0436\u0430, \u0430 \u043D\u0435 \u0441 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u043C \u0440\u043E\u043B\u0438\u043A\u0430"
|
|
17447
18319
|
).optional(),
|
|
17448
18320
|
name: external_exports.string().describe(
|
|
17449
18321
|
'\u0418\u043C\u044F \u0428\u0410\u0413\u0410, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u0442\u0430\u0432\u0438\u043C (\u0434\u043B\u044F step="insert"). \u041E\u0434\u043D\u043E \u0441\u043B\u043E\u0432\u043E \u2014 \u0442\u0430\u043A, \u043A\u0430\u043A \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u0435\u0433\u043E \u043F\u0430\u043F\u043A\u0430 \u0432 mine/steps'
|
|
@@ -17462,54 +18334,31 @@ function planEditTool(engine, key) {
|
|
|
17462
18334
|
const say = (message, where) => {
|
|
17463
18335
|
ctx.issues.push({ code: "custom", message, input: asked, path: [where] });
|
|
17464
18336
|
};
|
|
17465
|
-
const
|
|
17466
|
-
if (asked.step !== void 0
|
|
17467
|
-
|
|
17468
|
-
`\xABstep\xBB \u043F\u0440\u0430\u0432\u0438\u0442 \u043F\u043E\u0440\u044F\u0434\u043E\u043A \u0448\u0430\u0433\u043E\u0432 \u043C\u043E\u043D\u0442\u0430\u0436\u0430, \u0430 \u043D\u0435 \u043F\u043B\u0430\u043D \u0440\u043E\u043B\u0438\u043A\u0430 \u2014 \u043B\u0438\u0448\u043D\u0435\u0435: ${planKeys.join(", ")}. \u041F\u043E\u0437\u043E\u0432\u0438 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E`,
|
|
17469
|
-
"step"
|
|
17470
|
-
);
|
|
17471
|
-
return;
|
|
17472
|
-
}
|
|
17473
|
-
if (asked.step === void 0) {
|
|
17474
|
-
const stepKeys = STEP_KEYS.filter((key2) => asked[key2] !== void 0);
|
|
17475
|
-
if (stepKeys.length > 0) {
|
|
18337
|
+
const editKeys = ["reel", "ops", "stamps", "by", "rebuild"].filter((key2) => asked[key2] !== void 0);
|
|
18338
|
+
if (asked.step !== void 0) {
|
|
18339
|
+
if (editKeys.length > 0) {
|
|
17476
18340
|
say(
|
|
17477
|
-
`\
|
|
18341
|
+
`\xABstep\xBB \u043F\u0440\u0430\u0432\u0438\u0442 \u043F\u043E\u0440\u044F\u0434\u043E\u043A \u0448\u0430\u0433\u043E\u0432 \u043C\u043E\u043D\u0442\u0430\u0436\u0430, \u0430 \u043D\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0440\u043E\u043B\u0438\u043A\u0430 \u2014 \u043B\u0438\u0448\u043D\u0435\u0435: ${editKeys.join(", ")}. \u041F\u043E\u0437\u043E\u0432\u0438 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E`,
|
|
17478
18342
|
"step"
|
|
17479
18343
|
);
|
|
17480
18344
|
}
|
|
17481
|
-
|
|
17482
|
-
|
|
17483
|
-
|
|
17484
|
-
|
|
17485
|
-
|
|
17486
|
-
|
|
17487
|
-
|
|
17488
|
-
|
|
17489
|
-
|
|
17490
|
-
|
|
17491
|
-
|
|
17492
|
-
|
|
17493
|
-
|
|
17494
|
-
|
|
17495
|
-
|
|
17496
|
-
|
|
17497
|
-
|
|
17498
|
-
}
|
|
17499
|
-
const asking = [
|
|
17500
|
-
asked.ops !== void 0 ? "ops" : "",
|
|
17501
|
-
asked.plan !== void 0 ? "plan" : "",
|
|
17502
|
-
asked.project !== void 0 ? "project" : "",
|
|
17503
|
-
asked.confirm === true ? "confirm" : "",
|
|
17504
|
-
asked.draft === true ? "draft" : "",
|
|
17505
|
-
asked.rebuild === true ? "rebuild" : ""
|
|
17506
|
-
].filter((one) => one !== "");
|
|
17507
|
-
if (asking.length === 0) {
|
|
17508
|
-
say(
|
|
17509
|
-
"\u0414\u0435\u043B\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E: \u043D\u0438 \u043F\u0440\u0430\u0432\u043E\u043A, \u043D\u0438 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u044F. \xABops\xBB \u2014 \u043F\u0440\u0430\u0432\u043A\u0438 \u043F\u043B\u0430\u043D\u0430, \xABplan\xBB \u2014 \u0432\u0435\u0441\u044C \u043F\u043B\u0430\u043D \u0440\u043E\u043B\u0438\u043A\u0430 \u0446\u0435\u043B\u0438\u043A\u043E\u043C, \xABconfirm\xBB \u2014 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0441\u043A\u0430\u0437\u0430\u043B \xAB\u0434\u0430\xBB \u043D\u0430 \u043D\u044B\u043D\u0435\u0448\u043D\u044E\u044E \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u044E, \xABdraft\xBB \u2014 \u0432\u0435\u0440\u043D\u0443\u0442\u044C \u043D\u0430\u0448 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A. \u041F\u043E\u0440\u044F\u0434\u043E\u043A \u0448\u0430\u0433\u043E\u0432 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043F\u0440\u0430\u0432\u0438\u0442\u0441\u044F \u043A\u043B\u044E\u0447\u043E\u043C \xABstep\xBB",
|
|
17510
|
-
"ops"
|
|
17511
|
-
);
|
|
17512
|
-
}
|
|
18345
|
+
return;
|
|
18346
|
+
}
|
|
18347
|
+
const stepKeys = STEP_KEYS.filter((key2) => asked[key2] !== void 0);
|
|
18348
|
+
if (stepKeys.length > 0) {
|
|
18349
|
+
say(`\xAB${stepKeys.join(", ")}\xBB \u043E\u0442\u043D\u043E\u0441\u044F\u0442\u0441\u044F \u043A \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044E \u0441\u043E \u0441\u0432\u043E\u0438\u043C \u0448\u0430\u0433\u043E\u043C \u2014 \u043D\u0430\u0437\u043E\u0432\u0438 \xABstep\xBB`, "step");
|
|
18350
|
+
}
|
|
18351
|
+
if (asked.reel === void 0) {
|
|
18352
|
+
say(
|
|
18353
|
+
"\u041D\u0435 \u0437\u0430\u0434\u0430\u043D \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0439 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442 \xABreel\xBB: \u043F\u0440\u0430\u0432\u043A\u0430 \u2014 \u044D\u0442\u043E \u0440\u043E\u043B\u0438\u043A \u0438 \u0442\u043E, \u0447\u0442\u043E \u0441 \u043D\u0438\u043C \u0434\u0435\u043B\u0430\u0435\u043C. \u041F\u043E\u0440\u044F\u0434\u043E\u043A \u0448\u0430\u0433\u043E\u0432 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043F\u0440\u0430\u0432\u0438\u0442\u0441\u044F \u043A\u043B\u044E\u0447\u043E\u043C \xABstep\xBB",
|
|
18354
|
+
"reel"
|
|
18355
|
+
);
|
|
18356
|
+
}
|
|
18357
|
+
if (asked.ops === void 0 || asked.ops.length === 0) {
|
|
18358
|
+
say(
|
|
18359
|
+
'\u0414\u0435\u043B\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E: \u043D\u0435\u0442 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0439. \u041F\u0440\u0430\u0432\u043A\u0430 \u2014 ops \u0441\u043E \u0441\u043F\u0438\u0441\u043A\u043E\u043C \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0439, \xAB\u0434\u0430\xBB \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u2014 [{"op": "agree"}]. \u041F\u043E\u0440\u044F\u0434\u043E\u043A \u0448\u0430\u0433\u043E\u0432 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043F\u0440\u0430\u0432\u0438\u0442\u0441\u044F \u043A\u043B\u044E\u0447\u043E\u043C \xABstep\xBB',
|
|
18360
|
+
"ops"
|
|
18361
|
+
);
|
|
17513
18362
|
}
|
|
17514
18363
|
}),
|
|
17515
18364
|
async execute(args, ctx) {
|
|
@@ -17522,352 +18371,21 @@ function planEditTool(engine, key) {
|
|
|
17522
18371
|
with: args.with
|
|
17523
18372
|
});
|
|
17524
18373
|
}
|
|
17525
|
-
return
|
|
18374
|
+
return editDocument(
|
|
17526
18375
|
engine,
|
|
17527
18376
|
{
|
|
17528
18377
|
reel: args.reel ?? "",
|
|
17529
18378
|
ops: args.ops ?? [],
|
|
18379
|
+
stamps: args.stamps,
|
|
17530
18380
|
by: args.by,
|
|
17531
|
-
rebuild: args.rebuild
|
|
17532
|
-
confirm: args.confirm,
|
|
17533
|
-
plan: args.plan,
|
|
17534
|
-
project: args.project,
|
|
17535
|
-
draft: args.draft
|
|
17536
|
-
},
|
|
17537
|
-
key,
|
|
17538
|
-
ctx?.emitProgress
|
|
17539
|
-
);
|
|
17540
|
-
}
|
|
17541
|
-
});
|
|
17542
|
-
}
|
|
17543
|
-
function universalOptions(asked) {
|
|
17544
|
-
const found = /* @__PURE__ */ new Set();
|
|
17545
|
-
const known = [
|
|
17546
|
-
["only_pauses", asked.onlyPauses],
|
|
17547
|
-
["style", asked.style],
|
|
17548
|
-
["preset", asked.preset],
|
|
17549
|
-
["model", asked.model],
|
|
17550
|
-
["tempo", asked.tempo],
|
|
17551
|
-
["keep_pauses", asked.keepPauses],
|
|
17552
|
-
["redo", asked.redo],
|
|
17553
|
-
["from_scratch", asked.fromScratch],
|
|
17554
|
-
["even_without_speech", asked.evenWithoutSpeech]
|
|
17555
|
-
];
|
|
17556
|
-
for (const [name, value] of known) {
|
|
17557
|
-
if (value !== void 0) found.add(name);
|
|
17558
|
-
}
|
|
17559
|
-
for (const [name, value] of Object.entries(asked.args ?? {})) {
|
|
17560
|
-
if (name !== "reel" && value !== void 0) found.add(name);
|
|
17561
|
-
}
|
|
17562
|
-
return [...found].sort();
|
|
17563
|
-
}
|
|
17564
|
-
async function startRender(engine, asked, passport, key, tell) {
|
|
17565
|
-
const place = engine.place();
|
|
17566
|
-
if (place === null) return toolError(engine.whyNoEngine());
|
|
17567
|
-
const where = fileOrRefusal(asked.video);
|
|
17568
|
-
if ("refusal" in where) return toolError(where.refusal);
|
|
17569
|
-
if (asked.reel === true) {
|
|
17570
|
-
const viewed = await engine.command([
|
|
17571
|
-
"composition-view",
|
|
17572
|
-
"--project",
|
|
17573
|
-
path(where.path),
|
|
17574
|
-
"--json"
|
|
17575
|
-
]);
|
|
17576
|
-
if (!viewed.ok) return toolError(viewed.text);
|
|
17577
|
-
try {
|
|
17578
|
-
const lines = viewed.text.trim().split("\n");
|
|
17579
|
-
const answer = JSON.parse(lines[lines.length - 1] ?? "{}");
|
|
17580
|
-
if (answer.universal === true) {
|
|
17581
|
-
const extra = universalOptions(asked);
|
|
17582
|
-
if (extra.length > 0) {
|
|
17583
|
-
return toolError(
|
|
17584
|
-
`\u041E\u0431\u0449\u0438\u0439 naparnik-project/1 \u0443\u0436\u0435 \u0445\u0440\u0430\u043D\u0438\u0442 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u0432 \u0441\u0430\u043C\u043E\u043C project, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 render \u043D\u0435 \u043F\u0440\u0438\u043C\u0435\u043D\u0438\u0442 \u043A \u043D\u0435\u043C\u0443 legacy-\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B: ${extra.join(", ")}.
|
|
17585
|
-
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0432\u043D\u0435\u0441\u0438 \u044D\u0442\u0438 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432 project \u0447\u0435\u0440\u0435\u0437 plan_edit \u0438 \u043F\u043E\u0437\u043E\u0432\u0438 render \u0442\u043E\u043B\u044C\u043A\u043E \u0441 reel.`
|
|
17586
|
-
);
|
|
17587
|
-
}
|
|
17588
|
-
return startComposition(engine, where.path, key, tell);
|
|
17589
|
-
}
|
|
17590
|
-
} catch {
|
|
17591
|
-
return toolError(
|
|
17592
|
-
"\u0414\u0432\u0438\u0436\u043E\u043A \u043D\u0435 \u0441\u043C\u043E\u0433 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0438\u0442\u044C \u0432\u0438\u0434 \u043F\u0440\u043E\u0435\u043A\u0442\u0430. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043E\u0431\u043D\u043E\u0432\u0438 \u043D\u0430\u0447\u0438\u043D\u043A\u0443 \u0447\u0435\u0440\u0435\u0437 setup."
|
|
17593
|
-
);
|
|
17594
|
-
}
|
|
17595
|
-
}
|
|
17596
|
-
const onlyPauses = asked.onlyPauses === true;
|
|
17597
|
-
const line = onlyPauses ? ["--without-subs"] : [];
|
|
17598
|
-
if (asked.style !== void 0) line.push("--style", path(asked.style));
|
|
17599
|
-
if (asked.preset !== void 0) line.push("--preset", asked.preset);
|
|
17600
|
-
if (asked.model !== void 0) line.push("--model", asked.model);
|
|
17601
|
-
if (asked.tempo !== void 0 && asked.tempo !== 1) line.push("--tempo", String(asked.tempo));
|
|
17602
|
-
if (asked.keepPauses === true) line.push("--keep-pauses");
|
|
17603
|
-
if (asked.fromScratch === true) line.push("--afresh");
|
|
17604
|
-
if (asked.evenWithoutSpeech === true) line.push("--anyway");
|
|
17605
|
-
if (asked.redo !== void 0 && asked.redo.length > 0) line.push("--only", ...asked.redo);
|
|
17606
|
-
line.push(...readCapabilities(asked.args ?? {}, passport));
|
|
17607
|
-
const what = onlyPauses ? `\u043F\u0430\u0443\u0437\u044B ${basename(where.path)}` : `\u043C\u043E\u043D\u0442\u0430\u0436 ${basename(where.path)}`;
|
|
17608
|
-
return startMontage(engine, {
|
|
17609
|
-
key,
|
|
17610
|
-
place,
|
|
17611
|
-
...onlyPauses ? { ladder: PAUSES_LADDER } : {},
|
|
17612
|
-
...tell !== void 0 ? { tell } : {},
|
|
17613
|
-
video: where.path,
|
|
17614
|
-
what,
|
|
17615
|
-
// ⚠ КЛЮЧИ ЭТОГО СЛОВАРЯ — ДВИЖКОВЫЕ, И ПЕРЕИМЕНОВЫВАТЬ ИХ НЕЛЬЗЯ. По ним
|
|
17616
|
-
// движок узнаёт повторный вызов с той же настройкой — то самое «повторный
|
|
17617
|
-
// монтаж почти ничего не считает». Имя инструмента тут прежнее (`montage`,
|
|
17618
|
-
// `cut_pauses`) нарочно: смени его — и каждое задание выглядело бы новым, а
|
|
17619
|
-
// кэш перестал бы срабатывать молча.
|
|
17620
|
-
command: onlyPauses ? { "tool": "cut_pauses", "args": { style: asked.style, tempo: asked.tempo } } : {
|
|
17621
|
-
"tool": "montage",
|
|
17622
|
-
"args": {
|
|
17623
|
-
style: asked.style,
|
|
17624
|
-
preset: asked.preset,
|
|
17625
|
-
model: asked.model,
|
|
17626
|
-
tempo: asked.tempo,
|
|
17627
|
-
keep_pauses: asked.keepPauses === true
|
|
17628
|
-
}
|
|
17629
|
-
},
|
|
17630
|
-
...asked.style !== void 0 ? { style: path(asked.style) } : {},
|
|
17631
|
-
args: line,
|
|
17632
|
-
hint: onlyPauses ? "\u0411\u044B\u0441\u0442\u0440\u043E, \u043E\u0431\u044B\u0447\u043D\u043E \u043C\u0435\u043D\u044C\u0448\u0435 \u043C\u0438\u043D\u0443\u0442\u044B." : "\u041F\u0435\u0440\u0432\u044B\u0439 \u0440\u0430\u0437 \u2014 \u043C\u0438\u043D\u0443\u0442\u044B; \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u044B\u0439 \u0441 \u0442\u043E\u0439 \u0436\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u043E\u0439 \u2014 \u0441\u0435\u043A\u0443\u043D\u0434\u044B."
|
|
17633
|
-
});
|
|
17634
|
-
}
|
|
17635
|
-
async function startComposition(engine, reel, key, tell) {
|
|
17636
|
-
const place = engine.place();
|
|
17637
|
-
if (place === null) return toolError(engine.whyNoEngine());
|
|
17638
|
-
const trouble = await engine.pythonTrouble();
|
|
17639
|
-
if (trouble !== null) return toolError(trouble);
|
|
17640
|
-
const python = engine.packPython();
|
|
17641
|
-
if (python === null) {
|
|
17642
|
-
return toolError("\u041E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 setup.");
|
|
17643
|
-
}
|
|
17644
|
-
if (tell !== void 0) {
|
|
17645
|
-
tell("\u041F\u0440\u043E\u0432\u0435\u0440\u044E \u0442\u043E\u0447\u043D\u0443\u044E \u0440\u0435\u0434\u0430\u043A\u0446\u0438\u044E \u043F\u0440\u043E\u0435\u043A\u0442\u0430 \u0438 \u0435\u0433\u043E \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0438.");
|
|
17646
|
-
tell("\u0421\u043E\u0431\u0435\u0440\u0443 \u044D\u0444\u0444\u0435\u043A\u0442\u044B, \u0432\u0438\u0434\u0435\u043E \u0438 \u0437\u0432\u0443\u043A \u043F\u043E \u043E\u0431\u0449\u0435\u0439 \u043A\u043E\u043C\u043F\u043E\u0437\u0438\u0446\u0438\u0438.");
|
|
17647
|
-
}
|
|
17648
|
-
const launch = await engine.background({
|
|
17649
|
-
place,
|
|
17650
|
-
executable: python,
|
|
17651
|
-
key,
|
|
17652
|
-
startJob: [
|
|
17653
|
-
"job-create",
|
|
17654
|
-
"--video",
|
|
17655
|
-
reel,
|
|
17656
|
-
"--composition",
|
|
17657
|
-
"--what",
|
|
17658
|
-
`\u043C\u043E\u043D\u0442\u0430\u0436 ${basename(reel)}`,
|
|
17659
|
-
"--command",
|
|
17660
|
-
JSON.stringify({ tool: "composition", args: {} })
|
|
17661
|
-
],
|
|
17662
|
-
args: (id) => [
|
|
17663
|
-
place.consolePy,
|
|
17664
|
-
"composition-render",
|
|
17665
|
-
"--project",
|
|
17666
|
-
reel,
|
|
17667
|
-
"--job",
|
|
17668
|
-
id
|
|
17669
|
-
],
|
|
17670
|
-
advice: "\u043F\u043E\u0437\u043E\u0432\u0438 setup \u2014 \u0441\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043D\u0435\u043F\u043E\u043B\u043D\u043E\u0435"
|
|
17671
|
-
});
|
|
17672
|
-
if ("refusal" in launch) return toolError(launch.refusal);
|
|
17673
|
-
return toolSuccess(
|
|
17674
|
-
`\u0417\u0430\u0434\u0430\u0447\u0430 ${launch.id}: \u043C\u043E\u043D\u0442\u0430\u0436 ${basename(reel)}
|
|
17675
|
-
\u0414\u0430\u043B\u044C\u0448\u0435 \u043F\u043E\u0437\u043E\u0432\u0438 wait \u0441 \u044D\u0442\u0438\u043C \u043D\u043E\u043C\u0435\u0440\u043E\u043C.`,
|
|
17676
|
-
startedJob({
|
|
17677
|
-
id: launch.id,
|
|
17678
|
-
what: `\u043C\u043E\u043D\u0442\u0430\u0436 ${basename(reel)}`,
|
|
17679
|
-
ahead: "\u041F\u0440\u043E\u0432\u0435\u0440\u044E \u043F\u0440\u043E\u0435\u043A\u0442. \u0421\u043E\u0431\u0435\u0440\u0443 \u044D\u0444\u0444\u0435\u043A\u0442\u044B, \u0432\u0438\u0434\u0435\u043E \u0438 \u0437\u0432\u0443\u043A.",
|
|
17680
|
-
message: "\u041E\u0431\u0449\u0438\u0439 \u043F\u0440\u043E\u0435\u043A\u0442 \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F."
|
|
17681
|
-
})
|
|
17682
|
-
);
|
|
17683
|
-
}
|
|
17684
|
-
async function followWork(engine, asked, pace = realPace, tell) {
|
|
17685
|
-
const ask2 = () => engine.command(["job", asked.job]);
|
|
17686
|
-
const seconds2 = waitSeconds(asked.seconds ?? WAIT_LIMIT_SECONDS);
|
|
17687
|
-
if (seconds2 === 0) return asJobResult(await ask2());
|
|
17688
|
-
const state = await followJob({
|
|
17689
|
-
ask: ask2,
|
|
17690
|
-
seconds: seconds2,
|
|
17691
|
-
pace,
|
|
17692
|
-
// ⚠ Рассказ есть только если КЛИЕНТ его попросил (токен хода работы в
|
|
17693
|
-
// `_meta`). Нет — ждём молча и отвечаем итогом: ждать всё равно дешевле
|
|
17694
|
-
// пяти кругов переписки «спроси ещё раз».
|
|
17695
|
-
...tell !== void 0 ? { tell } : {}
|
|
17696
|
-
});
|
|
17697
|
-
if (state.ok && stillWorking(state.text)) {
|
|
17698
|
-
const words = `${state.text}
|
|
17699
|
-
\u0416\u0434\u0430\u043B ${seconds2} \u0441, \u0440\u0430\u0431\u043E\u0442\u0430 \u0435\u0449\u0451 \u0438\u0434\u0451\u0442. \u0421\u043A\u0430\u0436\u0438 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0438 \u043F\u043E\u0437\u043E\u0432\u0438 wait \u0435\u0449\u0451 \u0440\u0430\u0437 \u2014 \u0442\u0430\u043A \u043E\u043D \u0443\u0441\u043B\u044B\u0448\u0438\u0442 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0435 \u0448\u0430\u0433\u0438.`;
|
|
17700
|
-
const job = readJob(state.text);
|
|
17701
|
-
return job === null ? toolSuccess(words) : toolSuccess(words, job);
|
|
17702
|
-
}
|
|
17703
|
-
return asJobResult(state);
|
|
17704
|
-
}
|
|
17705
|
-
async function listJobs(engine, asked) {
|
|
17706
|
-
return asToolResult(
|
|
17707
|
-
await engine.command([
|
|
17708
|
-
"jobs",
|
|
17709
|
-
...asked.video !== void 0 ? ["--video", path(asked.video)] : [],
|
|
17710
|
-
...asked.limit !== void 0 ? ["--count", String(asked.limit)] : []
|
|
17711
|
-
])
|
|
17712
|
-
);
|
|
17713
|
-
}
|
|
17714
|
-
function renderDeclared(passport) {
|
|
17715
|
-
return external_exports.object({
|
|
17716
|
-
video: external_exports.string().describe(
|
|
17717
|
-
"\u041F\u0443\u0442\u044C \u043A \u0432\u0438\u0434\u0435\u043E\u0444\u0430\u0439\u043B\u0443 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430. \u0417\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u044B\u0439 \u0440\u043E\u043B\u0438\u043A \u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0437\u0432\u0430\u0442\u044C \u0438 \u043F\u0430\u043F\u043A\u043E\u0439 \u2014 \u043A\u043B\u044E\u0447\u043E\u043C reel"
|
|
17718
|
-
).optional(),
|
|
17719
|
-
reel: external_exports.string().describe(
|
|
17720
|
-
"\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430. \u0422\u043E \u0436\u0435, \u0447\u0442\u043E video, \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043B\u044F \u0440\u043E\u043B\u0438\u043A\u0430 \u0446\u0435\u043B\u0438\u043A\u043E\u043C: \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u0438, \u0431\u0440\u0438\u0444 \u0438 \u043F\u0440\u0430\u0432\u043A\u0438 \u043F\u043B\u0430\u043D\u0430 \u0434\u0432\u0438\u0436\u043E\u043A \u0432\u043E\u0437\u044C\u043C\u0451\u0442 \u0438\u0437 \u043D\u0435\u0451 \u0441\u0430\u043C"
|
|
17721
|
-
).optional(),
|
|
17722
|
-
only_pauses: external_exports.boolean().describe(
|
|
17723
|
-
"\u0422\u043E\u043B\u044C\u043A\u043E \u0443\u0431\u0440\u0430\u0442\u044C \u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u0438 \u0437\u0430\u043F\u0438\u043D\u043A\u0438. \u0420\u0435\u0447\u044C \u043F\u0440\u0438 \u044D\u0442\u043E\u043C \u041D\u0415 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0451\u0442\u0441\u044F \u0438 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0430 \u043D\u0435\u0442: \u0447\u0435\u043B\u043E\u0432\u0435\u043A, \u043F\u043E\u043F\u0440\u043E\u0441\u0438\u0432\u0448\u0438\u0439 \xAB\u043F\u0440\u043E\u0441\u0442\u043E \u0443\u0431\u0435\u0440\u0438 \u0442\u0438\u0448\u0438\u043D\u0443\xBB, \u043D\u0435 \u0436\u0434\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u044B \u0438 \u043D\u0435 \u043A\u0430\u0447\u0430\u0435\u0442 \u043F\u043E\u043B\u0442\u043E\u0440\u0430 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442\u0430. \u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044B \u0438 \u0433\u0440\u0430\u0444\u0438\u043A\u0443 \u044D\u0442\u0438\u043C \u043D\u0435 \u0441\u043E\u0431\u0440\u0430\u0442\u044C"
|
|
17724
|
-
).optional(),
|
|
17725
|
-
style: external_exports.string().describe(
|
|
17726
|
-
"\u041F\u0430\u043F\u043A\u0430 \u043F\u0430\u043A\u0430 \u0444\u0438\u0440\u043C\u0435\u043D\u043D\u043E\u0433\u043E \u0441\u0442\u0438\u043B\u044F. \u041D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D \u2014 \u0431\u0435\u0440\u0451\u0442\u0441\u044F \u0441\u0442\u0438\u043B\u044C \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E, \u0430 \u0435\u0441\u043B\u0438 \u0438 \u0435\u0433\u043E \u043D\u0435\u0442, \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 \u043D\u0435\u0439\u0442\u0440\u0430\u043B\u044C\u043D\u044B\u0439"
|
|
17727
|
-
).optional(),
|
|
17728
|
-
preset: external_exports.string().describe(
|
|
17729
|
-
"\u0418\u043C\u044F \u043F\u0440\u0435\u0441\u0435\u0442\u0430 \u0432\u0438\u0434\u0430 \u0418\u0417 \u041F\u0410\u041A\u0410 \u0421\u0422\u0418\u041B\u042F \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430. \u041D\u0435 \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0439 \u0438\u043C\u0435\u043D\u0430: \u0443 \u043D\u0435\u0433\u043E \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043E\u0434\u0438\u043D \u043F\u0440\u0435\u0441\u0435\u0442 \u0438\u043B\u0438 \u0441\u0432\u043E\u0438"
|
|
17730
|
-
).optional(),
|
|
17731
|
-
model: fromList(
|
|
17732
|
-
passport?.["models"],
|
|
17733
|
-
`\u041C\u043E\u0434\u0435\u043B\u044C \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u044F \u0440\u0435\u0447\u0438. ${aboutModels(passport)}`
|
|
17734
|
-
).optional(),
|
|
17735
|
-
tempo: external_exports.number().describe("\u0423\u0441\u043A\u043E\u0440\u0435\u043D\u0438\u0435 \u0440\u0435\u0447\u0438, 1.0 \u2014 \u0431\u0435\u0437 \u0443\u0441\u043A\u043E\u0440\u0435\u043D\u0438\u044F").optional(),
|
|
17736
|
-
keep_pauses: external_exports.boolean().describe("\u041D\u0435 \u0442\u0440\u043E\u0433\u0430\u0442\u044C \u043F\u0430\u0443\u0437\u044B, \u0442\u043E\u043B\u044C\u043A\u043E \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B").optional(),
|
|
17737
|
-
redo: external_exports.array(fromList(passport?.["stages"], "\u0418\u043C\u044F \u0448\u0430\u0433\u0430 \u043C\u043E\u043D\u0442\u0430\u0436\u0430")).describe(
|
|
17738
|
-
"\u0421\u043E\u0431\u0440\u0430\u0442\u044C \u043D\u0430\u0437\u0432\u0430\u043D\u043D\u044B\u0435 \u0448\u0430\u0433\u0438 \u0437\u0430\u043D\u043E\u0432\u043E, \u0434\u0430\u0436\u0435 \u0435\u0441\u043B\u0438 \u0433\u043E\u0442\u043E\u0432\u043E\u0435 \u0443\u0436\u0435 \u043B\u0435\u0436\u0438\u0442. \u041D\u0443\u0436\u043D\u043E \u0440\u0435\u0434\u043A\u043E \u2014 \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, \u043A\u043E\u0433\u0434\u0430 \u043F\u043E\u0434\u043C\u0435\u043D\u0438\u043B\u0438 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A \u0442\u0435\u043C \u0436\u0435 \u0438\u043C\u0435\u043D\u0435\u043C" + (passport !== null ? `. \u0428\u0430\u0433\u0438: ${passport["stages"].join(", ")}` : "")
|
|
17739
|
-
).optional(),
|
|
17740
|
-
from_scratch: external_exports.boolean().describe(
|
|
17741
|
-
"\u0421\u0447\u0438\u0442\u0430\u0442\u044C \u0432\u0441\u0451 \u0437\u0430\u043D\u043E\u0432\u043E, \u043A\u044D\u0448 \u043D\u0435 \u0442\u0440\u043E\u0433\u0430\u0442\u044C. \u0414\u043E\u0440\u043E\u0433\u043E: \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438 \u044D\u0442\u043E \u043C\u0438\u043D\u0443\u0442\u044B. \u0421\u043D\u0430\u0447\u0430\u043B\u0430 \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439 redo \u0441 \u043E\u0434\u043D\u0438\u043C \u0448\u0430\u0433\u043E\u043C"
|
|
17742
|
-
).optional(),
|
|
17743
|
-
even_without_speech: external_exports.boolean().describe(
|
|
17744
|
-
"\u0421\u043E\u0431\u0440\u0430\u0442\u044C, \u0434\u0430\u0436\u0435 \u0435\u0441\u043B\u0438 \u043C\u043E\u043D\u0442\u0430\u0436 \u0433\u043E\u0432\u043E\u0440\u0438\u0442 \xAB\u0440\u0435\u0447\u0438 \u0432 \u0444\u0430\u0439\u043B\u0435 \u043D\u0435\u0442\xBB. \u0421\u0442\u0430\u0432\u044C \u0422\u041E\u041B\u042C\u041A\u041E \u043F\u043E\u0441\u043B\u0435 \u0442\u043E\u0433\u043E, \u043A\u0430\u043A \u0441\u043F\u0440\u043E\u0441\u0438\u043B \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0438 \u043E\u043D \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043B, \u0447\u0442\u043E \u0440\u0435\u0447\u044C \u0442\u0430\u043C \u0435\u0441\u0442\u044C: \u043D\u0430 \u043A\u043B\u0438\u043F\u0430\u0445 \u043F\u043E\u0434 \u043C\u0443\u0437\u044B\u043A\u0443 \u0434\u0432\u0438\u0436\u043E\u043A \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u044F \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0435\u0442 \u0441\u043B\u043E\u0432\u0430, \u0438 \u043E\u043D\u0438 \u043F\u043E\u043F\u0430\u0434\u0443\u0442 \u0432 \u043A\u0430\u0434\u0440"
|
|
17745
|
-
).optional()
|
|
17746
|
-
});
|
|
17747
|
-
}
|
|
17748
|
-
var NOT_FOR_PAUSES = ["preset", "model", "keep_pauses", "redo", "even_without_speech"];
|
|
17749
|
-
function renderArgs(passport) {
|
|
17750
|
-
const ours = renderDeclared(passport);
|
|
17751
|
-
const packKeys = capabilitiesToSchema(passport, new Set(Object.keys(ours.shape)));
|
|
17752
|
-
return ours.extend(packKeys);
|
|
17753
|
-
}
|
|
17754
|
-
function renderTool(engine, passport, key) {
|
|
17755
|
-
return defineTool({
|
|
17756
|
-
name: "render",
|
|
17757
|
-
title: "\u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0440\u043E\u043B\u0438\u043A",
|
|
17758
|
-
description: "\u0421\u043E\u0431\u0438\u0440\u0430\u0435\u0442 \u0440\u043E\u043B\u0438\u043A \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430: \u0443\u0431\u0438\u0440\u0430\u0435\u0442 \u043F\u0430\u0443\u0437\u044B, \u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B \u043F\u043E \u0441\u043B\u043E\u0432\u0430\u043C, \u0440\u0438\u0441\u0443\u0435\u0442 \u0433\u0440\u0430\u0444\u0438\u043A\u0443 \u043F\u043E \u043F\u043B\u0430\u043D\u0443, \u0441\u0432\u043E\u0434\u0438\u0442 \u0437\u0432\u0443\u043A. \u0417\u043E\u0432\u0438 \u041F\u041E\u0421\u041B\u0415 \u0442\u043E\u0433\u043E, \u043A\u0430\u043A \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0441\u043A\u0430\u0437\u0430\u043B \xAB\u0434\u0430\xBB \u043D\u0430 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0438\u0437 plan: \u0441\u043E\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043A\u0430\u0434\u0440 \u0441\u043F\u043E\u0440\u0438\u0442\u044C \u0434\u043E\u0440\u043E\u0436\u0435, \u0447\u0435\u043C \u0441\u0442\u0440\u043E\u0447\u043A\u0443 \u043F\u043B\u0430\u043D\u0430.\n\u0421\u043E\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0422\u041E\u041B\u042C\u041A\u041E \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u043F\u043B\u0430\u043D, \u0438 \xAB\u0434\u0430\xBB \u0432 \u0447\u0430\u0442\u0435 \u0441\u0430\u043C\u043E \u043F\u043E \u0441\u0435\u0431\u0435 \u043D\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044F: \u0437\u0430\u043F\u0438\u0448\u0438 \u0435\u0433\u043E \u0432\u044B\u0437\u043E\u0432\u043E\u043C plan_edit \u0441 confirm \u2014 \u0442\u0435\u043C \u0436\u0435, \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u0448\u043B\u0451\u0448\u044C \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044E\u044E \u043F\u0440\u0430\u0432\u043A\u0443. \u041B\u044E\u0431\u0430\u044F \u043F\u0440\u0430\u0432\u043A\u0430 \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0435 \u0441\u043D\u0438\u043C\u0430\u0435\u0442, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043F\u043E\u0440\u044F\u0434\u043E\u043A \u0442\u0430\u043A\u043E\u0439: \u043F\u043E\u043F\u0440\u0430\u0432\u0438\u043B, \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u0430\u043B \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443, \u0443\u0441\u043B\u044B\u0448\u0430\u043B \xAB\u0434\u0430\xBB, \u043F\u043E\u0437\u0432\u0430\u043B plan_edit \u0441 confirm, \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u0442\u0435\u043F\u0435\u0440\u044C render.\n\u0415\u0441\u043B\u0438 reel \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 \u043E\u0431\u0449\u0438\u0439 naparnik-project/1, render \u0441\u0430\u043C \u0432\u044B\u0431\u0438\u0440\u0430\u0435\u0442 \u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0430\u043B\u044C\u043D\u0443\u044E \u0441\u0431\u043E\u0440\u043A\u0443; \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0433\u043E \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0430 \u0434\u043B\u044F \u043D\u0435\u0451 \u043D\u0435\u0442. \u0412\u0441\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0442\u0430\u043A\u043E\u0433\u043E \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u0443\u0436\u0435 \u043B\u0435\u0436\u0430\u0442 \u0432 project: \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 reel \u043D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0439 style, preset, tempo \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0441\u0442\u0430\u0440\u043E\u0433\u043E \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u2014 \u043D\u0443\u0436\u043D\u0443\u044E \u043F\u0440\u0430\u0432\u043A\u0443 \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0437\u0430\u043F\u0438\u0448\u0438 \u0447\u0435\u0440\u0435\u0437 plan_edit.\n\u041E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0434\u0430\u043B\u044C\u0448\u0435 wait, \u043E\u043D \u043F\u043E\u0434\u043E\u0436\u0434\u0451\u0442 \u0438 \u0440\u0430\u0441\u0441\u043A\u0430\u0436\u0435\u0442 \u0445\u043E\u0434. \u041F\u043E\u0432\u0442\u043E\u0440\u043D\u044B\u0439 \u0432\u044B\u0437\u043E\u0432 \u0441 \u0442\u043E\u0439 \u0436\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u043E\u0439 \u043F\u043E\u0447\u0442\u0438 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0434\u0435\u043B\u0430\u0435\u0442 \u0437\u0430\u043D\u043E\u0432\u043E: \u0432\u0441\u0451 \u0431\u0435\u0440\u0451\u0442\u0441\u044F \u0438\u0437 \u043A\u044D\u0448\u0430.\n\u041F\u0440\u043E\u0441\u044F\u0442 \xAB\u043F\u0440\u043E\u0441\u0442\u043E \u0443\u0431\u0435\u0440\u0438 \u043F\u0430\u0443\u0437\u044B\xBB, \xAB\u0443\u0431\u0435\u0440\u0438 \u0442\u0438\u0448\u0438\u043D\u0443\xBB \u2014 only_pauses=true: \u0440\u0435\u0447\u044C \u043F\u0440\u0438 \u044D\u0442\u043E\u043C \u043D\u0435 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0451\u0442\u0441\u044F, \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A\u0430 \u043D\u0435\u0442 \u0438 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u044B\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E. \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0432 \u043D\u0430\u0447\u0430\u043B\u0435 (plan_edit, \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044F intro) \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u0438 \u0437\u0434\u0435\u0441\u044C: \u043E\u043D\u0430 \u043D\u0435 \u043F\u0440\u043E \u0440\u0435\u0447\u044C, \u0430 \u043F\u0440\u043E \u0442\u043E, \u0447\u0442\u043E \u0432\u0441\u0442\u0430\u0451\u0442 \u041F\u0415\u0420\u0415\u0414 \u0440\u043E\u043B\u0438\u043A\u043E\u043C.\n\u0420\u0430\u0431\u043E\u0442\u0430 \u0438\u0434\u0451\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430, \u043A \u043D\u0430\u043C \u0432\u0438\u0434\u0435\u043E \u043D\u0435 \u0443\u0445\u043E\u0434\u0438\u0442 \u2014 \u043D\u0430\u0432\u0435\u0440\u0445 \u0438\u0434\u0451\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u043F\u043E \u043A\u043B\u044E\u0447\u0443.",
|
|
17759
|
-
// Полоса хода работы: монтаж идёт минутами, и всё это время в ленте не
|
|
17760
|
-
// происходило бы ничего. ⚠ Ожидание — у `wait`, и полосы там нет: иначе
|
|
17761
|
-
// каждая проверка рисовала бы новую поверх этой.
|
|
17762
|
-
ui: { resourceUri: RUNBAR_RESOURCE_URI },
|
|
17763
|
-
// ⚠ КЛЮЧИ ПАКА ДОБАВЛЯЮТСЯ К СХЕМЕ ЧЕРЕЗ `extend`, А ТИП ОСТАЁТСЯ ОТ
|
|
17764
|
-
// ОБЪЯВЛЕННОЙ ЧАСТИ. Их набор известен только в рантайме (паспорт пака), и
|
|
17765
|
-
// выведенный из них тип превратился бы в словарь со свободными ключами —
|
|
17766
|
-
// тогда `args.video` перестал бы быть строкой, а описка в имени поля
|
|
17767
|
-
// перестала бы быть ошибкой компиляции. В объявление модели они при этом
|
|
17768
|
-
// попадают полностью: схема-то настоящая.
|
|
17769
|
-
args: renderArgs(passport).check((ctx) => {
|
|
17770
|
-
const asked = ctx.value;
|
|
17771
|
-
const say = (message, where) => {
|
|
17772
|
-
ctx.issues.push({ code: "custom", message, input: asked, path: [where] });
|
|
17773
|
-
};
|
|
17774
|
-
const video = asked["video"];
|
|
17775
|
-
const reel = asked["reel"];
|
|
17776
|
-
if (video === void 0 && reel === void 0) {
|
|
17777
|
-
say(
|
|
17778
|
-
"\u041D\u0435 \u0441\u043A\u0430\u0437\u0430\u043D\u043E, \u0447\u0442\u043E \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C: \u043D\u0430\u0437\u043E\u0432\u0438 video (\u0444\u0430\u0439\u043B) \u0438\u043B\u0438 reel (\u043F\u0430\u043F\u043A\u0443 \u0437\u0430\u0432\u0435\u0434\u0451\u043D\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430). \u0427\u0442\u043E \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0435\u0441\u0442\u044C, \u043F\u043E\u043A\u0430\u0436\u0435\u0442 plan \u0431\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432",
|
|
17779
|
-
"video"
|
|
17780
|
-
);
|
|
17781
|
-
}
|
|
17782
|
-
if (video !== void 0 && reel !== void 0) {
|
|
17783
|
-
say("\xABvideo\xBB \u0438 \xABreel\xBB \u2014 \u044D\u0442\u043E \u043E\u0434\u043D\u043E \u0438 \u0442\u043E \u0436\u0435 \u043C\u0435\u0441\u0442\u043E, \u043D\u0430\u0437\u0432\u0430\u043D\u043D\u043E\u0435 \u0434\u0432\u0430\u0436\u0434\u044B. \u041E\u0441\u0442\u0430\u0432\u044C \u043E\u0434\u043D\u043E", "reel");
|
|
17784
|
-
}
|
|
17785
|
-
if (asked["only_pauses"] !== true) return;
|
|
17786
|
-
const extra = NOT_FOR_PAUSES.filter((name) => asked[name] !== void 0);
|
|
17787
|
-
if (extra.length > 0) {
|
|
17788
|
-
say(
|
|
17789
|
-
`\xABonly_pauses\xBB \u0440\u0435\u0436\u0435\u0442 \u0442\u0438\u0448\u0438\u043D\u0443 \u0438 \u043D\u0430 \u044D\u0442\u043E\u043C \u043E\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u0435\u0442\u0441\u044F \u2014 \u043B\u0438\u0448\u043D\u0435\u0435: ${extra.join(", ")}. \u041F\u043E\u0437\u043E\u0432\u0438 \u043B\u0438\u0431\u043E \u0441 only_pauses, \u043B\u0438\u0431\u043E \u0437\u0430 \u043F\u043E\u043B\u043D\u044B\u043C \u043C\u043E\u043D\u0442\u0430\u0436\u043E\u043C`,
|
|
17790
|
-
"only_pauses"
|
|
17791
|
-
);
|
|
17792
|
-
}
|
|
17793
|
-
}),
|
|
17794
|
-
async execute(args, ctx) {
|
|
17795
|
-
const all = args;
|
|
17796
|
-
const video = args.video ?? args.reel ?? "";
|
|
17797
|
-
return startRender(
|
|
17798
|
-
engine,
|
|
17799
|
-
{
|
|
17800
|
-
video,
|
|
17801
|
-
reel: args.reel !== void 0,
|
|
17802
|
-
onlyPauses: args.only_pauses,
|
|
17803
|
-
style: args.style,
|
|
17804
|
-
preset: args.preset,
|
|
17805
|
-
model: args.model,
|
|
17806
|
-
tempo: args.tempo,
|
|
17807
|
-
keepPauses: args.keep_pauses,
|
|
17808
|
-
redo: args.redo,
|
|
17809
|
-
fromScratch: args.from_scratch,
|
|
17810
|
-
evenWithoutSpeech: args.even_without_speech,
|
|
17811
|
-
args: all
|
|
18381
|
+
rebuild: args.rebuild
|
|
17812
18382
|
},
|
|
17813
|
-
passport,
|
|
17814
18383
|
key,
|
|
17815
18384
|
ctx?.emitProgress
|
|
17816
18385
|
);
|
|
17817
18386
|
}
|
|
17818
18387
|
});
|
|
17819
18388
|
}
|
|
17820
|
-
function waitTool(engine, pace = realPace) {
|
|
17821
|
-
return defineTool({
|
|
17822
|
-
name: "wait",
|
|
17823
|
-
title: "\u0414\u043E\u0436\u0434\u0430\u0442\u044C\u0441\u044F \u0440\u0430\u0431\u043E\u0442\u044B",
|
|
17824
|
-
description: `\u0416\u0434\u0451\u0442 \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u043F\u043E \u0445\u043E\u0434\u0443 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442, \u043A\u0430\u043A\u043E\u0439 \u0448\u0430\u0433 \u043F\u043E\u0448\u0451\u043B \u0438 \u043A\u0430\u043A\u043E\u0439 \u0437\u0430\u043A\u043E\u043D\u0447\u0438\u043B\u0441\u044F \u2014 \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0441\u0440\u0430\u0437\u0443, \u043D\u0435 \u0434\u043E\u0436\u0438\u0434\u0430\u044F\u0441\u044C \u043A\u043E\u043D\u0446\u0430. \u0422\u0430\u043A \u0438 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0439: \u043E\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044C \u043F\u043E \u043A\u0440\u0443\u0433\u0443 \u043D\u0435 \u043D\u0430\u0434\u043E, \u0436\u0434\u0451\u0442 \u043E\u043D \u0434\u043E ${WAIT_LIMIT_SECONDS} \u0441\u0435\u043A\u0443\u043D\u0434 \u0438 \u0432\u0435\u0440\u043D\u0451\u0442\u0441\u044F \u0440\u0430\u043D\u044C\u0448\u0435, \u0435\u0441\u043B\u0438 \u0440\u0430\u0431\u043E\u0442\u0430 \u043A\u043E\u043D\u0447\u0438\u0442\u0441\u044F.
|
|
17825
|
-
\u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u043D\u043E\u043C\u0435\u0440, \u0440\u043E\u043B\u0438\u043A, \u0447\u0435\u043C \u043A\u043E\u043D\u0447\u0438\u043B\u043E\u0441\u044C. \u0417\u043E\u0432\u0438, \u043A\u043E\u0433\u0434\u0430 \u043D\u043E\u043C\u0435\u0440 \u043F\u043E\u0442\u0435\u0440\u044F\u043B\u0441\u044F: \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, \u043F\u043E\u0441\u043B\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u0438\u043B\u0438 \u043A\u043E\u0433\u0434\u0430 \u0432\u044B\u0437\u043E\u0432 \u043E\u0431\u043E\u0440\u0432\u0430\u043B\u0441\u044F \u043F\u043E\u0441\u0440\u0435\u0434\u0438 \u0440\u0430\u0431\u043E\u0442\u044B. \u0421 video \u2014 \u0437\u0430\u0434\u0430\u0447\u0438 \u043E\u0434\u043D\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430.
|
|
17826
|
-
\u0417\u0430\u0434\u0430\u0447\u0438 \u043B\u0435\u0436\u0430\u0442 \u043D\u0430 \u0434\u0438\u0441\u043A\u0435 \u0438 \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u044E\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B. \u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u043D\u0435 \u043D\u0443\u0436\u043D\u0430: \u0437\u0430\u0431\u0440\u0430\u0442\u044C \u0443\u0436\u0435 \u0441\u0434\u0435\u043B\u0430\u043D\u043D\u043E\u0435 \u043C\u043E\u0436\u043D\u043E \u0432\u0441\u0435\u0433\u0434\u0430.`,
|
|
17827
|
-
args: external_exports.object({
|
|
17828
|
-
job: external_exports.string().describe(
|
|
17829
|
-
"\u041D\u043E\u043C\u0435\u0440 \u0437\u0430\u0434\u0430\u0447\u0438, \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 2026-08-19T14-03-12Z-a3f1. \u0415\u0433\u043E \u043D\u0430\u0437\u0432\u0430\u043B \u0442\u043E\u0442 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442, \u0447\u0442\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u043B \u0440\u0430\u0431\u043E\u0442\u0443"
|
|
17830
|
-
).optional(),
|
|
17831
|
-
seconds: external_exports.number().describe(
|
|
17832
|
-
`\u0421\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0435\u043A\u0443\u043D\u0434 \u0436\u0434\u0430\u0442\u044C. \u041F\u043E\u0442\u043E\u043B\u043E\u043A ${WAIT_LIMIT_SECONDS}: \u043F\u0440\u043E\u0441\u044C\u0431\u0430 \u0431\u043E\u043B\u044C\u0448\u0435 \u043C\u043E\u043B\u0447\u0430 \u043E\u0431\u0440\u0435\u0436\u0435\u0442\u0441\u044F. \u0411\u0435\u0437 \u043D\u0435\u0433\u043E \u0436\u0434\u0451\u0442 \u0441\u0442\u043E\u043B\u044C\u043A\u043E, \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u043C\u043E\u0436\u043D\u043E`
|
|
17833
|
-
).optional(),
|
|
17834
|
-
video: external_exports.string().describe("\u0422\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u0434\u0430\u0447\u0438 \u044D\u0442\u043E\u0433\u043E \u0440\u043E\u043B\u0438\u043A\u0430 (\u0431\u0435\u0437 job)").optional(),
|
|
17835
|
-
limit: external_exports.number().describe("\u0421\u043A\u043E\u043B\u044C\u043A\u043E \u0437\u0430\u0434\u0430\u0447 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C, \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E 15").optional()
|
|
17836
|
-
}).check((ctx) => {
|
|
17837
|
-
const asked = ctx.value;
|
|
17838
|
-
if (asked.job === void 0) {
|
|
17839
|
-
if (asked.seconds !== void 0) {
|
|
17840
|
-
ctx.issues.push({
|
|
17841
|
-
code: "custom",
|
|
17842
|
-
message: "\xABseconds\xBB \u2014 \u044D\u0442\u043E \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0436\u0434\u0430\u0442\u044C \u041E\u0414\u041D\u0423 \u0437\u0430\u0434\u0430\u0447\u0443: \u043D\u0430\u0437\u043E\u0432\u0438 \u0435\u0451 \u043D\u043E\u043C\u0435\u0440 \u0432 \xABjob\xBB",
|
|
17843
|
-
input: asked,
|
|
17844
|
-
path: ["seconds"]
|
|
17845
|
-
});
|
|
17846
|
-
}
|
|
17847
|
-
return;
|
|
17848
|
-
}
|
|
17849
|
-
for (const key of ["video", "limit"]) {
|
|
17850
|
-
if (asked[key] !== void 0) {
|
|
17851
|
-
ctx.issues.push({
|
|
17852
|
-
code: "custom",
|
|
17853
|
-
message: `\xAB${key}\xBB \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0441\u044F \u043A \u0421\u041F\u0418\u0421\u041A\u0423 \u0437\u0430\u0434\u0430\u0447, \u0430 \u0441 \xABjob\xBB \u0436\u0434\u0443\u0442 \u043E\u0434\u043D\u0443. \u041F\u043E\u0437\u043E\u0432\u0438 \u0431\u0435\u0437 \xABjob\xBB, \u0447\u0442\u043E\u0431\u044B \u0443\u0432\u0438\u0434\u0435\u0442\u044C \u0441\u043F\u0438\u0441\u043E\u043A`,
|
|
17854
|
-
input: asked,
|
|
17855
|
-
path: [key]
|
|
17856
|
-
});
|
|
17857
|
-
}
|
|
17858
|
-
}
|
|
17859
|
-
}),
|
|
17860
|
-
readOnly: true,
|
|
17861
|
-
async execute(args, ctx) {
|
|
17862
|
-
const place = engine.place();
|
|
17863
|
-
if (place === null) return toolError(engine.whyNoEngine());
|
|
17864
|
-
if (args.job === void 0) {
|
|
17865
|
-
return listJobs(engine, { video: args.video, limit: args.limit });
|
|
17866
|
-
}
|
|
17867
|
-
return followWork(engine, { job: args.job, seconds: args.seconds }, pace, ctx?.emitProgress);
|
|
17868
|
-
}
|
|
17869
|
-
});
|
|
17870
|
-
}
|
|
17871
18389
|
async function showFrame(engine, asked) {
|
|
17872
18390
|
const video = asked.video;
|
|
17873
18391
|
const moment = asked.moment;
|
|
@@ -18002,10 +18520,10 @@ var OWN_STYLE_FOLDER = "style";
|
|
|
18002
18520
|
function contractRefusal(theirs) {
|
|
18003
18521
|
return `\u0414\u0432\u0438\u0436\u043E\u043A \u0433\u043E\u0432\u043E\u0440\u0438\u0442 \u043D\u0430 \u0434\u043E\u0433\u043E\u0432\u043E\u0440\u0435 \xAB${theirs}\xBB, \u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 \u043F\u043E\u043D\u0438\u043C\u0430\u0435\u0442 \xAB${CHOICES_CONTRACT}\xBB. \u041E\u0431\u043D\u043E\u0432\u0438 \u0442\u043E, \u0447\u0442\u043E \u0441\u0442\u0430\u0440\u0435\u0435: setup \u0441 what=engine \u0434\u043B\u044F \u0434\u0432\u0438\u0436\u043A\u0430, what=shell \u0434\u043B\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.`;
|
|
18004
18522
|
}
|
|
18005
|
-
function notJson(
|
|
18006
|
-
const
|
|
18007
|
-
return NOT_JSON2 + (
|
|
18008
|
-
\u0427\u0442\u043E \u043F\u0440\u0438\u0448\u043B\u043E \u0432\u043C\u0435\u0441\u0442\u043E JSON: \xAB${
|
|
18523
|
+
function notJson(text2) {
|
|
18524
|
+
const head2 = text2.trim().slice(0, 160).replace(/\s+/g, " ");
|
|
18525
|
+
return NOT_JSON2 + (head2 ? `
|
|
18526
|
+
\u0427\u0442\u043E \u043F\u0440\u0438\u0448\u043B\u043E \u0432\u043C\u0435\u0441\u0442\u043E JSON: \xAB${head2}\u2026\xBB` : "");
|
|
18009
18527
|
}
|
|
18010
18528
|
var NOT_JSON2 = "\u0414\u0432\u0438\u0436\u043E\u043A \u043E\u0442\u0432\u0435\u0442\u0438\u043B \u043D\u0435 \u0442\u0435\u043C, \u0447\u0435\u0433\u043E \u0436\u0434\u0430\u043B\u0438. \u041E\u0431\u043D\u043E\u0432\u0438 \u0434\u0432\u0438\u0436\u043E\u043A \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u043C setup \u0441 what=engine \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438.";
|
|
18011
18529
|
var FIRST_BATCH = 12;
|
|
@@ -18353,7 +18871,7 @@ async function showCards(engine, input) {
|
|
|
18353
18871
|
// «Готово» требовало ответить и там. Нашло ревью устройства
|
|
18354
18872
|
// 2026-09-18.
|
|
18355
18873
|
only: wanted2,
|
|
18356
|
-
clip:
|
|
18874
|
+
clip: basename5(where.path),
|
|
18357
18875
|
video: where.path,
|
|
18358
18876
|
// ⚠ СЫРЬЁ ПРЕВЬЮ ЕДЕТ ФОРМЕ ЦЕЛИКОМ: чистый кадр, числа вида и
|
|
18359
18877
|
// умолчания движка. Картинку она складывает сама (решение владельца
|
|
@@ -18432,7 +18950,7 @@ function questionInWords(q) {
|
|
|
18432
18950
|
return `${q.title} ${shown}${rest}`;
|
|
18433
18951
|
}
|
|
18434
18952
|
var LATIN_NAME = /^[a-z][a-z0-9_-]{0,31}$/;
|
|
18435
|
-
function
|
|
18953
|
+
function basename5(path2) {
|
|
18436
18954
|
const parts = path2.split(/[\\/]/);
|
|
18437
18955
|
return parts[parts.length - 1] ?? path2;
|
|
18438
18956
|
}
|
|
@@ -21119,44 +21637,6 @@ function chooseWidgetHtml() {
|
|
|
21119
21637
|
</body>
|
|
21120
21638
|
</html>`;
|
|
21121
21639
|
}
|
|
21122
|
-
var CALLS_FILE = "calls.jsonl";
|
|
21123
|
-
var CALLS_PREVIOUS = "calls.1.jsonl";
|
|
21124
|
-
var CALLS_CAP_BYTES = 1e6;
|
|
21125
|
-
function withCallLog(home, now = () => Date.now()) {
|
|
21126
|
-
return (tool) => {
|
|
21127
|
-
const original = tool.execute.bind(tool);
|
|
21128
|
-
return {
|
|
21129
|
-
...tool,
|
|
21130
|
-
async execute(input, ...rest) {
|
|
21131
|
-
const started = now();
|
|
21132
|
-
const result = await original(input, ...rest);
|
|
21133
|
-
write(home, {
|
|
21134
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21135
|
-
tool: tool.name,
|
|
21136
|
-
ok: result.type === "success",
|
|
21137
|
-
ms: now() - started
|
|
21138
|
-
});
|
|
21139
|
-
return result;
|
|
21140
|
-
}
|
|
21141
|
-
};
|
|
21142
|
-
};
|
|
21143
|
-
}
|
|
21144
|
-
function write(home, line) {
|
|
21145
|
-
try {
|
|
21146
|
-
mkdirSync(home, { recursive: true });
|
|
21147
|
-
const file2 = join(home, CALLS_FILE);
|
|
21148
|
-
rotate(file2, join(home, CALLS_PREVIOUS));
|
|
21149
|
-
appendFileSync(file2, `${JSON.stringify(line)}
|
|
21150
|
-
`, { encoding: "utf8", mode: 384 });
|
|
21151
|
-
} catch {
|
|
21152
|
-
}
|
|
21153
|
-
}
|
|
21154
|
-
function rotate(file2, previous) {
|
|
21155
|
-
try {
|
|
21156
|
-
if (statSync(file2).size >= CALLS_CAP_BYTES) renameSync(file2, previous);
|
|
21157
|
-
} catch {
|
|
21158
|
-
}
|
|
21159
|
-
}
|
|
21160
21640
|
|
|
21161
21641
|
// src/update-nudge.ts
|
|
21162
21642
|
function usable2(value) {
|
|
@@ -21317,7 +21797,7 @@ ${result.content}` : [{ type: "text", text: header }, ...result.content]
|
|
|
21317
21797
|
}
|
|
21318
21798
|
|
|
21319
21799
|
// src/tool-registry.ts
|
|
21320
|
-
function buildAll(client, engine, passport, key, baseUrl, pace = realPace) {
|
|
21800
|
+
function buildAll(client, engine, passport, key, baseUrl, pace = realPace, awake = ASLEEP, crashes = null) {
|
|
21321
21801
|
return [
|
|
21322
21802
|
// Порядок — это порядок работы, и модель читает список сверху вниз:
|
|
21323
21803
|
// проверить машину, придумать словами, поправить словами, собрать, дождаться.
|
|
@@ -21349,7 +21829,16 @@ function buildAll(client, engine, passport, key, baseUrl, pace = realPace) {
|
|
|
21349
21829
|
// ходы МОДЕЛИ, а ход, отбитый опиской или мёртвой подпиской, стоил тех же
|
|
21350
21830
|
// секунд. Встань счётчик внутрь — из замера выпали бы именно неудачные
|
|
21351
21831
|
// ходы, то есть самые дорогие (`call-log.ts`).
|
|
21352
|
-
|
|
21832
|
+
//
|
|
21833
|
+
// ⚠ «НЕ СПИ» — СНАРУЖИ СВЕРКИ И ЗАСЛОНА, ПОД СЧЁТЧИКОМ. Держит любой ход
|
|
21834
|
+
// модели, в том числе отбитый: раз модель зовёт — она работает, и хвост
|
|
21835
|
+
// бодрости после него нужен так же (`keep-awake.ts`). Счётчик остаётся
|
|
21836
|
+
// самым внешним по доводу выше.
|
|
21837
|
+
//
|
|
21838
|
+
// ⚠ ЛОВУШКА ПОЛОМОК — СНАРУЖИ СВЕРКИ И ЗАСЛОНА: падение в самом заслоне
|
|
21839
|
+
// подписки — тоже наш баг, и его надо поймать. Под счётчиком — чтобы
|
|
21840
|
+
// пойманный вызов лёг в журнал отказом, а не пропал из замера.
|
|
21841
|
+
].map(withSubscription(client)).map(withArgs).map(withCrashReport(crashes)).map(withWakefulness(awake)).map(withCallLog(engine.home()));
|
|
21353
21842
|
}
|
|
21354
21843
|
function buildResources() {
|
|
21355
21844
|
return [chooseResource(), runbarResource()];
|
|
@@ -21402,8 +21891,8 @@ function buildBlock(entryFile, key) {
|
|
|
21402
21891
|
function withoutBom(string5) {
|
|
21403
21892
|
return string5.charCodeAt(0) === 65279 ? string5.slice(1) : string5;
|
|
21404
21893
|
}
|
|
21405
|
-
function findBlock(
|
|
21406
|
-
const lines =
|
|
21894
|
+
function findBlock(text2) {
|
|
21895
|
+
const lines = text2.split("\n");
|
|
21407
21896
|
const heading = new RegExp(`^\\[mcp_servers\\.(?:${SERVER_NAME}|"${SERVER_NAME}")\\]\\s*$`);
|
|
21408
21897
|
const child = new RegExp(`^\\[mcp_servers\\.(?:${SERVER_NAME}|"${SERVER_NAME}")\\.`);
|
|
21409
21898
|
const i = lines.findIndex((s) => heading.test(s));
|
|
@@ -21428,8 +21917,8 @@ function keyFromBlock(blockText) {
|
|
|
21428
21917
|
}
|
|
21429
21918
|
return void 0;
|
|
21430
21919
|
}
|
|
21431
|
-
function keyInTable(
|
|
21432
|
-
const lines =
|
|
21920
|
+
function keyInTable(text2) {
|
|
21921
|
+
const lines = text2.split("\n");
|
|
21433
21922
|
let inTable = false;
|
|
21434
21923
|
for (const raw of lines) {
|
|
21435
21924
|
const s = withoutBom(raw);
|
|
@@ -21546,4 +22035,4 @@ ${inTable}`, file2);
|
|
|
21546
22035
|
};
|
|
21547
22036
|
}
|
|
21548
22037
|
|
|
21549
|
-
export { DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSIDE_PYTHON, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, McpServer, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, SOURCES_FILE, START_SEC, StdioServerTransport, TOOL_SEC, USER_AGENT, VERSION, WHERE_TO_GET_KEY, buildAll, buildBlock, buildResources, bundleUrlFor, chooseBody, compare, configPath, currentMachineFingerprint, decide, decideShell, defineTool, deploy, downloadFile, fetchManifest, fetchShellManifest, fileOrRefusal, findBlock, fromHost, fromNpxCache, handOverToBody, inside, install, installPayload, installPython, installStep, installedShell, jsonSchemaOf, keyFromBlock, keyInTable, lastLine, loadConfig, manifestUrlFor, markChecked, markChecked2, markCurrent2 as markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion2 as previousVersion, probe, pythonSource, readConfig, refusalFor, remove, rollback, rollbackShell, shellDir, tarEntries, tidyOld2 as tidyOld, timeToCheck, timeToCheck2, unpackArchive, updateEngine, withArgs };
|
|
22038
|
+
export { CrashReporter, DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSIDE_PYTHON, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, McpServer, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, SOURCES_FILE, START_SEC, StdioServerTransport, TOOL_SEC, USER_AGENT, VERSION, WHERE_TO_GET_KEY, Wakefulness, buildAll, buildBlock, buildResources, bundleUrlFor, chooseBody, compare, configPath, currentMachineFingerprint, decide, decideShell, defineTool, deploy, downloadFile, fetchManifest, fetchShellManifest, fileOrRefusal, findBlock, fromHost, fromNpxCache, handOverToBody, inside, install, installPayload, installPython, installStep, installedShell, jsonSchemaOf, keyFromBlock, keyInTable, lastLine, loadConfig, manifestUrlFor, markChecked, markChecked2, markCurrent2 as markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion2 as previousVersion, probe, pythonSource, readConfig, realPace, refusalFor, remove, rollback, rollbackShell, shellDir, systemBlocker, tarEntries, tidyOld2 as tidyOld, timeToCheck, timeToCheck2, unpackArchive, updateEngine, watchProcessCrashes, withArgs };
|