@mindstudio-ai/remy 0.1.245 → 0.1.247
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/headless.d.ts +4 -1
- package/dist/headless.js +298 -80
- package/dist/index.js +305 -82
- package/dist/subagents/designExpert/data/sources/compile-font-descriptions.sh +1 -1
- package/dist/subagents/designExpert/data/sources/compile-inspiration.sh +2 -2
- package/dist/subagents/designExpert/data/sources/compile-ui-inspiration.sh +1 -1
- package/package.json +1 -1
package/dist/headless.d.ts
CHANGED
|
@@ -19,7 +19,10 @@
|
|
|
19
19
|
* page size (default 500, hard cap 2000). Response: {event:"history",
|
|
20
20
|
* messages, startIndex, endIndex, totalMessageCount, ...}. Walk backward by
|
|
21
21
|
* passing the previous response's `startIndex` as the next `before`. When
|
|
22
|
-
* `startIndex === 0`, no older messages remain.
|
|
22
|
+
* `startIndex === 0`, no older messages remain. Indices are GLOBAL — they span
|
|
23
|
+
* the sealed session archives followed by the live tail (see getHistoryPage in
|
|
24
|
+
* session.ts), so scrollback continues past a rotation to the conversation
|
|
25
|
+
* start, not just to the start of the live (post-rotation) array.
|
|
23
26
|
*/
|
|
24
27
|
interface HeadlessOptions {
|
|
25
28
|
apiKey?: string;
|
package/dist/headless.js
CHANGED
|
@@ -476,6 +476,9 @@ var ALLOWED_MODELS_BY_TYPE = {
|
|
|
476
476
|
"claude-fable-5",
|
|
477
477
|
"claude-5-sonnet",
|
|
478
478
|
"gpt-5.5",
|
|
479
|
+
"gpt-5.6-sol",
|
|
480
|
+
"gpt-5.6-terra",
|
|
481
|
+
"gpt-5.6-luna",
|
|
479
482
|
"gemini-3-pro",
|
|
480
483
|
"gemini-3.1-pro",
|
|
481
484
|
"gemini-3-flash",
|
|
@@ -1624,6 +1627,15 @@ var confirmDestructiveActionTool = {
|
|
|
1624
1627
|
|
|
1625
1628
|
// src/subagents/common/runCli.ts
|
|
1626
1629
|
import { spawn } from "child_process";
|
|
1630
|
+
var SCRAPE_MAX_BUFFER = 4 * 1024 * 1024;
|
|
1631
|
+
var SEARCH_MAX_BUFFER = 512 * 1024;
|
|
1632
|
+
var SIGKILL_GRACE_MS = 2e3;
|
|
1633
|
+
function formatCliResult(r) {
|
|
1634
|
+
const logBlock = r.logs.length > 0 ? r.logs.join("\n") + "\n\n" : "";
|
|
1635
|
+
const body = r.ok ? r.output : `Error: ${r.output}`;
|
|
1636
|
+
const truncNote = r.truncated ? "\n\n[output truncated]" : "";
|
|
1637
|
+
return logBlock + body + truncNote;
|
|
1638
|
+
}
|
|
1627
1639
|
function runCli(command, args, options) {
|
|
1628
1640
|
return new Promise((resolve2) => {
|
|
1629
1641
|
const timeout = options?.timeout ?? 6e4;
|
|
@@ -1632,35 +1644,71 @@ function runCli(command, args, options) {
|
|
|
1632
1644
|
if (options?.jsonLogs && !args.includes("--json-logs")) {
|
|
1633
1645
|
finalArgs = args.length > 0 ? [args[0], "--json-logs", ...args.slice(1)] : ["--json-logs"];
|
|
1634
1646
|
}
|
|
1635
|
-
const child = spawn(command, finalArgs, {
|
|
1636
|
-
stdio: [options?.stdin ? "pipe" : "ignore", "pipe", "pipe"]
|
|
1637
|
-
});
|
|
1638
|
-
if (options?.stdin) {
|
|
1639
|
-
child.stdin.write(options.stdin);
|
|
1640
|
-
child.stdin.end();
|
|
1641
|
-
}
|
|
1642
1647
|
const logs = [];
|
|
1643
1648
|
let stdout = "";
|
|
1644
1649
|
let stderr = "";
|
|
1645
1650
|
let stdoutSize = 0;
|
|
1646
1651
|
let stderrSize = 0;
|
|
1647
1652
|
let killed = false;
|
|
1653
|
+
let timedOut = false;
|
|
1654
|
+
let truncated = false;
|
|
1655
|
+
let settled = false;
|
|
1656
|
+
let timer;
|
|
1657
|
+
let killTimer;
|
|
1658
|
+
const finish = (result) => {
|
|
1659
|
+
if (settled) {
|
|
1660
|
+
return;
|
|
1661
|
+
}
|
|
1662
|
+
settled = true;
|
|
1663
|
+
if (timer) {
|
|
1664
|
+
clearTimeout(timer);
|
|
1665
|
+
}
|
|
1666
|
+
if (killTimer) {
|
|
1667
|
+
clearTimeout(killTimer);
|
|
1668
|
+
}
|
|
1669
|
+
resolve2(result);
|
|
1670
|
+
};
|
|
1671
|
+
const child = spawn(command, finalArgs, {
|
|
1672
|
+
stdio: [options?.stdin ? "pipe" : "ignore", "pipe", "pipe"]
|
|
1673
|
+
});
|
|
1674
|
+
child.on("error", (err) => {
|
|
1675
|
+
finish({
|
|
1676
|
+
ok: false,
|
|
1677
|
+
output: err.message,
|
|
1678
|
+
logs,
|
|
1679
|
+
timedOut: false,
|
|
1680
|
+
truncated: false
|
|
1681
|
+
});
|
|
1682
|
+
});
|
|
1683
|
+
if (options?.stdin) {
|
|
1684
|
+
child.stdin.on("error", () => {
|
|
1685
|
+
});
|
|
1686
|
+
try {
|
|
1687
|
+
child.stdin.write(options.stdin);
|
|
1688
|
+
child.stdin.end();
|
|
1689
|
+
} catch {
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
const killForOverflow = () => {
|
|
1693
|
+
if (killed) {
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
killed = true;
|
|
1697
|
+
truncated = true;
|
|
1698
|
+
child.kill();
|
|
1699
|
+
};
|
|
1648
1700
|
child.stdout.on("data", (chunk) => {
|
|
1649
1701
|
stdoutSize += chunk.length;
|
|
1650
1702
|
if (stdoutSize <= maxBuffer) {
|
|
1651
1703
|
stdout += chunk.toString();
|
|
1652
|
-
} else
|
|
1653
|
-
|
|
1654
|
-
child.kill();
|
|
1704
|
+
} else {
|
|
1705
|
+
killForOverflow();
|
|
1655
1706
|
}
|
|
1656
1707
|
});
|
|
1657
1708
|
child.stderr.on("data", (chunk) => {
|
|
1658
1709
|
stderrSize += chunk.length;
|
|
1659
1710
|
if (stderrSize > maxBuffer) {
|
|
1660
|
-
|
|
1661
|
-
killed = true;
|
|
1662
|
-
child.kill();
|
|
1663
|
-
}
|
|
1711
|
+
killForOverflow();
|
|
1664
1712
|
return;
|
|
1665
1713
|
}
|
|
1666
1714
|
const text = chunk.toString();
|
|
@@ -1685,24 +1733,38 @@ function runCli(command, args, options) {
|
|
|
1685
1733
|
}
|
|
1686
1734
|
}
|
|
1687
1735
|
});
|
|
1688
|
-
|
|
1736
|
+
timer = setTimeout(() => {
|
|
1737
|
+
if (killed) {
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1689
1740
|
killed = true;
|
|
1741
|
+
timedOut = true;
|
|
1690
1742
|
child.kill();
|
|
1743
|
+
killTimer = setTimeout(() => child.kill("SIGKILL"), SIGKILL_GRACE_MS);
|
|
1691
1744
|
}, timeout);
|
|
1692
1745
|
child.on("close", (code) => {
|
|
1693
|
-
clearTimeout(timer);
|
|
1694
|
-
const logBlock = !options?.onLog && logs.length > 0 ? logs.join("\n") + "\n\n" : "";
|
|
1695
1746
|
const out = stdout.trim();
|
|
1696
|
-
if (
|
|
1697
|
-
|
|
1747
|
+
if (timedOut) {
|
|
1748
|
+
finish({
|
|
1749
|
+
ok: false,
|
|
1750
|
+
output: stderr.trim() || "Process timed out",
|
|
1751
|
+
logs,
|
|
1752
|
+
timedOut: true,
|
|
1753
|
+
truncated
|
|
1754
|
+
});
|
|
1698
1755
|
return;
|
|
1699
1756
|
}
|
|
1700
|
-
if (
|
|
1701
|
-
|
|
1702
|
-
resolve2(logBlock + `Error: ${errMsg}`);
|
|
1757
|
+
if (out) {
|
|
1758
|
+
finish({ ok: true, output: out, logs, timedOut: false, truncated });
|
|
1703
1759
|
return;
|
|
1704
1760
|
}
|
|
1705
|
-
|
|
1761
|
+
finish({
|
|
1762
|
+
ok: false,
|
|
1763
|
+
output: stderr.trim() || (code !== 0 ? `Exit code ${code}` : "(no response)"),
|
|
1764
|
+
logs,
|
|
1765
|
+
timedOut: false,
|
|
1766
|
+
truncated
|
|
1767
|
+
});
|
|
1706
1768
|
});
|
|
1707
1769
|
});
|
|
1708
1770
|
}
|
|
@@ -1726,11 +1788,12 @@ var askMindStudioSdkTool = {
|
|
|
1726
1788
|
},
|
|
1727
1789
|
async execute(input, context) {
|
|
1728
1790
|
const query = input.query;
|
|
1729
|
-
|
|
1791
|
+
const result = await runCli("mindstudio", ["ask", query], {
|
|
1730
1792
|
timeout: 2e5,
|
|
1731
1793
|
maxBuffer: 512 * 1024,
|
|
1732
1794
|
onLog: context?.onLog
|
|
1733
1795
|
});
|
|
1796
|
+
return formatCliResult(result);
|
|
1734
1797
|
}
|
|
1735
1798
|
};
|
|
1736
1799
|
|
|
@@ -1768,17 +1831,21 @@ function stripFlags(args) {
|
|
|
1768
1831
|
}
|
|
1769
1832
|
return out;
|
|
1770
1833
|
}
|
|
1771
|
-
async function
|
|
1834
|
+
async function runMindstudioCliResult(args, options) {
|
|
1772
1835
|
const cleanArgs = stripFlags(args);
|
|
1773
1836
|
const cliAction = args[0];
|
|
1774
1837
|
const agentName = options?.caller ?? "mindstudio-cli";
|
|
1775
1838
|
const start = Date.now();
|
|
1776
|
-
const
|
|
1839
|
+
const res = await runCli("mindstudio", cleanArgs, options);
|
|
1840
|
+
if (!res.ok) {
|
|
1841
|
+
return { ok: false, value: formatCliResult(res) };
|
|
1842
|
+
}
|
|
1843
|
+
const truncNote = res.truncated ? "\n\n[output truncated]" : "";
|
|
1777
1844
|
let envelope;
|
|
1778
1845
|
try {
|
|
1779
|
-
envelope = JSON.parse(
|
|
1846
|
+
envelope = JSON.parse(res.output);
|
|
1780
1847
|
} catch {
|
|
1781
|
-
return
|
|
1848
|
+
return { ok: true, value: res.output + truncNote };
|
|
1782
1849
|
}
|
|
1783
1850
|
if (envelope && typeof envelope === "object" && Array.isArray(envelope.results)) {
|
|
1784
1851
|
const durationMs = Date.now() - start;
|
|
@@ -1796,7 +1863,7 @@ async function runMindstudioCli(args, options) {
|
|
|
1796
1863
|
});
|
|
1797
1864
|
}
|
|
1798
1865
|
}
|
|
1799
|
-
return JSON.stringify(envelope.results);
|
|
1866
|
+
return { ok: true, value: JSON.stringify(envelope.results) + truncNote };
|
|
1800
1867
|
}
|
|
1801
1868
|
if (typeof envelope?.$billingCost === "number") {
|
|
1802
1869
|
recordUsage({
|
|
@@ -1817,11 +1884,18 @@ async function runMindstudioCli(args, options) {
|
|
|
1817
1884
|
if (options?.outputKey) {
|
|
1818
1885
|
const v = envelope?.[options.outputKey];
|
|
1819
1886
|
if (v === void 0 || v === null) {
|
|
1820
|
-
return JSON.stringify(stripDollarKeys(envelope));
|
|
1887
|
+
return { ok: false, value: JSON.stringify(stripDollarKeys(envelope)) };
|
|
1821
1888
|
}
|
|
1822
|
-
|
|
1889
|
+
const value = typeof v === "string" ? v : JSON.stringify(v);
|
|
1890
|
+
return { ok: true, value: value + truncNote };
|
|
1823
1891
|
}
|
|
1824
|
-
return
|
|
1892
|
+
return {
|
|
1893
|
+
ok: true,
|
|
1894
|
+
value: JSON.stringify(stripDollarKeys(envelope)) + truncNote
|
|
1895
|
+
};
|
|
1896
|
+
}
|
|
1897
|
+
async function runMindstudioCli(args, options) {
|
|
1898
|
+
return (await runMindstudioCliResult(args, options)).value;
|
|
1825
1899
|
}
|
|
1826
1900
|
function stripDollarKeys(envelope) {
|
|
1827
1901
|
if (!envelope || typeof envelope !== "object" || Array.isArray(envelope)) {
|
|
@@ -1857,7 +1931,12 @@ var searchGoogleTool = {
|
|
|
1857
1931
|
const query = input.query;
|
|
1858
1932
|
return runMindstudioCli(
|
|
1859
1933
|
["search-google", "--query", query, "--export-type", "json"],
|
|
1860
|
-
{
|
|
1934
|
+
{
|
|
1935
|
+
outputKey: "results",
|
|
1936
|
+
maxBuffer: SEARCH_MAX_BUFFER,
|
|
1937
|
+
onLog: context?.onLog,
|
|
1938
|
+
caller: "parent"
|
|
1939
|
+
}
|
|
1861
1940
|
);
|
|
1862
1941
|
}
|
|
1863
1942
|
};
|
|
@@ -4146,7 +4225,12 @@ var definition = {
|
|
|
4146
4225
|
async function execute(input, onLog) {
|
|
4147
4226
|
return runMindstudioCli(
|
|
4148
4227
|
["search-google", "--query", input.query, "--export-type", "json"],
|
|
4149
|
-
{
|
|
4228
|
+
{
|
|
4229
|
+
outputKey: "results",
|
|
4230
|
+
onLog,
|
|
4231
|
+
caller: "designExpert",
|
|
4232
|
+
maxBuffer: SEARCH_MAX_BUFFER
|
|
4233
|
+
}
|
|
4150
4234
|
);
|
|
4151
4235
|
}
|
|
4152
4236
|
|
|
@@ -4173,9 +4257,6 @@ var definition2 = {
|
|
|
4173
4257
|
};
|
|
4174
4258
|
async function execute2(input, onLog) {
|
|
4175
4259
|
const pageOptions = { onlyMainContent: true };
|
|
4176
|
-
if (input.screenshot) {
|
|
4177
|
-
pageOptions.screenshot = true;
|
|
4178
|
-
}
|
|
4179
4260
|
return runMindstudioCli(
|
|
4180
4261
|
[
|
|
4181
4262
|
"scrape-url",
|
|
@@ -4184,7 +4265,7 @@ async function execute2(input, onLog) {
|
|
|
4184
4265
|
"--page-options",
|
|
4185
4266
|
JSON.stringify(pageOptions)
|
|
4186
4267
|
],
|
|
4187
|
-
{ onLog, caller: "designExpert" }
|
|
4268
|
+
{ onLog, caller: "designExpert", maxBuffer: SCRAPE_MAX_BUFFER }
|
|
4188
4269
|
);
|
|
4189
4270
|
}
|
|
4190
4271
|
|
|
@@ -4242,7 +4323,7 @@ async function execute3(input, onLog, context) {
|
|
|
4242
4323
|
const isImageUrl = /\.(png|jpe?g|webp|gif|svg|avif)(\?|$)/i.test(url);
|
|
4243
4324
|
let imageUrl = url;
|
|
4244
4325
|
if (!isImageUrl) {
|
|
4245
|
-
const
|
|
4326
|
+
const ss = await runMindstudioCliResult(
|
|
4246
4327
|
[
|
|
4247
4328
|
"screenshot-url",
|
|
4248
4329
|
"--url",
|
|
@@ -4261,10 +4342,10 @@ async function execute3(input, onLog, context) {
|
|
|
4261
4342
|
caller: "designExpert"
|
|
4262
4343
|
}
|
|
4263
4344
|
);
|
|
4264
|
-
if (
|
|
4265
|
-
return `Could not screenshot ${url}: ${
|
|
4345
|
+
if (!ss.ok) {
|
|
4346
|
+
return `Could not screenshot ${url}: ${ss.value}`;
|
|
4266
4347
|
}
|
|
4267
|
-
imageUrl =
|
|
4348
|
+
imageUrl = ss.value;
|
|
4268
4349
|
}
|
|
4269
4350
|
const analysis = await analyzeImage({
|
|
4270
4351
|
prompt: analysisPrompt,
|
|
@@ -4430,7 +4511,7 @@ ${context}
|
|
|
4430
4511
|
<brief>
|
|
4431
4512
|
${brief}
|
|
4432
4513
|
</brief>`;
|
|
4433
|
-
const enhanced = await
|
|
4514
|
+
const enhanced = await runMindstudioCliResult(
|
|
4434
4515
|
[
|
|
4435
4516
|
"generate-text",
|
|
4436
4517
|
"--message",
|
|
@@ -4440,7 +4521,11 @@ ${brief}
|
|
|
4440
4521
|
],
|
|
4441
4522
|
{ outputKey: "content", timeout: 6e4, onLog, caller: "designExpert" }
|
|
4442
4523
|
);
|
|
4443
|
-
|
|
4524
|
+
if (!enhanced.ok) {
|
|
4525
|
+
onLog?.(`[enhancePrompt] enhancement failed, using original brief`);
|
|
4526
|
+
return brief;
|
|
4527
|
+
}
|
|
4528
|
+
return enhanced.value.trim();
|
|
4444
4529
|
}
|
|
4445
4530
|
|
|
4446
4531
|
// src/subagents/designExpert/tools/images/imageGenerator.ts
|
|
@@ -4492,7 +4577,7 @@ async function generateImageAssets(opts) {
|
|
|
4492
4577
|
config
|
|
4493
4578
|
}
|
|
4494
4579
|
});
|
|
4495
|
-
const
|
|
4580
|
+
const res = await runMindstudioCliResult(["generate-image"], {
|
|
4496
4581
|
outputKey: "imageUrl",
|
|
4497
4582
|
jsonLogs: true,
|
|
4498
4583
|
timeout: 2e5,
|
|
@@ -4500,7 +4585,7 @@ async function generateImageAssets(opts) {
|
|
|
4500
4585
|
stdin: step,
|
|
4501
4586
|
caller: "designExpert"
|
|
4502
4587
|
});
|
|
4503
|
-
imageUrls = [
|
|
4588
|
+
imageUrls = [res.ok ? res.value : `Error: ${res.value}`];
|
|
4504
4589
|
} else {
|
|
4505
4590
|
const steps = enhancedPrompts.map((prompt) => ({
|
|
4506
4591
|
stepType: "generateImage",
|
|
@@ -4512,20 +4597,23 @@ async function generateImageAssets(opts) {
|
|
|
4512
4597
|
}
|
|
4513
4598
|
}
|
|
4514
4599
|
}));
|
|
4515
|
-
const
|
|
4600
|
+
const batchRes = await runMindstudioCliResult(["batch"], {
|
|
4516
4601
|
jsonLogs: true,
|
|
4517
4602
|
timeout: 2e5,
|
|
4518
4603
|
onLog,
|
|
4519
4604
|
stdin: JSON.stringify(steps),
|
|
4520
4605
|
caller: "designExpert"
|
|
4521
4606
|
});
|
|
4607
|
+
if (!batchRes.ok) {
|
|
4608
|
+
return batchRes.value;
|
|
4609
|
+
}
|
|
4522
4610
|
try {
|
|
4523
|
-
const parsed = JSON.parse(
|
|
4611
|
+
const parsed = JSON.parse(batchRes.value);
|
|
4524
4612
|
imageUrls = parsed.map(
|
|
4525
4613
|
(r) => r.output?.imageUrl ?? `Error: ${r.error}`
|
|
4526
4614
|
);
|
|
4527
4615
|
} catch {
|
|
4528
|
-
return
|
|
4616
|
+
return batchRes.value;
|
|
4529
4617
|
}
|
|
4530
4618
|
}
|
|
4531
4619
|
if (transparentBackground) {
|
|
@@ -4534,7 +4622,7 @@ async function generateImageAssets(opts) {
|
|
|
4534
4622
|
if (url.startsWith("Error")) {
|
|
4535
4623
|
return url;
|
|
4536
4624
|
}
|
|
4537
|
-
const result = await
|
|
4625
|
+
const result = await runMindstudioCliResult(
|
|
4538
4626
|
["remove-background-from-image", "--image-url", url],
|
|
4539
4627
|
{
|
|
4540
4628
|
outputKey: "imageUrl",
|
|
@@ -4543,7 +4631,7 @@ async function generateImageAssets(opts) {
|
|
|
4543
4631
|
caller: "designExpert"
|
|
4544
4632
|
}
|
|
4545
4633
|
);
|
|
4546
|
-
return result.
|
|
4634
|
+
return result.ok ? result.value : url;
|
|
4547
4635
|
})
|
|
4548
4636
|
);
|
|
4549
4637
|
}
|
|
@@ -5773,7 +5861,11 @@ var scrapeWebUrlTool = {
|
|
|
5773
5861
|
"--page-options",
|
|
5774
5862
|
JSON.stringify(pageOptions)
|
|
5775
5863
|
],
|
|
5776
|
-
{
|
|
5864
|
+
{
|
|
5865
|
+
onLog: context?.onLog,
|
|
5866
|
+
maxBuffer: SCRAPE_MAX_BUFFER,
|
|
5867
|
+
caller: "parent"
|
|
5868
|
+
}
|
|
5777
5869
|
);
|
|
5778
5870
|
}
|
|
5779
5871
|
};
|
|
@@ -6309,6 +6401,14 @@ var ARCHIVE_DIR = ".logs/sessions";
|
|
|
6309
6401
|
var ROTATE_THRESHOLD_BYTES = 32 * 1024 * 1024;
|
|
6310
6402
|
var RETAIN_TAIL_BYTES = 16 * 1024 * 1024;
|
|
6311
6403
|
var ARCHIVE_RETENTION_BYTES = 64 * 1024 * 1024;
|
|
6404
|
+
var ARCHIVE_NAME_RE = /^(cleared|rotated)-.*\.json$/;
|
|
6405
|
+
var archiveSortKey = (name) => name.replace(/^(cleared|rotated)-/, "");
|
|
6406
|
+
var ARCHIVE_COUNT_RE = /\.c(\d+)\.json$/;
|
|
6407
|
+
var HISTORY_DEFAULT_LIMIT = 500;
|
|
6408
|
+
var HISTORY_MAX_LIMIT = 2e3;
|
|
6409
|
+
var archiveCountCache = /* @__PURE__ */ new Map();
|
|
6410
|
+
var archiveMsgCache = /* @__PURE__ */ new Map();
|
|
6411
|
+
var ARCHIVE_MSG_CACHE_MAX = 3;
|
|
6312
6412
|
function loadSession(state) {
|
|
6313
6413
|
pruneArchives();
|
|
6314
6414
|
try {
|
|
@@ -6387,31 +6487,34 @@ function buildPayload(state) {
|
|
|
6387
6487
|
function archiveMessages(messages, label, models) {
|
|
6388
6488
|
fs21.mkdirSync(ARCHIVE_DIR, { recursive: true });
|
|
6389
6489
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
6390
|
-
|
|
6490
|
+
const count = messages.length;
|
|
6491
|
+
let dest = path11.join(ARCHIVE_DIR, `${label}-${ts}.c${count}.json`);
|
|
6391
6492
|
let n = 1;
|
|
6392
6493
|
while (fs21.existsSync(dest)) {
|
|
6393
|
-
dest = path11.join(ARCHIVE_DIR, `${label}-${ts}-${n++}.json`);
|
|
6494
|
+
dest = path11.join(ARCHIVE_DIR, `${label}-${ts}-${n++}.c${count}.json`);
|
|
6394
6495
|
}
|
|
6395
6496
|
const payload = { messages };
|
|
6396
6497
|
if (models && Object.keys(models).length > 0) {
|
|
6397
6498
|
payload.models = models;
|
|
6398
6499
|
}
|
|
6399
6500
|
fs21.writeFileSync(dest, JSON.stringify(payload), "utf-8");
|
|
6400
|
-
|
|
6501
|
+
archiveCountCache.set(path11.basename(dest), count);
|
|
6502
|
+
log9.info("Session archived", { label, dest, messageCount: count });
|
|
6401
6503
|
pruneArchives();
|
|
6402
6504
|
return dest;
|
|
6403
6505
|
}
|
|
6404
6506
|
function pruneArchives() {
|
|
6405
6507
|
try {
|
|
6406
|
-
const entries = fs21.readdirSync(ARCHIVE_DIR).filter((name) =>
|
|
6508
|
+
const entries = fs21.readdirSync(ARCHIVE_DIR).filter((name) => ARCHIVE_NAME_RE.test(name));
|
|
6407
6509
|
if (entries.length <= 1) {
|
|
6408
6510
|
return;
|
|
6409
6511
|
}
|
|
6410
|
-
const sortKey = (name) => name.replace(/^(cleared|rotated)-/, "");
|
|
6411
6512
|
const archives = entries.map((name) => ({
|
|
6412
6513
|
name,
|
|
6413
6514
|
size: fs21.statSync(path11.join(ARCHIVE_DIR, name)).size
|
|
6414
|
-
})).sort(
|
|
6515
|
+
})).sort(
|
|
6516
|
+
(a, b) => archiveSortKey(b.name).localeCompare(archiveSortKey(a.name))
|
|
6517
|
+
);
|
|
6415
6518
|
let kept = 0;
|
|
6416
6519
|
let cut = archives.length;
|
|
6417
6520
|
for (let i = 0; i < archives.length; i++) {
|
|
@@ -6442,6 +6545,129 @@ function pruneArchives() {
|
|
|
6442
6545
|
} catch {
|
|
6443
6546
|
}
|
|
6444
6547
|
}
|
|
6548
|
+
function parseArchive(name) {
|
|
6549
|
+
const cached3 = archiveMsgCache.get(name);
|
|
6550
|
+
if (cached3) {
|
|
6551
|
+
archiveMsgCache.delete(name);
|
|
6552
|
+
archiveMsgCache.set(name, cached3);
|
|
6553
|
+
return cached3;
|
|
6554
|
+
}
|
|
6555
|
+
try {
|
|
6556
|
+
const raw = fs21.readFileSync(path11.join(ARCHIVE_DIR, name), "utf-8");
|
|
6557
|
+
const data = JSON.parse(raw);
|
|
6558
|
+
const messages = Array.isArray(data?.messages) ? data.messages : [];
|
|
6559
|
+
archiveCountCache.set(name, messages.length);
|
|
6560
|
+
archiveMsgCache.set(name, messages);
|
|
6561
|
+
while (archiveMsgCache.size > ARCHIVE_MSG_CACHE_MAX) {
|
|
6562
|
+
const oldest = archiveMsgCache.keys().next().value;
|
|
6563
|
+
if (oldest === void 0) {
|
|
6564
|
+
break;
|
|
6565
|
+
}
|
|
6566
|
+
archiveMsgCache.delete(oldest);
|
|
6567
|
+
}
|
|
6568
|
+
return messages;
|
|
6569
|
+
} catch (err) {
|
|
6570
|
+
log9.warn("Session archive unreadable", { name, error: err?.message });
|
|
6571
|
+
return null;
|
|
6572
|
+
}
|
|
6573
|
+
}
|
|
6574
|
+
function archiveCount(name) {
|
|
6575
|
+
const cached3 = archiveCountCache.get(name);
|
|
6576
|
+
if (cached3 !== void 0) {
|
|
6577
|
+
return cached3;
|
|
6578
|
+
}
|
|
6579
|
+
const m = ARCHIVE_COUNT_RE.exec(name);
|
|
6580
|
+
if (m) {
|
|
6581
|
+
const n = Number(m[1]);
|
|
6582
|
+
archiveCountCache.set(name, n);
|
|
6583
|
+
return n;
|
|
6584
|
+
}
|
|
6585
|
+
const msgs = parseArchive(name);
|
|
6586
|
+
return msgs ? msgs.length : null;
|
|
6587
|
+
}
|
|
6588
|
+
function readArchiveMessages(name) {
|
|
6589
|
+
return parseArchive(name) ?? [];
|
|
6590
|
+
}
|
|
6591
|
+
function listConversationArchives() {
|
|
6592
|
+
let names;
|
|
6593
|
+
try {
|
|
6594
|
+
names = fs21.readdirSync(ARCHIVE_DIR).filter((n) => ARCHIVE_NAME_RE.test(n));
|
|
6595
|
+
} catch {
|
|
6596
|
+
return { slots: [], archivedCount: 0 };
|
|
6597
|
+
}
|
|
6598
|
+
let maxClearedKey = null;
|
|
6599
|
+
for (const name of names) {
|
|
6600
|
+
if (name.startsWith("cleared-")) {
|
|
6601
|
+
const key = archiveSortKey(name);
|
|
6602
|
+
if (maxClearedKey === null || key > maxClearedKey) {
|
|
6603
|
+
maxClearedKey = key;
|
|
6604
|
+
}
|
|
6605
|
+
}
|
|
6606
|
+
}
|
|
6607
|
+
const rotated = names.filter((n) => n.startsWith("rotated-")).filter((n) => maxClearedKey === null || archiveSortKey(n) > maxClearedKey).sort((a, b) => archiveSortKey(a).localeCompare(archiveSortKey(b)));
|
|
6608
|
+
const slots = [];
|
|
6609
|
+
let offset = 0;
|
|
6610
|
+
for (const name of rotated) {
|
|
6611
|
+
const count = archiveCount(name);
|
|
6612
|
+
if (count === null || count <= 0) {
|
|
6613
|
+
continue;
|
|
6614
|
+
}
|
|
6615
|
+
slots.push({ name, count, offset });
|
|
6616
|
+
offset += count;
|
|
6617
|
+
}
|
|
6618
|
+
return { slots, archivedCount: offset };
|
|
6619
|
+
}
|
|
6620
|
+
function getHistoryPage(state, opts) {
|
|
6621
|
+
const { slots, archivedCount } = listConversationArchives();
|
|
6622
|
+
const liveLen = state.messages.length;
|
|
6623
|
+
const total = archivedCount + liveLen;
|
|
6624
|
+
const rawLimit = opts?.limit;
|
|
6625
|
+
const limit = typeof rawLimit === "number" && Number.isFinite(rawLimit) ? Math.min(Math.max(1, rawLimit | 0), HISTORY_MAX_LIMIT) : HISTORY_DEFAULT_LIMIT;
|
|
6626
|
+
const rawBefore = opts?.before;
|
|
6627
|
+
const before = typeof rawBefore === "number" && Number.isFinite(rawBefore) ? Math.max(0, Math.min(rawBefore | 0, total)) : total;
|
|
6628
|
+
const peekGlobal = (i) => {
|
|
6629
|
+
if (i >= archivedCount) {
|
|
6630
|
+
return state.messages[i - archivedCount];
|
|
6631
|
+
}
|
|
6632
|
+
for (const slot of slots) {
|
|
6633
|
+
if (i < slot.offset + slot.count) {
|
|
6634
|
+
return readArchiveMessages(slot.name)[i - slot.offset];
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6637
|
+
return void 0;
|
|
6638
|
+
};
|
|
6639
|
+
let startIndex = Math.max(0, before - limit);
|
|
6640
|
+
while (startIndex > 0) {
|
|
6641
|
+
const msg = peekGlobal(startIndex);
|
|
6642
|
+
if (msg && msg.role === "user" && msg.toolCallId) {
|
|
6643
|
+
startIndex--;
|
|
6644
|
+
} else {
|
|
6645
|
+
break;
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
const endIndex = before;
|
|
6649
|
+
const messages = [];
|
|
6650
|
+
for (const slot of slots) {
|
|
6651
|
+
const slotEnd = slot.offset + slot.count;
|
|
6652
|
+
if (slotEnd <= startIndex || slot.offset >= endIndex) {
|
|
6653
|
+
continue;
|
|
6654
|
+
}
|
|
6655
|
+
const from = Math.max(startIndex, slot.offset) - slot.offset;
|
|
6656
|
+
const to = Math.min(endIndex, slotEnd) - slot.offset;
|
|
6657
|
+
const msgs = readArchiveMessages(slot.name);
|
|
6658
|
+
for (let i = from; i < to; i++) {
|
|
6659
|
+
messages.push(msgs[i]);
|
|
6660
|
+
}
|
|
6661
|
+
}
|
|
6662
|
+
if (endIndex > archivedCount) {
|
|
6663
|
+
const from = Math.max(startIndex, archivedCount) - archivedCount;
|
|
6664
|
+
const to = endIndex - archivedCount;
|
|
6665
|
+
for (let i = from; i < to; i++) {
|
|
6666
|
+
messages.push(state.messages[i]);
|
|
6667
|
+
}
|
|
6668
|
+
}
|
|
6669
|
+
return { messages, startIndex, endIndex, totalMessageCount: total };
|
|
6670
|
+
}
|
|
6445
6671
|
function rotate(state) {
|
|
6446
6672
|
const messages = state.messages;
|
|
6447
6673
|
if (messages.length === 0) {
|
|
@@ -7979,8 +8205,6 @@ var USER_FACING_TOOLS = /* @__PURE__ */ new Set([
|
|
|
7979
8205
|
"presentPublishPlan"
|
|
7980
8206
|
]);
|
|
7981
8207
|
var FORCED_COMPACTION_THRESHOLD_TOKENS = 85e4;
|
|
7982
|
-
var HISTORY_DEFAULT_LIMIT = 500;
|
|
7983
|
-
var HISTORY_MAX_LIMIT = 2e3;
|
|
7984
8208
|
var HeadlessSession = class {
|
|
7985
8209
|
// Configuration
|
|
7986
8210
|
opts;
|
|
@@ -8726,30 +8950,24 @@ var HeadlessSession = class {
|
|
|
8726
8950
|
}
|
|
8727
8951
|
if (action === "get_history") {
|
|
8728
8952
|
this.applyPendingBlockUpdates();
|
|
8729
|
-
const
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
const before = typeof rawBefore === "number" && Number.isFinite(rawBefore) ? Math.max(0, Math.min(rawBefore | 0, total)) : total;
|
|
8734
|
-
let startIndex = Math.max(0, before - limit);
|
|
8735
|
-
while (startIndex > 0 && this.state.messages[startIndex].role === "user" && this.state.messages[startIndex].toolCallId) {
|
|
8736
|
-
startIndex--;
|
|
8737
|
-
}
|
|
8738
|
-
const endIndex = before;
|
|
8953
|
+
const page = getHistoryPage(this.state, {
|
|
8954
|
+
...typeof parsed.before === "number" ? { before: parsed.before } : {},
|
|
8955
|
+
...typeof parsed.limit === "number" ? { limit: parsed.limit } : {}
|
|
8956
|
+
});
|
|
8739
8957
|
log15.info("History response", {
|
|
8740
8958
|
requestId,
|
|
8741
|
-
startIndex,
|
|
8742
|
-
endIndex,
|
|
8743
|
-
count: endIndex - startIndex,
|
|
8744
|
-
totalMessageCount:
|
|
8745
|
-
beforeParam:
|
|
8746
|
-
limitParam:
|
|
8959
|
+
startIndex: page.startIndex,
|
|
8960
|
+
endIndex: page.endIndex,
|
|
8961
|
+
count: page.endIndex - page.startIndex,
|
|
8962
|
+
totalMessageCount: page.totalMessageCount,
|
|
8963
|
+
beforeParam: parsed.before,
|
|
8964
|
+
limitParam: parsed.limit
|
|
8747
8965
|
});
|
|
8748
8966
|
this.dispatchSimple(requestId, "history", () => ({
|
|
8749
|
-
messages:
|
|
8750
|
-
startIndex,
|
|
8751
|
-
endIndex,
|
|
8752
|
-
totalMessageCount:
|
|
8967
|
+
messages: page.messages,
|
|
8968
|
+
startIndex: page.startIndex,
|
|
8969
|
+
endIndex: page.endIndex,
|
|
8970
|
+
totalMessageCount: page.totalMessageCount,
|
|
8753
8971
|
running: this.running,
|
|
8754
8972
|
...this.running && this.currentRequestId ? { currentRequestId: this.currentRequestId } : {},
|
|
8755
8973
|
...this.state.models && { models: this.state.models },
|
package/dist/index.js
CHANGED
|
@@ -1169,6 +1169,12 @@ var init_confirmDestructiveAction = __esm({
|
|
|
1169
1169
|
|
|
1170
1170
|
// src/subagents/common/runCli.ts
|
|
1171
1171
|
import { spawn } from "child_process";
|
|
1172
|
+
function formatCliResult(r) {
|
|
1173
|
+
const logBlock = r.logs.length > 0 ? r.logs.join("\n") + "\n\n" : "";
|
|
1174
|
+
const body = r.ok ? r.output : `Error: ${r.output}`;
|
|
1175
|
+
const truncNote = r.truncated ? "\n\n[output truncated]" : "";
|
|
1176
|
+
return logBlock + body + truncNote;
|
|
1177
|
+
}
|
|
1172
1178
|
function runCli(command, args2, options) {
|
|
1173
1179
|
return new Promise((resolve2) => {
|
|
1174
1180
|
const timeout = options?.timeout ?? 6e4;
|
|
@@ -1177,35 +1183,71 @@ function runCli(command, args2, options) {
|
|
|
1177
1183
|
if (options?.jsonLogs && !args2.includes("--json-logs")) {
|
|
1178
1184
|
finalArgs = args2.length > 0 ? [args2[0], "--json-logs", ...args2.slice(1)] : ["--json-logs"];
|
|
1179
1185
|
}
|
|
1180
|
-
const child = spawn(command, finalArgs, {
|
|
1181
|
-
stdio: [options?.stdin ? "pipe" : "ignore", "pipe", "pipe"]
|
|
1182
|
-
});
|
|
1183
|
-
if (options?.stdin) {
|
|
1184
|
-
child.stdin.write(options.stdin);
|
|
1185
|
-
child.stdin.end();
|
|
1186
|
-
}
|
|
1187
1186
|
const logs = [];
|
|
1188
1187
|
let stdout = "";
|
|
1189
1188
|
let stderr = "";
|
|
1190
1189
|
let stdoutSize = 0;
|
|
1191
1190
|
let stderrSize = 0;
|
|
1192
1191
|
let killed = false;
|
|
1192
|
+
let timedOut = false;
|
|
1193
|
+
let truncated = false;
|
|
1194
|
+
let settled = false;
|
|
1195
|
+
let timer;
|
|
1196
|
+
let killTimer;
|
|
1197
|
+
const finish = (result) => {
|
|
1198
|
+
if (settled) {
|
|
1199
|
+
return;
|
|
1200
|
+
}
|
|
1201
|
+
settled = true;
|
|
1202
|
+
if (timer) {
|
|
1203
|
+
clearTimeout(timer);
|
|
1204
|
+
}
|
|
1205
|
+
if (killTimer) {
|
|
1206
|
+
clearTimeout(killTimer);
|
|
1207
|
+
}
|
|
1208
|
+
resolve2(result);
|
|
1209
|
+
};
|
|
1210
|
+
const child = spawn(command, finalArgs, {
|
|
1211
|
+
stdio: [options?.stdin ? "pipe" : "ignore", "pipe", "pipe"]
|
|
1212
|
+
});
|
|
1213
|
+
child.on("error", (err) => {
|
|
1214
|
+
finish({
|
|
1215
|
+
ok: false,
|
|
1216
|
+
output: err.message,
|
|
1217
|
+
logs,
|
|
1218
|
+
timedOut: false,
|
|
1219
|
+
truncated: false
|
|
1220
|
+
});
|
|
1221
|
+
});
|
|
1222
|
+
if (options?.stdin) {
|
|
1223
|
+
child.stdin.on("error", () => {
|
|
1224
|
+
});
|
|
1225
|
+
try {
|
|
1226
|
+
child.stdin.write(options.stdin);
|
|
1227
|
+
child.stdin.end();
|
|
1228
|
+
} catch {
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
const killForOverflow = () => {
|
|
1232
|
+
if (killed) {
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
killed = true;
|
|
1236
|
+
truncated = true;
|
|
1237
|
+
child.kill();
|
|
1238
|
+
};
|
|
1193
1239
|
child.stdout.on("data", (chunk) => {
|
|
1194
1240
|
stdoutSize += chunk.length;
|
|
1195
1241
|
if (stdoutSize <= maxBuffer) {
|
|
1196
1242
|
stdout += chunk.toString();
|
|
1197
|
-
} else
|
|
1198
|
-
|
|
1199
|
-
child.kill();
|
|
1243
|
+
} else {
|
|
1244
|
+
killForOverflow();
|
|
1200
1245
|
}
|
|
1201
1246
|
});
|
|
1202
1247
|
child.stderr.on("data", (chunk) => {
|
|
1203
1248
|
stderrSize += chunk.length;
|
|
1204
1249
|
if (stderrSize > maxBuffer) {
|
|
1205
|
-
|
|
1206
|
-
killed = true;
|
|
1207
|
-
child.kill();
|
|
1208
|
-
}
|
|
1250
|
+
killForOverflow();
|
|
1209
1251
|
return;
|
|
1210
1252
|
}
|
|
1211
1253
|
const text = chunk.toString();
|
|
@@ -1230,30 +1272,48 @@ function runCli(command, args2, options) {
|
|
|
1230
1272
|
}
|
|
1231
1273
|
}
|
|
1232
1274
|
});
|
|
1233
|
-
|
|
1275
|
+
timer = setTimeout(() => {
|
|
1276
|
+
if (killed) {
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1234
1279
|
killed = true;
|
|
1280
|
+
timedOut = true;
|
|
1235
1281
|
child.kill();
|
|
1282
|
+
killTimer = setTimeout(() => child.kill("SIGKILL"), SIGKILL_GRACE_MS);
|
|
1236
1283
|
}, timeout);
|
|
1237
1284
|
child.on("close", (code) => {
|
|
1238
|
-
clearTimeout(timer);
|
|
1239
|
-
const logBlock = !options?.onLog && logs.length > 0 ? logs.join("\n") + "\n\n" : "";
|
|
1240
1285
|
const out = stdout.trim();
|
|
1241
|
-
if (
|
|
1242
|
-
|
|
1286
|
+
if (timedOut) {
|
|
1287
|
+
finish({
|
|
1288
|
+
ok: false,
|
|
1289
|
+
output: stderr.trim() || "Process timed out",
|
|
1290
|
+
logs,
|
|
1291
|
+
timedOut: true,
|
|
1292
|
+
truncated
|
|
1293
|
+
});
|
|
1243
1294
|
return;
|
|
1244
1295
|
}
|
|
1245
|
-
if (
|
|
1246
|
-
|
|
1247
|
-
resolve2(logBlock + `Error: ${errMsg}`);
|
|
1296
|
+
if (out) {
|
|
1297
|
+
finish({ ok: true, output: out, logs, timedOut: false, truncated });
|
|
1248
1298
|
return;
|
|
1249
1299
|
}
|
|
1250
|
-
|
|
1300
|
+
finish({
|
|
1301
|
+
ok: false,
|
|
1302
|
+
output: stderr.trim() || (code !== 0 ? `Exit code ${code}` : "(no response)"),
|
|
1303
|
+
logs,
|
|
1304
|
+
timedOut: false,
|
|
1305
|
+
truncated
|
|
1306
|
+
});
|
|
1251
1307
|
});
|
|
1252
1308
|
});
|
|
1253
1309
|
}
|
|
1310
|
+
var SCRAPE_MAX_BUFFER, SEARCH_MAX_BUFFER, SIGKILL_GRACE_MS;
|
|
1254
1311
|
var init_runCli = __esm({
|
|
1255
1312
|
"src/subagents/common/runCli.ts"() {
|
|
1256
1313
|
"use strict";
|
|
1314
|
+
SCRAPE_MAX_BUFFER = 4 * 1024 * 1024;
|
|
1315
|
+
SEARCH_MAX_BUFFER = 512 * 1024;
|
|
1316
|
+
SIGKILL_GRACE_MS = 2e3;
|
|
1257
1317
|
}
|
|
1258
1318
|
});
|
|
1259
1319
|
|
|
@@ -1281,11 +1341,12 @@ var init_sdkConsultant = __esm({
|
|
|
1281
1341
|
},
|
|
1282
1342
|
async execute(input, context) {
|
|
1283
1343
|
const query = input.query;
|
|
1284
|
-
|
|
1344
|
+
const result = await runCli("mindstudio", ["ask", query], {
|
|
1285
1345
|
timeout: 2e5,
|
|
1286
1346
|
maxBuffer: 512 * 1024,
|
|
1287
1347
|
onLog: context?.onLog
|
|
1288
1348
|
});
|
|
1349
|
+
return formatCliResult(result);
|
|
1289
1350
|
}
|
|
1290
1351
|
};
|
|
1291
1352
|
}
|
|
@@ -1331,17 +1392,21 @@ function stripFlags(args2) {
|
|
|
1331
1392
|
}
|
|
1332
1393
|
return out;
|
|
1333
1394
|
}
|
|
1334
|
-
async function
|
|
1395
|
+
async function runMindstudioCliResult(args2, options) {
|
|
1335
1396
|
const cleanArgs = stripFlags(args2);
|
|
1336
1397
|
const cliAction = args2[0];
|
|
1337
1398
|
const agentName = options?.caller ?? "mindstudio-cli";
|
|
1338
1399
|
const start = Date.now();
|
|
1339
|
-
const
|
|
1400
|
+
const res = await runCli("mindstudio", cleanArgs, options);
|
|
1401
|
+
if (!res.ok) {
|
|
1402
|
+
return { ok: false, value: formatCliResult(res) };
|
|
1403
|
+
}
|
|
1404
|
+
const truncNote = res.truncated ? "\n\n[output truncated]" : "";
|
|
1340
1405
|
let envelope;
|
|
1341
1406
|
try {
|
|
1342
|
-
envelope = JSON.parse(
|
|
1407
|
+
envelope = JSON.parse(res.output);
|
|
1343
1408
|
} catch {
|
|
1344
|
-
return
|
|
1409
|
+
return { ok: true, value: res.output + truncNote };
|
|
1345
1410
|
}
|
|
1346
1411
|
if (envelope && typeof envelope === "object" && Array.isArray(envelope.results)) {
|
|
1347
1412
|
const durationMs = Date.now() - start;
|
|
@@ -1359,7 +1424,7 @@ async function runMindstudioCli(args2, options) {
|
|
|
1359
1424
|
});
|
|
1360
1425
|
}
|
|
1361
1426
|
}
|
|
1362
|
-
return JSON.stringify(envelope.results);
|
|
1427
|
+
return { ok: true, value: JSON.stringify(envelope.results) + truncNote };
|
|
1363
1428
|
}
|
|
1364
1429
|
if (typeof envelope?.$billingCost === "number") {
|
|
1365
1430
|
recordUsage({
|
|
@@ -1380,11 +1445,18 @@ async function runMindstudioCli(args2, options) {
|
|
|
1380
1445
|
if (options?.outputKey) {
|
|
1381
1446
|
const v = envelope?.[options.outputKey];
|
|
1382
1447
|
if (v === void 0 || v === null) {
|
|
1383
|
-
return JSON.stringify(stripDollarKeys(envelope));
|
|
1448
|
+
return { ok: false, value: JSON.stringify(stripDollarKeys(envelope)) };
|
|
1384
1449
|
}
|
|
1385
|
-
|
|
1450
|
+
const value = typeof v === "string" ? v : JSON.stringify(v);
|
|
1451
|
+
return { ok: true, value: value + truncNote };
|
|
1386
1452
|
}
|
|
1387
|
-
return
|
|
1453
|
+
return {
|
|
1454
|
+
ok: true,
|
|
1455
|
+
value: JSON.stringify(stripDollarKeys(envelope)) + truncNote
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
async function runMindstudioCli(args2, options) {
|
|
1459
|
+
return (await runMindstudioCliResult(args2, options)).value;
|
|
1388
1460
|
}
|
|
1389
1461
|
function stripDollarKeys(envelope) {
|
|
1390
1462
|
if (!envelope || typeof envelope !== "object" || Array.isArray(envelope)) {
|
|
@@ -1412,6 +1484,7 @@ var init_searchGoogle = __esm({
|
|
|
1412
1484
|
"src/tools/common/searchGoogle.ts"() {
|
|
1413
1485
|
"use strict";
|
|
1414
1486
|
init_runMindstudioCli();
|
|
1487
|
+
init_runCli();
|
|
1415
1488
|
searchGoogleTool = {
|
|
1416
1489
|
clearable: false,
|
|
1417
1490
|
definition: {
|
|
@@ -1432,7 +1505,12 @@ var init_searchGoogle = __esm({
|
|
|
1432
1505
|
const query = input.query;
|
|
1433
1506
|
return runMindstudioCli(
|
|
1434
1507
|
["search-google", "--query", query, "--export-type", "json"],
|
|
1435
|
-
{
|
|
1508
|
+
{
|
|
1509
|
+
outputKey: "results",
|
|
1510
|
+
maxBuffer: SEARCH_MAX_BUFFER,
|
|
1511
|
+
onLog: context?.onLog,
|
|
1512
|
+
caller: "parent"
|
|
1513
|
+
}
|
|
1436
1514
|
);
|
|
1437
1515
|
}
|
|
1438
1516
|
};
|
|
@@ -2011,6 +2089,9 @@ var init_surfaces = __esm({
|
|
|
2011
2089
|
"claude-fable-5",
|
|
2012
2090
|
"claude-5-sonnet",
|
|
2013
2091
|
"gpt-5.5",
|
|
2092
|
+
"gpt-5.6-sol",
|
|
2093
|
+
"gpt-5.6-terra",
|
|
2094
|
+
"gpt-5.6-luna",
|
|
2014
2095
|
"gemini-3-pro",
|
|
2015
2096
|
"gemini-3.1-pro",
|
|
2016
2097
|
"gemini-3-flash",
|
|
@@ -2314,31 +2395,34 @@ function buildPayload(state) {
|
|
|
2314
2395
|
function archiveMessages(messages, label, models) {
|
|
2315
2396
|
fs10.mkdirSync(ARCHIVE_DIR, { recursive: true });
|
|
2316
2397
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2317
|
-
|
|
2398
|
+
const count = messages.length;
|
|
2399
|
+
let dest = path4.join(ARCHIVE_DIR, `${label}-${ts}.c${count}.json`);
|
|
2318
2400
|
let n = 1;
|
|
2319
2401
|
while (fs10.existsSync(dest)) {
|
|
2320
|
-
dest = path4.join(ARCHIVE_DIR, `${label}-${ts}-${n++}.json`);
|
|
2402
|
+
dest = path4.join(ARCHIVE_DIR, `${label}-${ts}-${n++}.c${count}.json`);
|
|
2321
2403
|
}
|
|
2322
2404
|
const payload = { messages };
|
|
2323
2405
|
if (models && Object.keys(models).length > 0) {
|
|
2324
2406
|
payload.models = models;
|
|
2325
2407
|
}
|
|
2326
2408
|
fs10.writeFileSync(dest, JSON.stringify(payload), "utf-8");
|
|
2327
|
-
|
|
2409
|
+
archiveCountCache.set(path4.basename(dest), count);
|
|
2410
|
+
log3.info("Session archived", { label, dest, messageCount: count });
|
|
2328
2411
|
pruneArchives();
|
|
2329
2412
|
return dest;
|
|
2330
2413
|
}
|
|
2331
2414
|
function pruneArchives() {
|
|
2332
2415
|
try {
|
|
2333
|
-
const entries = fs10.readdirSync(ARCHIVE_DIR).filter((name) =>
|
|
2416
|
+
const entries = fs10.readdirSync(ARCHIVE_DIR).filter((name) => ARCHIVE_NAME_RE.test(name));
|
|
2334
2417
|
if (entries.length <= 1) {
|
|
2335
2418
|
return;
|
|
2336
2419
|
}
|
|
2337
|
-
const sortKey = (name) => name.replace(/^(cleared|rotated)-/, "");
|
|
2338
2420
|
const archives = entries.map((name) => ({
|
|
2339
2421
|
name,
|
|
2340
2422
|
size: fs10.statSync(path4.join(ARCHIVE_DIR, name)).size
|
|
2341
|
-
})).sort(
|
|
2423
|
+
})).sort(
|
|
2424
|
+
(a, b) => archiveSortKey(b.name).localeCompare(archiveSortKey(a.name))
|
|
2425
|
+
);
|
|
2342
2426
|
let kept = 0;
|
|
2343
2427
|
let cut = archives.length;
|
|
2344
2428
|
for (let i = 0; i < archives.length; i++) {
|
|
@@ -2369,6 +2453,129 @@ function pruneArchives() {
|
|
|
2369
2453
|
} catch {
|
|
2370
2454
|
}
|
|
2371
2455
|
}
|
|
2456
|
+
function parseArchive(name) {
|
|
2457
|
+
const cached3 = archiveMsgCache.get(name);
|
|
2458
|
+
if (cached3) {
|
|
2459
|
+
archiveMsgCache.delete(name);
|
|
2460
|
+
archiveMsgCache.set(name, cached3);
|
|
2461
|
+
return cached3;
|
|
2462
|
+
}
|
|
2463
|
+
try {
|
|
2464
|
+
const raw = fs10.readFileSync(path4.join(ARCHIVE_DIR, name), "utf-8");
|
|
2465
|
+
const data = JSON.parse(raw);
|
|
2466
|
+
const messages = Array.isArray(data?.messages) ? data.messages : [];
|
|
2467
|
+
archiveCountCache.set(name, messages.length);
|
|
2468
|
+
archiveMsgCache.set(name, messages);
|
|
2469
|
+
while (archiveMsgCache.size > ARCHIVE_MSG_CACHE_MAX) {
|
|
2470
|
+
const oldest = archiveMsgCache.keys().next().value;
|
|
2471
|
+
if (oldest === void 0) {
|
|
2472
|
+
break;
|
|
2473
|
+
}
|
|
2474
|
+
archiveMsgCache.delete(oldest);
|
|
2475
|
+
}
|
|
2476
|
+
return messages;
|
|
2477
|
+
} catch (err) {
|
|
2478
|
+
log3.warn("Session archive unreadable", { name, error: err?.message });
|
|
2479
|
+
return null;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
function archiveCount(name) {
|
|
2483
|
+
const cached3 = archiveCountCache.get(name);
|
|
2484
|
+
if (cached3 !== void 0) {
|
|
2485
|
+
return cached3;
|
|
2486
|
+
}
|
|
2487
|
+
const m = ARCHIVE_COUNT_RE.exec(name);
|
|
2488
|
+
if (m) {
|
|
2489
|
+
const n = Number(m[1]);
|
|
2490
|
+
archiveCountCache.set(name, n);
|
|
2491
|
+
return n;
|
|
2492
|
+
}
|
|
2493
|
+
const msgs = parseArchive(name);
|
|
2494
|
+
return msgs ? msgs.length : null;
|
|
2495
|
+
}
|
|
2496
|
+
function readArchiveMessages(name) {
|
|
2497
|
+
return parseArchive(name) ?? [];
|
|
2498
|
+
}
|
|
2499
|
+
function listConversationArchives() {
|
|
2500
|
+
let names;
|
|
2501
|
+
try {
|
|
2502
|
+
names = fs10.readdirSync(ARCHIVE_DIR).filter((n) => ARCHIVE_NAME_RE.test(n));
|
|
2503
|
+
} catch {
|
|
2504
|
+
return { slots: [], archivedCount: 0 };
|
|
2505
|
+
}
|
|
2506
|
+
let maxClearedKey = null;
|
|
2507
|
+
for (const name of names) {
|
|
2508
|
+
if (name.startsWith("cleared-")) {
|
|
2509
|
+
const key = archiveSortKey(name);
|
|
2510
|
+
if (maxClearedKey === null || key > maxClearedKey) {
|
|
2511
|
+
maxClearedKey = key;
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
const rotated = names.filter((n) => n.startsWith("rotated-")).filter((n) => maxClearedKey === null || archiveSortKey(n) > maxClearedKey).sort((a, b) => archiveSortKey(a).localeCompare(archiveSortKey(b)));
|
|
2516
|
+
const slots = [];
|
|
2517
|
+
let offset = 0;
|
|
2518
|
+
for (const name of rotated) {
|
|
2519
|
+
const count = archiveCount(name);
|
|
2520
|
+
if (count === null || count <= 0) {
|
|
2521
|
+
continue;
|
|
2522
|
+
}
|
|
2523
|
+
slots.push({ name, count, offset });
|
|
2524
|
+
offset += count;
|
|
2525
|
+
}
|
|
2526
|
+
return { slots, archivedCount: offset };
|
|
2527
|
+
}
|
|
2528
|
+
function getHistoryPage(state, opts) {
|
|
2529
|
+
const { slots, archivedCount } = listConversationArchives();
|
|
2530
|
+
const liveLen = state.messages.length;
|
|
2531
|
+
const total = archivedCount + liveLen;
|
|
2532
|
+
const rawLimit = opts?.limit;
|
|
2533
|
+
const limit = typeof rawLimit === "number" && Number.isFinite(rawLimit) ? Math.min(Math.max(1, rawLimit | 0), HISTORY_MAX_LIMIT) : HISTORY_DEFAULT_LIMIT;
|
|
2534
|
+
const rawBefore = opts?.before;
|
|
2535
|
+
const before = typeof rawBefore === "number" && Number.isFinite(rawBefore) ? Math.max(0, Math.min(rawBefore | 0, total)) : total;
|
|
2536
|
+
const peekGlobal = (i) => {
|
|
2537
|
+
if (i >= archivedCount) {
|
|
2538
|
+
return state.messages[i - archivedCount];
|
|
2539
|
+
}
|
|
2540
|
+
for (const slot of slots) {
|
|
2541
|
+
if (i < slot.offset + slot.count) {
|
|
2542
|
+
return readArchiveMessages(slot.name)[i - slot.offset];
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
return void 0;
|
|
2546
|
+
};
|
|
2547
|
+
let startIndex = Math.max(0, before - limit);
|
|
2548
|
+
while (startIndex > 0) {
|
|
2549
|
+
const msg = peekGlobal(startIndex);
|
|
2550
|
+
if (msg && msg.role === "user" && msg.toolCallId) {
|
|
2551
|
+
startIndex--;
|
|
2552
|
+
} else {
|
|
2553
|
+
break;
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
const endIndex = before;
|
|
2557
|
+
const messages = [];
|
|
2558
|
+
for (const slot of slots) {
|
|
2559
|
+
const slotEnd = slot.offset + slot.count;
|
|
2560
|
+
if (slotEnd <= startIndex || slot.offset >= endIndex) {
|
|
2561
|
+
continue;
|
|
2562
|
+
}
|
|
2563
|
+
const from = Math.max(startIndex, slot.offset) - slot.offset;
|
|
2564
|
+
const to = Math.min(endIndex, slotEnd) - slot.offset;
|
|
2565
|
+
const msgs = readArchiveMessages(slot.name);
|
|
2566
|
+
for (let i = from; i < to; i++) {
|
|
2567
|
+
messages.push(msgs[i]);
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
if (endIndex > archivedCount) {
|
|
2571
|
+
const from = Math.max(startIndex, archivedCount) - archivedCount;
|
|
2572
|
+
const to = endIndex - archivedCount;
|
|
2573
|
+
for (let i = from; i < to; i++) {
|
|
2574
|
+
messages.push(state.messages[i]);
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
return { messages, startIndex, endIndex, totalMessageCount: total };
|
|
2578
|
+
}
|
|
2372
2579
|
function rotate(state) {
|
|
2373
2580
|
const messages = state.messages;
|
|
2374
2581
|
if (messages.length === 0) {
|
|
@@ -2428,7 +2635,7 @@ function clearSession(state) {
|
|
|
2428
2635
|
});
|
|
2429
2636
|
}
|
|
2430
2637
|
}
|
|
2431
|
-
var log3, SESSION_FILE, ARCHIVE_DIR, ROTATE_THRESHOLD_BYTES, RETAIN_TAIL_BYTES, ARCHIVE_RETENTION_BYTES;
|
|
2638
|
+
var log3, SESSION_FILE, ARCHIVE_DIR, ROTATE_THRESHOLD_BYTES, RETAIN_TAIL_BYTES, ARCHIVE_RETENTION_BYTES, ARCHIVE_NAME_RE, archiveSortKey, ARCHIVE_COUNT_RE, HISTORY_DEFAULT_LIMIT, HISTORY_MAX_LIMIT, archiveCountCache, archiveMsgCache, ARCHIVE_MSG_CACHE_MAX;
|
|
2432
2639
|
var init_session = __esm({
|
|
2433
2640
|
"src/session.ts"() {
|
|
2434
2641
|
"use strict";
|
|
@@ -2442,6 +2649,14 @@ var init_session = __esm({
|
|
|
2442
2649
|
ROTATE_THRESHOLD_BYTES = 32 * 1024 * 1024;
|
|
2443
2650
|
RETAIN_TAIL_BYTES = 16 * 1024 * 1024;
|
|
2444
2651
|
ARCHIVE_RETENTION_BYTES = 64 * 1024 * 1024;
|
|
2652
|
+
ARCHIVE_NAME_RE = /^(cleared|rotated)-.*\.json$/;
|
|
2653
|
+
archiveSortKey = (name) => name.replace(/^(cleared|rotated)-/, "");
|
|
2654
|
+
ARCHIVE_COUNT_RE = /\.c(\d+)\.json$/;
|
|
2655
|
+
HISTORY_DEFAULT_LIMIT = 500;
|
|
2656
|
+
HISTORY_MAX_LIMIT = 2e3;
|
|
2657
|
+
archiveCountCache = /* @__PURE__ */ new Map();
|
|
2658
|
+
archiveMsgCache = /* @__PURE__ */ new Map();
|
|
2659
|
+
ARCHIVE_MSG_CACHE_MAX = 3;
|
|
2445
2660
|
}
|
|
2446
2661
|
});
|
|
2447
2662
|
|
|
@@ -4756,7 +4971,12 @@ __export(searchGoogle_exports, {
|
|
|
4756
4971
|
async function execute(input, onLog) {
|
|
4757
4972
|
return runMindstudioCli(
|
|
4758
4973
|
["search-google", "--query", input.query, "--export-type", "json"],
|
|
4759
|
-
{
|
|
4974
|
+
{
|
|
4975
|
+
outputKey: "results",
|
|
4976
|
+
onLog,
|
|
4977
|
+
caller: "designExpert",
|
|
4978
|
+
maxBuffer: SEARCH_MAX_BUFFER
|
|
4979
|
+
}
|
|
4760
4980
|
);
|
|
4761
4981
|
}
|
|
4762
4982
|
var definition;
|
|
@@ -4764,6 +4984,7 @@ var init_searchGoogle2 = __esm({
|
|
|
4764
4984
|
"src/subagents/designExpert/tools/searchGoogle.ts"() {
|
|
4765
4985
|
"use strict";
|
|
4766
4986
|
init_runMindstudioCli();
|
|
4987
|
+
init_runCli();
|
|
4767
4988
|
definition = {
|
|
4768
4989
|
clearable: false,
|
|
4769
4990
|
name: "searchGoogle",
|
|
@@ -4790,9 +5011,6 @@ __export(scrapeWebUrl_exports, {
|
|
|
4790
5011
|
});
|
|
4791
5012
|
async function execute2(input, onLog) {
|
|
4792
5013
|
const pageOptions = { onlyMainContent: true };
|
|
4793
|
-
if (input.screenshot) {
|
|
4794
|
-
pageOptions.screenshot = true;
|
|
4795
|
-
}
|
|
4796
5014
|
return runMindstudioCli(
|
|
4797
5015
|
[
|
|
4798
5016
|
"scrape-url",
|
|
@@ -4801,7 +5019,7 @@ async function execute2(input, onLog) {
|
|
|
4801
5019
|
"--page-options",
|
|
4802
5020
|
JSON.stringify(pageOptions)
|
|
4803
5021
|
],
|
|
4804
|
-
{ onLog, caller: "designExpert" }
|
|
5022
|
+
{ onLog, caller: "designExpert", maxBuffer: SCRAPE_MAX_BUFFER }
|
|
4805
5023
|
);
|
|
4806
5024
|
}
|
|
4807
5025
|
var definition2;
|
|
@@ -4809,6 +5027,7 @@ var init_scrapeWebUrl = __esm({
|
|
|
4809
5027
|
"src/subagents/designExpert/tools/scrapeWebUrl.ts"() {
|
|
4810
5028
|
"use strict";
|
|
4811
5029
|
init_runMindstudioCli();
|
|
5030
|
+
init_runCli();
|
|
4812
5031
|
definition2 = {
|
|
4813
5032
|
clearable: false,
|
|
4814
5033
|
name: "scrapeWebUrl",
|
|
@@ -4839,7 +5058,7 @@ async function execute3(input, onLog, context) {
|
|
|
4839
5058
|
const isImageUrl = /\.(png|jpe?g|webp|gif|svg|avif)(\?|$)/i.test(url);
|
|
4840
5059
|
let imageUrl = url;
|
|
4841
5060
|
if (!isImageUrl) {
|
|
4842
|
-
const
|
|
5061
|
+
const ss = await runMindstudioCliResult(
|
|
4843
5062
|
[
|
|
4844
5063
|
"screenshot-url",
|
|
4845
5064
|
"--url",
|
|
@@ -4858,10 +5077,10 @@ async function execute3(input, onLog, context) {
|
|
|
4858
5077
|
caller: "designExpert"
|
|
4859
5078
|
}
|
|
4860
5079
|
);
|
|
4861
|
-
if (
|
|
4862
|
-
return `Could not screenshot ${url}: ${
|
|
5080
|
+
if (!ss.ok) {
|
|
5081
|
+
return `Could not screenshot ${url}: ${ss.value}`;
|
|
4863
5082
|
}
|
|
4864
|
-
imageUrl =
|
|
5083
|
+
imageUrl = ss.value;
|
|
4865
5084
|
}
|
|
4866
5085
|
const analysis = await analyzeImage({
|
|
4867
5086
|
prompt: analysisPrompt,
|
|
@@ -5087,7 +5306,7 @@ ${context}
|
|
|
5087
5306
|
<brief>
|
|
5088
5307
|
${brief}
|
|
5089
5308
|
</brief>`;
|
|
5090
|
-
const enhanced = await
|
|
5309
|
+
const enhanced = await runMindstudioCliResult(
|
|
5091
5310
|
[
|
|
5092
5311
|
"generate-text",
|
|
5093
5312
|
"--message",
|
|
@@ -5097,7 +5316,11 @@ ${brief}
|
|
|
5097
5316
|
],
|
|
5098
5317
|
{ outputKey: "content", timeout: 6e4, onLog, caller: "designExpert" }
|
|
5099
5318
|
);
|
|
5100
|
-
|
|
5319
|
+
if (!enhanced.ok) {
|
|
5320
|
+
onLog?.(`[enhancePrompt] enhancement failed, using original brief`);
|
|
5321
|
+
return brief;
|
|
5322
|
+
}
|
|
5323
|
+
return enhanced.value.trim();
|
|
5101
5324
|
}
|
|
5102
5325
|
var SYSTEM_PROMPT;
|
|
5103
5326
|
var init_enhancePrompt = __esm({
|
|
@@ -5159,7 +5382,7 @@ async function generateImageAssets(opts) {
|
|
|
5159
5382
|
config
|
|
5160
5383
|
}
|
|
5161
5384
|
});
|
|
5162
|
-
const
|
|
5385
|
+
const res = await runMindstudioCliResult(["generate-image"], {
|
|
5163
5386
|
outputKey: "imageUrl",
|
|
5164
5387
|
jsonLogs: true,
|
|
5165
5388
|
timeout: 2e5,
|
|
@@ -5167,7 +5390,7 @@ async function generateImageAssets(opts) {
|
|
|
5167
5390
|
stdin: step,
|
|
5168
5391
|
caller: "designExpert"
|
|
5169
5392
|
});
|
|
5170
|
-
imageUrls = [
|
|
5393
|
+
imageUrls = [res.ok ? res.value : `Error: ${res.value}`];
|
|
5171
5394
|
} else {
|
|
5172
5395
|
const steps = enhancedPrompts.map((prompt) => ({
|
|
5173
5396
|
stepType: "generateImage",
|
|
@@ -5179,20 +5402,23 @@ async function generateImageAssets(opts) {
|
|
|
5179
5402
|
}
|
|
5180
5403
|
}
|
|
5181
5404
|
}));
|
|
5182
|
-
const
|
|
5405
|
+
const batchRes = await runMindstudioCliResult(["batch"], {
|
|
5183
5406
|
jsonLogs: true,
|
|
5184
5407
|
timeout: 2e5,
|
|
5185
5408
|
onLog,
|
|
5186
5409
|
stdin: JSON.stringify(steps),
|
|
5187
5410
|
caller: "designExpert"
|
|
5188
5411
|
});
|
|
5412
|
+
if (!batchRes.ok) {
|
|
5413
|
+
return batchRes.value;
|
|
5414
|
+
}
|
|
5189
5415
|
try {
|
|
5190
|
-
const parsed = JSON.parse(
|
|
5416
|
+
const parsed = JSON.parse(batchRes.value);
|
|
5191
5417
|
imageUrls = parsed.map(
|
|
5192
5418
|
(r) => r.output?.imageUrl ?? `Error: ${r.error}`
|
|
5193
5419
|
);
|
|
5194
5420
|
} catch {
|
|
5195
|
-
return
|
|
5421
|
+
return batchRes.value;
|
|
5196
5422
|
}
|
|
5197
5423
|
}
|
|
5198
5424
|
if (transparentBackground) {
|
|
@@ -5201,7 +5427,7 @@ async function generateImageAssets(opts) {
|
|
|
5201
5427
|
if (url.startsWith("Error")) {
|
|
5202
5428
|
return url;
|
|
5203
5429
|
}
|
|
5204
|
-
const result = await
|
|
5430
|
+
const result = await runMindstudioCliResult(
|
|
5205
5431
|
["remove-background-from-image", "--image-url", url],
|
|
5206
5432
|
{
|
|
5207
5433
|
outputKey: "imageUrl",
|
|
@@ -5210,7 +5436,7 @@ async function generateImageAssets(opts) {
|
|
|
5210
5436
|
caller: "designExpert"
|
|
5211
5437
|
}
|
|
5212
5438
|
);
|
|
5213
|
-
return result.
|
|
5439
|
+
return result.ok ? result.value : url;
|
|
5214
5440
|
})
|
|
5215
5441
|
);
|
|
5216
5442
|
}
|
|
@@ -6700,6 +6926,7 @@ var init_scrapeWebUrl2 = __esm({
|
|
|
6700
6926
|
"src/tools/common/scrapeWebUrl.ts"() {
|
|
6701
6927
|
"use strict";
|
|
6702
6928
|
init_runMindstudioCli();
|
|
6929
|
+
init_runCli();
|
|
6703
6930
|
scrapeWebUrlTool = {
|
|
6704
6931
|
clearable: false,
|
|
6705
6932
|
definition: {
|
|
@@ -6735,7 +6962,11 @@ var init_scrapeWebUrl2 = __esm({
|
|
|
6735
6962
|
"--page-options",
|
|
6736
6963
|
JSON.stringify(pageOptions)
|
|
6737
6964
|
],
|
|
6738
|
-
{
|
|
6965
|
+
{
|
|
6966
|
+
onLog: context?.onLog,
|
|
6967
|
+
maxBuffer: SCRAPE_MAX_BUFFER,
|
|
6968
|
+
caller: "parent"
|
|
6969
|
+
}
|
|
6739
6970
|
);
|
|
6740
6971
|
}
|
|
6741
6972
|
};
|
|
@@ -8839,7 +9070,7 @@ var headless_exports = {};
|
|
|
8839
9070
|
__export(headless_exports, {
|
|
8840
9071
|
HeadlessSession: () => HeadlessSession
|
|
8841
9072
|
});
|
|
8842
|
-
var log15, EXTERNAL_TOOL_TIMEOUT_MS, USER_FACING_TOOLS, FORCED_COMPACTION_THRESHOLD_TOKENS,
|
|
9073
|
+
var log15, EXTERNAL_TOOL_TIMEOUT_MS, USER_FACING_TOOLS, FORCED_COMPACTION_THRESHOLD_TOKENS, HeadlessSession;
|
|
8843
9074
|
var init_headless = __esm({
|
|
8844
9075
|
"src/headless/index.ts"() {
|
|
8845
9076
|
"use strict";
|
|
@@ -8868,8 +9099,6 @@ var init_headless = __esm({
|
|
|
8868
9099
|
"presentPublishPlan"
|
|
8869
9100
|
]);
|
|
8870
9101
|
FORCED_COMPACTION_THRESHOLD_TOKENS = 85e4;
|
|
8871
|
-
HISTORY_DEFAULT_LIMIT = 500;
|
|
8872
|
-
HISTORY_MAX_LIMIT = 2e3;
|
|
8873
9102
|
HeadlessSession = class {
|
|
8874
9103
|
// Configuration
|
|
8875
9104
|
opts;
|
|
@@ -9615,30 +9844,24 @@ var init_headless = __esm({
|
|
|
9615
9844
|
}
|
|
9616
9845
|
if (action === "get_history") {
|
|
9617
9846
|
this.applyPendingBlockUpdates();
|
|
9618
|
-
const
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
const before = typeof rawBefore === "number" && Number.isFinite(rawBefore) ? Math.max(0, Math.min(rawBefore | 0, total)) : total;
|
|
9623
|
-
let startIndex = Math.max(0, before - limit);
|
|
9624
|
-
while (startIndex > 0 && this.state.messages[startIndex].role === "user" && this.state.messages[startIndex].toolCallId) {
|
|
9625
|
-
startIndex--;
|
|
9626
|
-
}
|
|
9627
|
-
const endIndex = before;
|
|
9847
|
+
const page = getHistoryPage(this.state, {
|
|
9848
|
+
...typeof parsed.before === "number" ? { before: parsed.before } : {},
|
|
9849
|
+
...typeof parsed.limit === "number" ? { limit: parsed.limit } : {}
|
|
9850
|
+
});
|
|
9628
9851
|
log15.info("History response", {
|
|
9629
9852
|
requestId,
|
|
9630
|
-
startIndex,
|
|
9631
|
-
endIndex,
|
|
9632
|
-
count: endIndex - startIndex,
|
|
9633
|
-
totalMessageCount:
|
|
9634
|
-
beforeParam:
|
|
9635
|
-
limitParam:
|
|
9853
|
+
startIndex: page.startIndex,
|
|
9854
|
+
endIndex: page.endIndex,
|
|
9855
|
+
count: page.endIndex - page.startIndex,
|
|
9856
|
+
totalMessageCount: page.totalMessageCount,
|
|
9857
|
+
beforeParam: parsed.before,
|
|
9858
|
+
limitParam: parsed.limit
|
|
9636
9859
|
});
|
|
9637
9860
|
this.dispatchSimple(requestId, "history", () => ({
|
|
9638
|
-
messages:
|
|
9639
|
-
startIndex,
|
|
9640
|
-
endIndex,
|
|
9641
|
-
totalMessageCount:
|
|
9861
|
+
messages: page.messages,
|
|
9862
|
+
startIndex: page.startIndex,
|
|
9863
|
+
endIndex: page.endIndex,
|
|
9864
|
+
totalMessageCount: page.totalMessageCount,
|
|
9642
9865
|
running: this.running,
|
|
9643
9866
|
...this.running && this.currentRequestId ? { currentRequestId: this.currentRequestId } : {},
|
|
9644
9867
|
...this.state.models && { models: this.state.models },
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# in specimens/fonts/{slug}.png, runs analyze-image, and writes the
|
|
7
7
|
# description back to the font's "description" field.
|
|
8
8
|
#
|
|
9
|
-
# Run: bash src/subagents/designExpert/data/compile-font-descriptions.sh
|
|
9
|
+
# Run: bash src/subagents/designExpert/data/sources/compile-font-descriptions.sh
|
|
10
10
|
# Supports resuming — skips fonts that already have a description.
|
|
11
11
|
|
|
12
12
|
set -euo pipefail
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Reads each image URL from inspiration.raw.json, runs analyze-image via the
|
|
6
6
|
# mindstudio CLI, and writes the compiled output with URL + analysis.
|
|
7
7
|
#
|
|
8
|
-
# Run manually: bash src/subagents/designExpert/data/compile-inspiration.sh
|
|
8
|
+
# Run manually: bash src/subagents/designExpert/data/sources/compile-inspiration.sh
|
|
9
9
|
# Processes images sequentially (one API call at a time).
|
|
10
10
|
# Supports resuming — skips URLs already present in the output file.
|
|
11
11
|
|
|
@@ -67,7 +67,7 @@ process_one() {
|
|
|
67
67
|
--output-key analysis \
|
|
68
68
|
--no-meta 2>&1) || true
|
|
69
69
|
|
|
70
|
-
if echo "$ANALYSIS" | grep -q '"error"'; then
|
|
70
|
+
if [ -z "$ANALYSIS" ] || echo "$ANALYSIS" | grep -q '"error"'; then
|
|
71
71
|
echo " FAILED — $url"
|
|
72
72
|
return
|
|
73
73
|
fi
|