@mytegroupinc/myte-core 0.0.34 → 0.0.35
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/mytecody-cli.js +86 -16
- package/package.json +1 -1
package/mytecody-cli.js
CHANGED
|
@@ -262,12 +262,31 @@ function isUrl(value) {
|
|
|
262
262
|
return /^https?:\/\//i.test(String(value || ""));
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
function statusLine(message) {
|
|
266
|
+
if (process.env.MYTE_CODY_QUIET_SETUP === "1") return;
|
|
267
|
+
console.error(`[MYTE CODY] ${message}`);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function formatBytes(bytes) {
|
|
271
|
+
const value = Number(bytes || 0);
|
|
272
|
+
if (!Number.isFinite(value) || value <= 0) return "unknown size";
|
|
273
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
274
|
+
let size = value;
|
|
275
|
+
let unit = 0;
|
|
276
|
+
while (size >= 1024 && unit < units.length - 1) {
|
|
277
|
+
size /= 1024;
|
|
278
|
+
unit += 1;
|
|
279
|
+
}
|
|
280
|
+
return `${size.toFixed(unit === 0 ? 0 : 1)} ${units[unit]}`;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async function readManifest(source, { fetchManifest, progress } = {}) {
|
|
266
284
|
if (!source) return { status: "missing", manifest: null };
|
|
267
285
|
if (isUrl(source)) {
|
|
268
286
|
if (!fetchManifest) {
|
|
269
287
|
return { status: "skipped", manifest: null };
|
|
270
288
|
}
|
|
289
|
+
if (progress) progress("checking signed release manifest");
|
|
271
290
|
const response = await fetch(source);
|
|
272
291
|
const text = await response.text();
|
|
273
292
|
if (!response.ok) {
|
|
@@ -367,20 +386,52 @@ function localPathFromArtifactUrl(urlValue) {
|
|
|
367
386
|
return null;
|
|
368
387
|
}
|
|
369
388
|
|
|
370
|
-
async function readArtifactBytes(artifact) {
|
|
389
|
+
async function readArtifactBytes(artifact, { progress } = {}) {
|
|
371
390
|
const urlValue = artifact && artifact.url ? String(artifact.url) : "";
|
|
372
391
|
const localPath = localPathFromArtifactUrl(urlValue);
|
|
373
392
|
if (localPath) {
|
|
393
|
+
if (progress) progress("reading local MyteCody engine artifact");
|
|
374
394
|
return fs.readFileSync(localPath);
|
|
375
395
|
}
|
|
376
396
|
const headers = {};
|
|
377
397
|
const token = getAuthToken();
|
|
378
398
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
399
|
+
if (progress) {
|
|
400
|
+
const expectedSize = Number(artifact && artifact.size_bytes ? artifact.size_bytes : 0);
|
|
401
|
+
progress(`downloading MyteCody engine (${formatBytes(expectedSize)})`);
|
|
402
|
+
}
|
|
379
403
|
const response = await fetch(urlValue, { method: "GET", headers });
|
|
380
|
-
const bytes = Buffer.from(await response.arrayBuffer());
|
|
381
404
|
if (!response.ok) {
|
|
405
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
382
406
|
throw new Error(`Artifact fetch failed (${response.status}): ${bytes.toString("utf8", 0, Math.min(bytes.length, 300))}`);
|
|
383
407
|
}
|
|
408
|
+
if (!response.body || typeof response.body.getReader !== "function") {
|
|
409
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
410
|
+
if (progress) progress(`downloaded MyteCody engine (${formatBytes(bytes.length)})`);
|
|
411
|
+
return bytes;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const total = Number(response.headers.get("content-length") || artifact?.size_bytes || 0);
|
|
415
|
+
const reader = response.body.getReader();
|
|
416
|
+
const chunks = [];
|
|
417
|
+
let received = 0;
|
|
418
|
+
let lastPct = -1;
|
|
419
|
+
while (true) {
|
|
420
|
+
const { done, value } = await reader.read();
|
|
421
|
+
if (done) break;
|
|
422
|
+
const chunk = Buffer.from(value);
|
|
423
|
+
chunks.push(chunk);
|
|
424
|
+
received += chunk.length;
|
|
425
|
+
if (progress && total > 0) {
|
|
426
|
+
const pct = Math.min(100, Math.floor((received / total) * 100));
|
|
427
|
+
if (pct >= lastPct + 10 || pct === 100) {
|
|
428
|
+
progress(`downloading MyteCody engine ${pct}% (${formatBytes(received)} / ${formatBytes(total)})`);
|
|
429
|
+
lastPct = pct;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const bytes = Buffer.concat(chunks);
|
|
434
|
+
if (progress) progress(`downloaded MyteCody engine (${formatBytes(bytes.length)})`);
|
|
384
435
|
return bytes;
|
|
385
436
|
}
|
|
386
437
|
|
|
@@ -525,8 +576,16 @@ function tomlString(value) {
|
|
|
525
576
|
return JSON.stringify(String(value || ""));
|
|
526
577
|
}
|
|
527
578
|
|
|
579
|
+
function tomlLiteralString(value) {
|
|
580
|
+
const text = String(value || "");
|
|
581
|
+
if (!text.includes("'") && !text.includes("\n") && !text.includes("\r")) {
|
|
582
|
+
return `'${text}'`;
|
|
583
|
+
}
|
|
584
|
+
return tomlString(text);
|
|
585
|
+
}
|
|
586
|
+
|
|
528
587
|
function pathForToml(value) {
|
|
529
|
-
return String(value || "")
|
|
588
|
+
return String(value || "");
|
|
530
589
|
}
|
|
531
590
|
|
|
532
591
|
function writeCodexModelCatalog() {
|
|
@@ -597,7 +656,7 @@ function writeCodexConfig(args = {}) {
|
|
|
597
656
|
const catalogPath = writeCodexModelCatalog();
|
|
598
657
|
const config = `model = ${tomlString(DEFAULT_MODEL_ALIAS)}
|
|
599
658
|
model_provider = "myte_ai"
|
|
600
|
-
model_catalog_json = ${tomlString(
|
|
659
|
+
model_catalog_json = ${tomlString(catalogPath)}
|
|
601
660
|
model_context_window = ${DEFAULT_CONTEXT_WINDOW}
|
|
602
661
|
model_auto_compact_token_limit = ${DEFAULT_AUTO_COMPACT_TOKENS}
|
|
603
662
|
tool_output_token_limit = ${DEFAULT_TOOL_OUTPUT_TOKENS}
|
|
@@ -636,7 +695,7 @@ include_instructions = true
|
|
|
636
695
|
[skills.bundled]
|
|
637
696
|
enabled = false
|
|
638
697
|
|
|
639
|
-
[projects.${
|
|
698
|
+
[projects.${tomlLiteralString(process.cwd())}]
|
|
640
699
|
trust_level = "trusted"
|
|
641
700
|
|
|
642
701
|
[windows]
|
|
@@ -666,7 +725,7 @@ function codexProviderArgs(args = {}) {
|
|
|
666
725
|
"-c",
|
|
667
726
|
'model_providers.myte_ai.wire_api="responses"',
|
|
668
727
|
"-c",
|
|
669
|
-
`model_catalog_json
|
|
728
|
+
`model_catalog_json=${tomlString(codexModelCatalogPath())}`,
|
|
670
729
|
"-c",
|
|
671
730
|
`model_context_window=${DEFAULT_CONTEXT_WINDOW}`,
|
|
672
731
|
"-c",
|
|
@@ -703,11 +762,14 @@ async function runCodex(rawArgs, args = {}, envPath = null) {
|
|
|
703
762
|
console.error("MyteCody requires MYTEAI_API_KEY for coding.");
|
|
704
763
|
return 1;
|
|
705
764
|
}
|
|
765
|
+
statusLine("preparing trusted workspace");
|
|
706
766
|
writeCodexConfig(args);
|
|
707
767
|
try {
|
|
708
|
-
const install = await ensureBrandedEngineInstalled(args, envPath);
|
|
768
|
+
const install = await ensureBrandedEngineInstalled(args, envPath, { progress: statusLine });
|
|
709
769
|
if (install.ok && install.installed) {
|
|
710
|
-
|
|
770
|
+
statusLine(`engine installed: ${install.payload.installed.version}`);
|
|
771
|
+
} else if (install.ok) {
|
|
772
|
+
statusLine("engine ready");
|
|
711
773
|
} else if (!install.ok) {
|
|
712
774
|
console.error(`MyteCody branded engine could not be verified: ${install.reason || "unknown"}.`);
|
|
713
775
|
console.error("Run `mytecody update` with access to the Myte release manifest.");
|
|
@@ -729,6 +791,7 @@ async function runCodex(rawArgs, args = {}, envPath = null) {
|
|
|
729
791
|
...process.env,
|
|
730
792
|
CODEX_HOME: codexHome(),
|
|
731
793
|
MYTE_CODY_AUTH_TOKEN: token,
|
|
794
|
+
MYTE_CODY_BRAND: "1",
|
|
732
795
|
};
|
|
733
796
|
return new Promise((resolve) => {
|
|
734
797
|
const child = spawn(command.cmd, launchArgs, {
|
|
@@ -778,10 +841,13 @@ async function runDoctor(args, envPath) {
|
|
|
778
841
|
return 0;
|
|
779
842
|
}
|
|
780
843
|
|
|
781
|
-
async function buildUpdatePayload(args, envPath, { dryRun = false } = {}) {
|
|
844
|
+
async function buildUpdatePayload(args, envPath, { dryRun = false, progress = null } = {}) {
|
|
782
845
|
const isDryRun = Boolean(dryRun);
|
|
783
846
|
const source = manifestUrl(args);
|
|
784
|
-
const manifestResult = await readManifest(source, {
|
|
847
|
+
const manifestResult = await readManifest(source, {
|
|
848
|
+
fetchManifest: Boolean(args["fetch-manifest"]) || !isDryRun,
|
|
849
|
+
progress,
|
|
850
|
+
});
|
|
785
851
|
const manifest = manifestResult.manifest;
|
|
786
852
|
const artifact = manifest ? artifactForPlatform(manifest) : null;
|
|
787
853
|
const signature = manifest ? signatureAccepted(manifest, args) : { ok: false, signature: { status: "not-checked", verified: false } };
|
|
@@ -811,7 +877,7 @@ async function buildUpdatePayload(args, envPath, { dryRun = false } = {}) {
|
|
|
811
877
|
if (!artifactMetadata.ok) {
|
|
812
878
|
throw new Error(`MyteCody release artifact metadata is ${artifactMetadata.status}.`);
|
|
813
879
|
}
|
|
814
|
-
const bytes = await readArtifactBytes(artifact);
|
|
880
|
+
const bytes = await readArtifactBytes(artifact, { progress });
|
|
815
881
|
const digest = sha256Hex(bytes);
|
|
816
882
|
if (digest.toLowerCase() !== String(artifact.sha256 || "").toLowerCase()) {
|
|
817
883
|
throw new Error(`Artifact SHA-256 mismatch: expected ${artifact.sha256}, got ${digest}`);
|
|
@@ -844,7 +910,7 @@ function autoInstallEnabled(args = {}) {
|
|
|
844
910
|
return true;
|
|
845
911
|
}
|
|
846
912
|
|
|
847
|
-
async function ensureBrandedEngineInstalled(args = {}, envPath = null) {
|
|
913
|
+
async function ensureBrandedEngineInstalled(args = {}, envPath = null, { progress = null } = {}) {
|
|
848
914
|
const updateArgs = {
|
|
849
915
|
...args,
|
|
850
916
|
"fetch-manifest": true,
|
|
@@ -853,7 +919,7 @@ async function ensureBrandedEngineInstalled(args = {}, envPath = null) {
|
|
|
853
919
|
delete updateArgs.json;
|
|
854
920
|
|
|
855
921
|
const source = manifestUrl(updateArgs);
|
|
856
|
-
const manifestResult = await readManifest(source, { fetchManifest: true });
|
|
922
|
+
const manifestResult = await readManifest(source, { fetchManifest: true, progress });
|
|
857
923
|
const manifest = manifestResult.manifest;
|
|
858
924
|
if (!manifest) {
|
|
859
925
|
return { ok: false, installed: false, reason: "manifest-unavailable", manifest_status: manifestResult.status };
|
|
@@ -875,7 +941,7 @@ async function ensureBrandedEngineInstalled(args = {}, envPath = null) {
|
|
|
875
941
|
return { ok: false, installed: false, reason: "update-required-auto-install-disabled" };
|
|
876
942
|
}
|
|
877
943
|
|
|
878
|
-
const payload = await buildUpdatePayload(updateArgs, envPath, { dryRun: false });
|
|
944
|
+
const payload = await buildUpdatePayload(updateArgs, envPath, { dryRun: false, progress });
|
|
879
945
|
return {
|
|
880
946
|
ok: Boolean(payload.installed && payload.installed.ok),
|
|
881
947
|
installed: Boolean(payload.installed && payload.installed.ok),
|
|
@@ -886,7 +952,10 @@ async function ensureBrandedEngineInstalled(args = {}, envPath = null) {
|
|
|
886
952
|
|
|
887
953
|
async function runUpdate(args, envPath) {
|
|
888
954
|
const dryRun = Boolean(args["dry-run"]);
|
|
889
|
-
const payload = await buildUpdatePayload(args, envPath, {
|
|
955
|
+
const payload = await buildUpdatePayload(args, envPath, {
|
|
956
|
+
dryRun,
|
|
957
|
+
progress: args.json ? null : statusLine,
|
|
958
|
+
});
|
|
890
959
|
|
|
891
960
|
if (args.json) {
|
|
892
961
|
printJson(payload);
|
|
@@ -959,6 +1028,7 @@ module.exports = {
|
|
|
959
1028
|
run,
|
|
960
1029
|
sha256Hex,
|
|
961
1030
|
stableJson,
|
|
1031
|
+
tomlLiteralString,
|
|
962
1032
|
verifyManifestSignature,
|
|
963
1033
|
writeCodexConfig,
|
|
964
1034
|
};
|