@moxt-ai/mobius 0.0.16 → 0.0.18
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/acp/session-config/grok-build-session-config.d.ts +10 -0
- package/dist/acp/session-config/grok-build-session-config.d.ts.map +1 -0
- package/dist/acp/session-config/grok-build-session-config.js +202 -0
- package/dist/acp/session-config/grok-build-session-config.js.map +1 -0
- package/dist/acp/session-config/session-config-protocol.d.ts +32 -0
- package/dist/acp/session-config/session-config-protocol.d.ts.map +1 -0
- package/dist/acp/session-config/session-config-protocol.js +237 -0
- package/dist/acp/session-config/session-config-protocol.js.map +1 -0
- package/dist/acp/session-config/session-config-registry.d.ts +3 -0
- package/dist/acp/session-config/session-config-registry.d.ts.map +1 -0
- package/dist/acp/session-config/session-config-registry.js +8 -0
- package/dist/acp/session-config/session-config-registry.js.map +1 -0
- package/dist/acp/session-manager.d.ts.map +1 -1
- package/dist/acp/session-manager.js +29 -155
- package/dist/acp/session-manager.js.map +1 -1
- package/dist/agent-catalog/agent-discovery.d.ts +19 -9
- package/dist/agent-catalog/agent-discovery.d.ts.map +1 -1
- package/dist/agent-catalog/agent-discovery.js +32 -16
- package/dist/agent-catalog/agent-discovery.js.map +1 -1
- package/dist/agent-catalog/agent-specification.d.ts +0 -1
- package/dist/agent-catalog/agent-specification.d.ts.map +1 -1
- package/dist/agent-catalog/agent-specification.js +0 -2
- package/dist/agent-catalog/agent-specification.js.map +1 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.d.ts +0 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.d.ts.map +1 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.js +0 -1
- package/dist/agent-catalog/agents/cursor-cli-agent.js.map +1 -1
- package/dist/agent-catalog/discover-agent.d.ts.map +1 -1
- package/dist/agent-catalog/discover-agent.js +30 -21
- package/dist/agent-catalog/discover-agent.js.map +1 -1
- package/dist/agent-catalog/discover-local-agents.d.ts +0 -1
- package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -1
- package/dist/agent-catalog/discover-local-agents.js +1 -1
- package/dist/agent-catalog/discover-local-agents.js.map +1 -1
- package/dist/agent-catalog/local-agent.d.ts +12 -1
- package/dist/agent-catalog/local-agent.d.ts.map +1 -1
- package/dist/agent-catalog/local-agent.js +16 -0
- package/dist/agent-catalog/local-agent.js.map +1 -1
- package/dist/agent-catalog/publish-agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog/publish-agent-catalog.js +3 -4
- package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
- package/dist/agent-installation/agent-installation-manager.d.ts.map +1 -1
- package/dist/agent-installation/agent-installation-manager.js +6 -7
- package/dist/agent-installation/agent-installation-manager.js.map +1 -1
- package/dist/agent-installation/fixed-installation-executor.d.ts +2 -3
- package/dist/agent-installation/fixed-installation-executor.d.ts.map +1 -1
- package/dist/agent-installation/fixed-installation-executor.js +47 -67
- package/dist/agent-installation/fixed-installation-executor.js.map +1 -1
- package/dist/agent-installation/managed-agent-archive.d.ts +2 -5
- package/dist/agent-installation/managed-agent-archive.d.ts.map +1 -1
- package/dist/agent-installation/managed-agent-archive.js +1 -1
- package/dist/agent-installation/managed-agent-archive.js.map +1 -1
- package/dist/agent-installation/verified-download.d.ts +0 -4
- package/dist/agent-installation/verified-download.d.ts.map +1 -1
- package/dist/agent-installation/verified-download.js +1 -1
- package/dist/agent-installation/verified-download.js.map +1 -1
- package/dist/cli.js +1128 -1782
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1129 -1783
- package/dist/index.js.map +4 -4
- package/dist/pairing/pair-local-machine.d.ts.map +1 -1
- package/dist/pairing/pair-local-machine.js +4 -5
- package/dist/pairing/pair-local-machine.js.map +1 -1
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +162 -57
- package/dist/run-daemon.js.map +1 -1
- package/package.json +1 -1
- package/dist/agent-installation/automatic-adapter-provisioner.d.ts +0 -19
- package/dist/agent-installation/automatic-adapter-provisioner.d.ts.map +0 -1
- package/dist/agent-installation/automatic-adapter-provisioner.js +0 -125
- package/dist/agent-installation/automatic-adapter-provisioner.js.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipe.d.ts +0 -20
- package/dist/agent-installation/fixed-agent-install-recipe.d.ts.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipe.js +0 -18
- package/dist/agent-installation/fixed-agent-install-recipe.js.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts +0 -26
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +0 -1
- package/dist/agent-installation/fixed-agent-install-recipes.js +0 -301
- package/dist/agent-installation/fixed-agent-install-recipes.js.map +0 -1
- package/dist/agent-installation/grok-build-install-recipe.d.ts +0 -12
- package/dist/agent-installation/grok-build-install-recipe.d.ts.map +0 -1
- package/dist/agent-installation/grok-build-install-recipe.js +0 -102
- package/dist/agent-installation/grok-build-install-recipe.js.map +0 -1
- package/dist/agent-installation/workbuddy-install-recipe.d.ts +0 -12
- package/dist/agent-installation/workbuddy-install-recipe.d.ts.map +0 -1
- package/dist/agent-installation/workbuddy-install-recipe.js +0 -51
- package/dist/agent-installation/workbuddy-install-recipe.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
|
-
import { mkdir as
|
|
9
|
+
import { mkdir as mkdir4 } from "node:fs/promises";
|
|
10
10
|
|
|
11
11
|
// src/agent-catalog/local-agent.ts
|
|
12
12
|
import { realpathSync, statSync } from "node:fs";
|
|
@@ -526,6 +526,22 @@ var InstallableAgentDefinition = class {
|
|
|
526
526
|
this.label = label;
|
|
527
527
|
}
|
|
528
528
|
};
|
|
529
|
+
var MissingAgentDefinition = class extends InstallableAgentDefinition {
|
|
530
|
+
status = "agent_not_installed";
|
|
531
|
+
constructor(id, label) {
|
|
532
|
+
super(id, label);
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
var AgentIntegrationDefinition = class extends InstallableAgentDefinition {
|
|
536
|
+
agentPath;
|
|
537
|
+
agentVersion;
|
|
538
|
+
status = "integration_not_installed";
|
|
539
|
+
constructor(id, label, agentPath, agentVersion) {
|
|
540
|
+
super(id, label);
|
|
541
|
+
this.agentPath = agentPath;
|
|
542
|
+
this.agentVersion = agentVersion;
|
|
543
|
+
}
|
|
544
|
+
};
|
|
529
545
|
var LocalAgentCatalogSnapshot = class {
|
|
530
546
|
agents;
|
|
531
547
|
installableAgents;
|
|
@@ -595,12 +611,19 @@ var AvailableAgent = class extends AgentDiscovery {
|
|
|
595
611
|
};
|
|
596
612
|
var UnavailableAgent = class extends AgentDiscovery {
|
|
597
613
|
};
|
|
598
|
-
var
|
|
614
|
+
var UnavailableInstalledAgent = class extends UnavailableAgent {
|
|
615
|
+
agent;
|
|
616
|
+
constructor(specification, agent) {
|
|
617
|
+
super(specification);
|
|
618
|
+
this.agent = agent;
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
var MissingAdapter = class extends UnavailableInstalledAgent {
|
|
599
622
|
code = "adapter_not_found";
|
|
600
623
|
message = "ACP adapter not found";
|
|
601
624
|
status = "missing_adapter";
|
|
602
|
-
constructor(specification) {
|
|
603
|
-
super(specification);
|
|
625
|
+
constructor(specification, agent) {
|
|
626
|
+
super(specification, agent);
|
|
604
627
|
}
|
|
605
628
|
};
|
|
606
629
|
var MissingAgent = class extends UnavailableAgent {
|
|
@@ -611,7 +634,7 @@ var MissingAgent = class extends UnavailableAgent {
|
|
|
611
634
|
super(specification);
|
|
612
635
|
}
|
|
613
636
|
};
|
|
614
|
-
var
|
|
637
|
+
var AgentProbeFailed = class extends UnavailableAgent {
|
|
615
638
|
code;
|
|
616
639
|
message;
|
|
617
640
|
status = "probe_failed";
|
|
@@ -621,20 +644,30 @@ var ProbeFailed = class extends UnavailableAgent {
|
|
|
621
644
|
this.message = message;
|
|
622
645
|
}
|
|
623
646
|
};
|
|
624
|
-
var
|
|
647
|
+
var IntegrationProbeFailed = class extends UnavailableInstalledAgent {
|
|
648
|
+
code;
|
|
649
|
+
message;
|
|
650
|
+
status = "probe_failed";
|
|
651
|
+
constructor(specification, agent, code, message) {
|
|
652
|
+
super(specification, agent);
|
|
653
|
+
this.code = code;
|
|
654
|
+
this.message = message;
|
|
655
|
+
}
|
|
656
|
+
};
|
|
657
|
+
var IncompatibleAdapter = class extends UnavailableInstalledAgent {
|
|
625
658
|
code = "acp_incompatible";
|
|
626
659
|
message = "ACP adapter is incompatible";
|
|
627
660
|
status = "incompatible_adapter";
|
|
628
|
-
constructor(specification) {
|
|
629
|
-
super(specification);
|
|
661
|
+
constructor(specification, agent) {
|
|
662
|
+
super(specification, agent);
|
|
630
663
|
}
|
|
631
664
|
};
|
|
632
|
-
var AuthenticationRequiredAgent = class extends
|
|
665
|
+
var AuthenticationRequiredAgent = class extends UnavailableInstalledAgent {
|
|
633
666
|
code = "authentication_required";
|
|
634
667
|
message = "Agent authentication is required";
|
|
635
668
|
status = "authentication_required";
|
|
636
|
-
constructor(specification) {
|
|
637
|
-
super(specification);
|
|
669
|
+
constructor(specification, agent) {
|
|
670
|
+
super(specification, agent);
|
|
638
671
|
}
|
|
639
672
|
};
|
|
640
673
|
var LocalAgentInventory = class {
|
|
@@ -642,7 +675,7 @@ var LocalAgentInventory = class {
|
|
|
642
675
|
discoveries;
|
|
643
676
|
installable;
|
|
644
677
|
unavailable;
|
|
645
|
-
constructor(discoveries
|
|
678
|
+
constructor(discoveries) {
|
|
646
679
|
const available = [];
|
|
647
680
|
const unavailable = [];
|
|
648
681
|
for (const discovery of discoveries) {
|
|
@@ -657,13 +690,8 @@ var LocalAgentInventory = class {
|
|
|
657
690
|
this.available = Object.freeze(available);
|
|
658
691
|
this.discoveries = Object.freeze([...discoveries]);
|
|
659
692
|
this.installable = Object.freeze(
|
|
660
|
-
unavailable.
|
|
661
|
-
(discovery) =>
|
|
662
|
-
platform,
|
|
663
|
-
architecture
|
|
664
|
-
)
|
|
665
|
-
).map(
|
|
666
|
-
(discovery) => new InstallableAgentDefinition(
|
|
693
|
+
unavailable.map(
|
|
694
|
+
(discovery) => discovery instanceof UnavailableInstalledAgent ? discovery.agent : new MissingAgentDefinition(
|
|
667
695
|
discovery.specification.id,
|
|
668
696
|
discovery.specification.label
|
|
669
697
|
)
|
|
@@ -1132,7 +1160,6 @@ var LocalAgentSpecification = class {
|
|
|
1132
1160
|
createLaunchEnvironment = async (_agent, _context) => Object.freeze({});
|
|
1133
1161
|
recoveryCommand = () => "";
|
|
1134
1162
|
resolveInstalledAgentExecutables = (_context) => Promise.resolve([]);
|
|
1135
|
-
supportsInstallation = (platform, architecture) => (platform === "darwin" || platform === "linux") && (architecture === "arm64" || architecture === "x64");
|
|
1136
1163
|
verifyAcp = (_connection, _initialized, _defaultWorkspace, _signal) => Promise.resolve();
|
|
1137
1164
|
};
|
|
1138
1165
|
var DirectAcpAgentDefinition = class extends LocalAgentSpecification {
|
|
@@ -1280,7 +1307,6 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1280
1307
|
["agents", "cursor", CURSOR_CLI_TESTED_VERSION, "bin", "cursor-agent"]
|
|
1281
1308
|
);
|
|
1282
1309
|
}
|
|
1283
|
-
supportsInstallation = (_platform, _architecture) => false;
|
|
1284
1310
|
verifyAcp = async (connection, initialized, defaultWorkspace, signal) => {
|
|
1285
1311
|
const capabilities = initialized.agentCapabilities ?? {};
|
|
1286
1312
|
if (capabilities.loadSession !== true || capabilities.sessionCapabilities?.list == null || !(initialized.authMethods ?? []).some(
|
|
@@ -1594,14 +1620,14 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
1594
1620
|
import { join as join8 } from "node:path";
|
|
1595
1621
|
|
|
1596
1622
|
// src/agent-installation/managed-agent-archive.ts
|
|
1597
|
-
import { createHash
|
|
1623
|
+
import { createHash } from "node:crypto";
|
|
1598
1624
|
import { createReadStream } from "node:fs";
|
|
1599
1625
|
import {
|
|
1600
1626
|
chmod,
|
|
1601
1627
|
copyFile,
|
|
1602
1628
|
mkdir as mkdir2,
|
|
1603
1629
|
mkdtemp as mkdtemp2,
|
|
1604
|
-
open as
|
|
1630
|
+
open as open2,
|
|
1605
1631
|
realpath as realpath5,
|
|
1606
1632
|
rename as rename2,
|
|
1607
1633
|
rm as rm2,
|
|
@@ -1611,208 +1637,16 @@ import {
|
|
|
1611
1637
|
import { dirname as dirname2, isAbsolute as isAbsolute4, join as join7, relative as relative3, sep as sep3 } from "node:path";
|
|
1612
1638
|
|
|
1613
1639
|
// src/agent-installation/verified-download.ts
|
|
1614
|
-
import { createHash } from "node:crypto";
|
|
1615
|
-
import { open as open2, unlink } from "node:fs/promises";
|
|
1616
1640
|
import { fetch } from "undici";
|
|
1617
1641
|
|
|
1618
1642
|
// src/network/environment-proxy.ts
|
|
1619
1643
|
import { EnvHttpProxyAgent } from "undici";
|
|
1620
1644
|
var environmentProxyDispatcher = new EnvHttpProxyAgent();
|
|
1621
1645
|
|
|
1622
|
-
// src/agent-installation/verified-download.ts
|
|
1623
|
-
var MAX_REDIRECTS = 4;
|
|
1624
|
-
var REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
1625
|
-
var InstallerDownloadError = class extends Error {
|
|
1626
|
-
code;
|
|
1627
|
-
constructor(code, message, options = {}) {
|
|
1628
|
-
super(message, options);
|
|
1629
|
-
this.code = code;
|
|
1630
|
-
this.name = "InstallerDownloadError";
|
|
1631
|
-
}
|
|
1632
|
-
};
|
|
1633
|
-
var VerifiedDownload = class {
|
|
1634
|
-
bytes;
|
|
1635
|
-
sha256;
|
|
1636
|
-
url;
|
|
1637
|
-
constructor(url2, bytes, sha256) {
|
|
1638
|
-
this.bytes = bytes;
|
|
1639
|
-
this.sha256 = sha256;
|
|
1640
|
-
this.url = url2;
|
|
1641
|
-
}
|
|
1642
|
-
};
|
|
1643
|
-
var UndiciInstallerDownloadTransport = class {
|
|
1644
|
-
get = async (url2, signal) => await fetch(url2, {
|
|
1645
|
-
dispatcher: environmentProxyDispatcher,
|
|
1646
|
-
headers: {
|
|
1647
|
-
accept: "text/plain, application/octet-stream;q=0.9",
|
|
1648
|
-
"user-agent": "Mobius-Agent-Installer/0.0.3"
|
|
1649
|
-
},
|
|
1650
|
-
method: "GET",
|
|
1651
|
-
redirect: "manual",
|
|
1652
|
-
signal
|
|
1653
|
-
});
|
|
1654
|
-
};
|
|
1655
|
-
function validateUrl(url2, allowedHosts) {
|
|
1656
|
-
if (url2.protocol !== "https:" || url2.username.length > 0 || url2.password.length > 0 || url2.port.length > 0 || !allowedHosts.has(url2.hostname)) {
|
|
1657
|
-
throw new InstallerDownloadError(
|
|
1658
|
-
"installer_host_not_allowed",
|
|
1659
|
-
"The installer download target is not allowed"
|
|
1660
|
-
);
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
async function fetchInstaller(options, signal, transport) {
|
|
1664
|
-
let url2 = new URL(options.url);
|
|
1665
|
-
for (let redirectCount = 0; redirectCount <= MAX_REDIRECTS; redirectCount += 1) {
|
|
1666
|
-
validateUrl(url2, options.allowedHosts);
|
|
1667
|
-
const response = await transport.get(url2, signal);
|
|
1668
|
-
if (!REDIRECT_STATUSES.has(response.status)) {
|
|
1669
|
-
return { response, url: url2 };
|
|
1670
|
-
}
|
|
1671
|
-
await response.body?.cancel();
|
|
1672
|
-
const location = response.headers.get("location");
|
|
1673
|
-
if (location === null || redirectCount === MAX_REDIRECTS) {
|
|
1674
|
-
throw new InstallerDownloadError(
|
|
1675
|
-
"installer_redirect_invalid",
|
|
1676
|
-
"The installer returned an invalid redirect"
|
|
1677
|
-
);
|
|
1678
|
-
}
|
|
1679
|
-
let redirected;
|
|
1680
|
-
try {
|
|
1681
|
-
redirected = new URL(location, url2);
|
|
1682
|
-
} catch (error61) {
|
|
1683
|
-
throw new InstallerDownloadError(
|
|
1684
|
-
"installer_redirect_invalid",
|
|
1685
|
-
"The installer returned an invalid redirect",
|
|
1686
|
-
{ cause: error61 }
|
|
1687
|
-
);
|
|
1688
|
-
}
|
|
1689
|
-
try {
|
|
1690
|
-
validateUrl(redirected, options.allowedHosts);
|
|
1691
|
-
} catch (error61) {
|
|
1692
|
-
throw new InstallerDownloadError(
|
|
1693
|
-
"installer_redirect_not_allowed",
|
|
1694
|
-
"The installer redirect left the approved host allowlist",
|
|
1695
|
-
{ cause: error61 }
|
|
1696
|
-
);
|
|
1697
|
-
}
|
|
1698
|
-
url2 = redirected;
|
|
1699
|
-
}
|
|
1700
|
-
throw new InstallerDownloadError(
|
|
1701
|
-
"installer_redirect_invalid",
|
|
1702
|
-
"The installer returned too many redirects"
|
|
1703
|
-
);
|
|
1704
|
-
}
|
|
1705
|
-
async function writeCompleteChunk(handle, chunk) {
|
|
1706
|
-
let offset = 0;
|
|
1707
|
-
while (offset < chunk.byteLength) {
|
|
1708
|
-
const written = await handle.write(
|
|
1709
|
-
chunk,
|
|
1710
|
-
offset,
|
|
1711
|
-
chunk.byteLength - offset
|
|
1712
|
-
);
|
|
1713
|
-
if (written.bytesWritten < 1) {
|
|
1714
|
-
throw new InstallerDownloadError(
|
|
1715
|
-
"installer_write_failed",
|
|
1716
|
-
"The verified installer could not be stored"
|
|
1717
|
-
);
|
|
1718
|
-
}
|
|
1719
|
-
offset += written.bytesWritten;
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
async function downloadVerifiedFile(options, transport = new UndiciInstallerDownloadTransport()) {
|
|
1723
|
-
options.signal.throwIfAborted();
|
|
1724
|
-
const timeoutSignal = AbortSignal.timeout(options.timeoutMilliseconds);
|
|
1725
|
-
const signal = AbortSignal.any([options.signal, timeoutSignal]);
|
|
1726
|
-
let handle = null;
|
|
1727
|
-
let responseBody = null;
|
|
1728
|
-
try {
|
|
1729
|
-
const fetched = await fetchInstaller(options, signal, transport);
|
|
1730
|
-
responseBody = fetched.response.body;
|
|
1731
|
-
if (!fetched.response.ok || fetched.response.body === null) {
|
|
1732
|
-
throw new InstallerDownloadError(
|
|
1733
|
-
"installer_download_failed",
|
|
1734
|
-
"The approved installer could not be downloaded"
|
|
1735
|
-
);
|
|
1736
|
-
}
|
|
1737
|
-
const contentLength = fetched.response.headers.get("content-length");
|
|
1738
|
-
if (contentLength !== null) {
|
|
1739
|
-
const declaredLength = Number(contentLength);
|
|
1740
|
-
if (!Number.isSafeInteger(declaredLength) || declaredLength < 1 || declaredLength > options.maximumBytes) {
|
|
1741
|
-
throw new InstallerDownloadError(
|
|
1742
|
-
"installer_size_invalid",
|
|
1743
|
-
"The installer size is outside the approved limit"
|
|
1744
|
-
);
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
handle = await open2(options.destination, "wx", 384);
|
|
1748
|
-
const digest = createHash("sha256");
|
|
1749
|
-
const reader = fetched.response.body.getReader();
|
|
1750
|
-
let bytes = 0;
|
|
1751
|
-
try {
|
|
1752
|
-
while (true) {
|
|
1753
|
-
signal.throwIfAborted();
|
|
1754
|
-
const chunk = await reader.read();
|
|
1755
|
-
if (chunk.done) {
|
|
1756
|
-
break;
|
|
1757
|
-
}
|
|
1758
|
-
bytes += chunk.value.byteLength;
|
|
1759
|
-
if (bytes > options.maximumBytes) {
|
|
1760
|
-
throw new InstallerDownloadError(
|
|
1761
|
-
"installer_size_invalid",
|
|
1762
|
-
"The installer exceeded the approved size limit"
|
|
1763
|
-
);
|
|
1764
|
-
}
|
|
1765
|
-
digest.update(chunk.value);
|
|
1766
|
-
await writeCompleteChunk(handle, chunk.value);
|
|
1767
|
-
}
|
|
1768
|
-
} finally {
|
|
1769
|
-
await reader.cancel().catch(() => void 0);
|
|
1770
|
-
reader.releaseLock();
|
|
1771
|
-
}
|
|
1772
|
-
if (bytes === 0) {
|
|
1773
|
-
throw new InstallerDownloadError(
|
|
1774
|
-
"installer_verification_failed",
|
|
1775
|
-
"The downloaded installer is empty"
|
|
1776
|
-
);
|
|
1777
|
-
}
|
|
1778
|
-
await handle.sync();
|
|
1779
|
-
await handle.close();
|
|
1780
|
-
handle = null;
|
|
1781
|
-
return new VerifiedDownload(fetched.url, bytes, digest.digest("hex"));
|
|
1782
|
-
} catch (error61) {
|
|
1783
|
-
if (handle !== null) {
|
|
1784
|
-
await handle.close().catch(() => void 0);
|
|
1785
|
-
}
|
|
1786
|
-
await unlink(options.destination).catch(() => void 0);
|
|
1787
|
-
if (options.signal.aborted) {
|
|
1788
|
-
options.signal.throwIfAborted();
|
|
1789
|
-
}
|
|
1790
|
-
if (timeoutSignal.aborted) {
|
|
1791
|
-
throw new InstallerDownloadError(
|
|
1792
|
-
"installer_download_timeout",
|
|
1793
|
-
"The installer download timed out",
|
|
1794
|
-
{ cause: error61 }
|
|
1795
|
-
);
|
|
1796
|
-
}
|
|
1797
|
-
if (error61 instanceof InstallerDownloadError) {
|
|
1798
|
-
throw error61;
|
|
1799
|
-
}
|
|
1800
|
-
throw new InstallerDownloadError(
|
|
1801
|
-
"installer_download_failed",
|
|
1802
|
-
"The approved installer could not be downloaded",
|
|
1803
|
-
{ cause: error61 }
|
|
1804
|
-
);
|
|
1805
|
-
} finally {
|
|
1806
|
-
await responseBody?.cancel().catch(() => void 0);
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
1646
|
// src/agent-installation/managed-agent-archive.ts
|
|
1811
1647
|
var ARCHIVE_DOWNLOAD_LIMIT_BYTES = 128 * 1024 * 1024;
|
|
1812
1648
|
var ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS = 2 * 60 * 1e3;
|
|
1813
|
-
var ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS = 6e4;
|
|
1814
1649
|
var MANIFEST_LIMIT_BYTES = 16 * 1024;
|
|
1815
|
-
var MINIMAL_PATH = "/usr/bin:/bin";
|
|
1816
1650
|
var ManagedAgentArchiveDefinition = class {
|
|
1817
1651
|
archiveName;
|
|
1818
1652
|
archiveSha256;
|
|
@@ -1851,9 +1685,6 @@ var ManagedAgentArchiveError = class extends Error {
|
|
|
1851
1685
|
this.name = "ManagedAgentArchiveError";
|
|
1852
1686
|
}
|
|
1853
1687
|
};
|
|
1854
|
-
var ManagedAgentArchiveDownloader = class {
|
|
1855
|
-
download = async (options) => await downloadVerifiedFile(options);
|
|
1856
|
-
};
|
|
1857
1688
|
function isRecord2(value) {
|
|
1858
1689
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1859
1690
|
}
|
|
@@ -1863,7 +1694,7 @@ function isContainedPath3(root, candidate) {
|
|
|
1863
1694
|
}
|
|
1864
1695
|
async function hashFile(path2, signal) {
|
|
1865
1696
|
signal.throwIfAborted();
|
|
1866
|
-
const digest =
|
|
1697
|
+
const digest = createHash("sha256");
|
|
1867
1698
|
const stream = createReadStream(path2, { signal });
|
|
1868
1699
|
try {
|
|
1869
1700
|
for await (const chunk of stream) {
|
|
@@ -1894,7 +1725,7 @@ async function hashFile(path2, signal) {
|
|
|
1894
1725
|
async function readManifest(path2) {
|
|
1895
1726
|
let handle;
|
|
1896
1727
|
try {
|
|
1897
|
-
handle = await
|
|
1728
|
+
handle = await open2(path2, "r");
|
|
1898
1729
|
} catch (error61) {
|
|
1899
1730
|
throw new ManagedAgentArchiveError(
|
|
1900
1731
|
"managed_archive_verification_failed",
|
|
@@ -1965,144 +1796,6 @@ async function validateManagedAgentArchive(root, definition, signal) {
|
|
|
1965
1796
|
);
|
|
1966
1797
|
}
|
|
1967
1798
|
}
|
|
1968
|
-
function validateArchiveEntries(output2, definition) {
|
|
1969
|
-
const entries = output2.split(/\r?\n/).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
1970
|
-
if (entries.length !== 1 || entries[0] !== definition.executableName && entries[0] !== `./${definition.executableName}`) {
|
|
1971
|
-
throw new ManagedAgentArchiveError(
|
|
1972
|
-
"managed_archive_verification_failed",
|
|
1973
|
-
"The managed Agent archive contains unexpected entries"
|
|
1974
|
-
);
|
|
1975
|
-
}
|
|
1976
|
-
}
|
|
1977
|
-
var ManagedAgentArchiveInstaller = class {
|
|
1978
|
-
#downloader;
|
|
1979
|
-
constructor(downloader = new ManagedAgentArchiveDownloader()) {
|
|
1980
|
-
this.#downloader = downloader;
|
|
1981
|
-
}
|
|
1982
|
-
install = async (root, definition, signal) => {
|
|
1983
|
-
signal.throwIfAborted();
|
|
1984
|
-
try {
|
|
1985
|
-
const metadata = await stat4(root);
|
|
1986
|
-
if (metadata.isDirectory()) {
|
|
1987
|
-
return await validateManagedAgentArchive(root, definition, signal);
|
|
1988
|
-
}
|
|
1989
|
-
} catch (error61) {
|
|
1990
|
-
if (error61 instanceof ManagedAgentArchiveError || !(error61 instanceof Error) || !("code" in error61) || error61.code !== "ENOENT") {
|
|
1991
|
-
throw error61;
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
|
-
const parent = dirname2(root);
|
|
1995
|
-
await mkdir2(parent, { mode: 448, recursive: true });
|
|
1996
|
-
const working = await mkdtemp2(
|
|
1997
|
-
join7(parent, `.${definition.version}.archive-`)
|
|
1998
|
-
);
|
|
1999
|
-
const staging = await mkdtemp2(
|
|
2000
|
-
join7(parent, `.${definition.version}.staging-`)
|
|
2001
|
-
);
|
|
2002
|
-
try {
|
|
2003
|
-
const archivePath = join7(working, definition.archiveName);
|
|
2004
|
-
const extractionRoot = join7(working, "extracted");
|
|
2005
|
-
await mkdir2(extractionRoot, { mode: 448 });
|
|
2006
|
-
const canonicalExtractionRoot = await realpath5(extractionRoot);
|
|
2007
|
-
const download = await this.#downloader.download({
|
|
2008
|
-
allowedHosts: /* @__PURE__ */ new Set([
|
|
2009
|
-
"github.com",
|
|
2010
|
-
"objects.githubusercontent.com",
|
|
2011
|
-
"release-assets.githubusercontent.com"
|
|
2012
|
-
]),
|
|
2013
|
-
destination: archivePath,
|
|
2014
|
-
maximumBytes: ARCHIVE_DOWNLOAD_LIMIT_BYTES,
|
|
2015
|
-
signal,
|
|
2016
|
-
timeoutMilliseconds: ARCHIVE_DOWNLOAD_TIMEOUT_MILLISECONDS,
|
|
2017
|
-
url: definition.archiveUrl
|
|
2018
|
-
});
|
|
2019
|
-
if (download.sha256 !== definition.archiveSha256) {
|
|
2020
|
-
throw new ManagedAgentArchiveError(
|
|
2021
|
-
"managed_archive_verification_failed",
|
|
2022
|
-
"The managed Agent archive checksum is invalid"
|
|
2023
|
-
);
|
|
2024
|
-
}
|
|
2025
|
-
const list = await runBoundedProcess({
|
|
2026
|
-
arguments: definition.listArguments(archivePath),
|
|
2027
|
-
command: definition.extractor,
|
|
2028
|
-
cwd: working,
|
|
2029
|
-
environment: { PATH: MINIMAL_PATH },
|
|
2030
|
-
outputLimitBytes: 64 * 1024,
|
|
2031
|
-
signal,
|
|
2032
|
-
timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
|
|
2033
|
-
});
|
|
2034
|
-
validateArchiveEntries(list.stdout, definition);
|
|
2035
|
-
await runBoundedProcess({
|
|
2036
|
-
arguments: definition.extractArguments(archivePath, extractionRoot),
|
|
2037
|
-
command: definition.extractor,
|
|
2038
|
-
cwd: working,
|
|
2039
|
-
environment: { PATH: MINIMAL_PATH },
|
|
2040
|
-
outputLimitBytes: 64 * 1024,
|
|
2041
|
-
signal,
|
|
2042
|
-
timeoutMilliseconds: ARCHIVE_EXTRACTION_TIMEOUT_MILLISECONDS
|
|
2043
|
-
});
|
|
2044
|
-
const extracted = await realpath5(
|
|
2045
|
-
join7(canonicalExtractionRoot, definition.executableName)
|
|
2046
|
-
);
|
|
2047
|
-
const extractedMetadata = await stat4(extracted);
|
|
2048
|
-
if (!isContainedPath3(canonicalExtractionRoot, extracted) || !extractedMetadata.isFile()) {
|
|
2049
|
-
throw new ManagedAgentArchiveError(
|
|
2050
|
-
"managed_archive_verification_failed",
|
|
2051
|
-
"The managed Agent archive executable is invalid"
|
|
2052
|
-
);
|
|
2053
|
-
}
|
|
2054
|
-
const binDirectory = join7(staging, "bin");
|
|
2055
|
-
const executablePath = join7(binDirectory, definition.executableName);
|
|
2056
|
-
await mkdir2(binDirectory, { mode: 448 });
|
|
2057
|
-
await copyFile(extracted, executablePath);
|
|
2058
|
-
await chmod(executablePath, 448);
|
|
2059
|
-
const executableSha256 = await hashFile(executablePath, signal);
|
|
2060
|
-
await writeFile(
|
|
2061
|
-
join7(staging, "archive.json"),
|
|
2062
|
-
`${JSON.stringify({
|
|
2063
|
-
archiveSha256: definition.archiveSha256,
|
|
2064
|
-
archiveUrl: definition.archiveUrl.toString(),
|
|
2065
|
-
executableSha256,
|
|
2066
|
-
version: definition.version
|
|
2067
|
-
})}
|
|
2068
|
-
`,
|
|
2069
|
-
{ mode: 384 }
|
|
2070
|
-
);
|
|
2071
|
-
await validateManagedAgentArchive(staging, definition, signal);
|
|
2072
|
-
try {
|
|
2073
|
-
await rename2(staging, root);
|
|
2074
|
-
} catch (error61) {
|
|
2075
|
-
try {
|
|
2076
|
-
return await validateManagedAgentArchive(root, definition, signal);
|
|
2077
|
-
} catch {
|
|
2078
|
-
throw new ManagedAgentArchiveError(
|
|
2079
|
-
"managed_archive_publish_failed",
|
|
2080
|
-
"The managed Agent archive could not be published",
|
|
2081
|
-
{ cause: error61 }
|
|
2082
|
-
);
|
|
2083
|
-
}
|
|
2084
|
-
}
|
|
2085
|
-
return await validateManagedAgentArchive(root, definition, signal);
|
|
2086
|
-
} catch (error61) {
|
|
2087
|
-
if (signal.aborted) {
|
|
2088
|
-
signal.throwIfAborted();
|
|
2089
|
-
}
|
|
2090
|
-
if (error61 instanceof ManagedAgentArchiveError) {
|
|
2091
|
-
throw error61;
|
|
2092
|
-
}
|
|
2093
|
-
throw new ManagedAgentArchiveError(
|
|
2094
|
-
"managed_archive_install_failed",
|
|
2095
|
-
"The pinned Agent archive could not be installed",
|
|
2096
|
-
{ cause: error61 }
|
|
2097
|
-
);
|
|
2098
|
-
} finally {
|
|
2099
|
-
await Promise.all([
|
|
2100
|
-
rm2(working, { force: true, recursive: true }),
|
|
2101
|
-
rm2(staging, { force: true, recursive: true })
|
|
2102
|
-
]);
|
|
2103
|
-
}
|
|
2104
|
-
};
|
|
2105
|
-
};
|
|
2106
1799
|
|
|
2107
1800
|
// src/agent-installation/opencode-managed-release.ts
|
|
2108
1801
|
var OPENCODE_MANAGED_VERSION = "1.18.29";
|
|
@@ -2644,10 +2337,6 @@ async function resolveAdapterExecutables(specification, context) {
|
|
|
2644
2337
|
context
|
|
2645
2338
|
);
|
|
2646
2339
|
}
|
|
2647
|
-
async function resolveAgentExecutable(specification, context) {
|
|
2648
|
-
const executables = await resolveAgentExecutables(specification, context);
|
|
2649
|
-
return executables[0] ?? null;
|
|
2650
|
-
}
|
|
2651
2340
|
async function resolveAdapterExecutable(specification, context) {
|
|
2652
2341
|
const executables = await resolveAdapterExecutables(specification, context);
|
|
2653
2342
|
return executables[0] ?? null;
|
|
@@ -2713,41 +2402,41 @@ var DiscoveryAcpHandler = class {
|
|
|
2713
2402
|
};
|
|
2714
2403
|
function readableAcpStream(input2) {
|
|
2715
2404
|
let byteLength = 0;
|
|
2716
|
-
let
|
|
2405
|
+
let open5 = true;
|
|
2717
2406
|
return new ReadableStream({
|
|
2718
2407
|
start(controller) {
|
|
2719
2408
|
input2.on("data", (chunk) => {
|
|
2720
|
-
if (!
|
|
2409
|
+
if (!open5) {
|
|
2721
2410
|
return;
|
|
2722
2411
|
}
|
|
2723
2412
|
if (!(chunk instanceof Uint8Array)) {
|
|
2724
|
-
|
|
2413
|
+
open5 = false;
|
|
2725
2414
|
controller.error(new Error("ACP adapter produced invalid output"));
|
|
2726
2415
|
return;
|
|
2727
2416
|
}
|
|
2728
2417
|
byteLength += chunk.byteLength;
|
|
2729
2418
|
if (byteLength > ACP_OUTPUT_LIMIT_BYTES) {
|
|
2730
|
-
|
|
2419
|
+
open5 = false;
|
|
2731
2420
|
controller.error(new Error("ACP adapter output limit exceeded"));
|
|
2732
2421
|
return;
|
|
2733
2422
|
}
|
|
2734
2423
|
controller.enqueue(new Uint8Array(chunk));
|
|
2735
2424
|
});
|
|
2736
2425
|
input2.once("end", () => {
|
|
2737
|
-
if (
|
|
2738
|
-
|
|
2426
|
+
if (open5) {
|
|
2427
|
+
open5 = false;
|
|
2739
2428
|
controller.close();
|
|
2740
2429
|
}
|
|
2741
2430
|
});
|
|
2742
2431
|
input2.once("error", (error61) => {
|
|
2743
|
-
if (
|
|
2744
|
-
|
|
2432
|
+
if (open5) {
|
|
2433
|
+
open5 = false;
|
|
2745
2434
|
controller.error(error61);
|
|
2746
2435
|
}
|
|
2747
2436
|
});
|
|
2748
2437
|
},
|
|
2749
2438
|
cancel() {
|
|
2750
|
-
|
|
2439
|
+
open5 = false;
|
|
2751
2440
|
}
|
|
2752
2441
|
});
|
|
2753
2442
|
}
|
|
@@ -2876,25 +2565,50 @@ async function probeAcpReadiness(specification, agent, environment, defaultWorks
|
|
|
2876
2565
|
}
|
|
2877
2566
|
|
|
2878
2567
|
// src/agent-catalog/discover-agent.ts
|
|
2879
|
-
function
|
|
2568
|
+
function agentProbeFailure(specification, error61) {
|
|
2569
|
+
if (error61 instanceof AgentProbeError) {
|
|
2570
|
+
return new AgentProbeFailed(specification, error61.code, error61.message);
|
|
2571
|
+
}
|
|
2572
|
+
if (error61 instanceof ProcessExecutionError) {
|
|
2573
|
+
const code = error61.code === "process_timeout" ? "agent_probe_timeout" : "agent_probe_failed";
|
|
2574
|
+
return new AgentProbeFailed(
|
|
2575
|
+
specification,
|
|
2576
|
+
code,
|
|
2577
|
+
"Agent version probe failed"
|
|
2578
|
+
);
|
|
2579
|
+
}
|
|
2580
|
+
return new AgentProbeFailed(
|
|
2581
|
+
specification,
|
|
2582
|
+
"agent_probe_failed",
|
|
2583
|
+
"Agent probe failed"
|
|
2584
|
+
);
|
|
2585
|
+
}
|
|
2586
|
+
function integrationProbeFailure(specification, agent, error61) {
|
|
2880
2587
|
if (error61 instanceof AgentProbeError) {
|
|
2881
2588
|
if (error61.code === "authentication_required") {
|
|
2882
|
-
return new AuthenticationRequiredAgent(specification);
|
|
2589
|
+
return new AuthenticationRequiredAgent(specification, agent);
|
|
2883
2590
|
}
|
|
2884
|
-
return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification) : new
|
|
2591
|
+
return error61.code === "acp_incompatible" ? new IncompatibleAdapter(specification, agent) : new IntegrationProbeFailed(
|
|
2592
|
+
specification,
|
|
2593
|
+
agent,
|
|
2594
|
+
error61.code,
|
|
2595
|
+
error61.message
|
|
2596
|
+
);
|
|
2885
2597
|
}
|
|
2886
2598
|
if (error61 instanceof ProcessExecutionError) {
|
|
2887
|
-
const code = error61.code === "process_timeout" ?
|
|
2888
|
-
return new
|
|
2599
|
+
const code = error61.code === "process_timeout" ? "adapter_probe_timeout" : "adapter_probe_failed";
|
|
2600
|
+
return new IntegrationProbeFailed(
|
|
2889
2601
|
specification,
|
|
2602
|
+
agent,
|
|
2890
2603
|
code,
|
|
2891
|
-
|
|
2604
|
+
"Adapter version probe failed"
|
|
2892
2605
|
);
|
|
2893
2606
|
}
|
|
2894
|
-
return new
|
|
2607
|
+
return new IntegrationProbeFailed(
|
|
2895
2608
|
specification,
|
|
2896
|
-
|
|
2897
|
-
|
|
2609
|
+
agent,
|
|
2610
|
+
"adapter_probe_failed",
|
|
2611
|
+
"Adapter probe failed"
|
|
2898
2612
|
);
|
|
2899
2613
|
}
|
|
2900
2614
|
async function discoverAgent(specification, context) {
|
|
@@ -2903,12 +2617,6 @@ async function discoverAgent(specification, context) {
|
|
|
2903
2617
|
resolveAdapterExecutables(specification, context),
|
|
2904
2618
|
resolveAgentExecutables(specification, context)
|
|
2905
2619
|
]);
|
|
2906
|
-
if (specification instanceof DirectAcpAgentDefinition && agents.length === 0) {
|
|
2907
|
-
return new MissingAgent(specification);
|
|
2908
|
-
}
|
|
2909
|
-
if (adapters.length === 0) {
|
|
2910
|
-
return new MissingAdapter(specification);
|
|
2911
|
-
}
|
|
2912
2620
|
if (agents.length === 0) {
|
|
2913
2621
|
return new MissingAgent(specification);
|
|
2914
2622
|
}
|
|
@@ -2928,9 +2636,18 @@ async function discoverAgent(specification, context) {
|
|
|
2928
2636
|
if (context.signal.aborted) {
|
|
2929
2637
|
context.signal.throwIfAborted();
|
|
2930
2638
|
}
|
|
2931
|
-
lastFailure =
|
|
2639
|
+
lastFailure = agentProbeFailure(specification, error61);
|
|
2932
2640
|
continue;
|
|
2933
2641
|
}
|
|
2642
|
+
const installedAgent = new AgentIntegrationDefinition(
|
|
2643
|
+
specification.id,
|
|
2644
|
+
specification.label,
|
|
2645
|
+
agent.identity.requestedPath,
|
|
2646
|
+
agentVersion
|
|
2647
|
+
);
|
|
2648
|
+
if (adapters.length === 0) {
|
|
2649
|
+
return new MissingAdapter(specification, installedAgent);
|
|
2650
|
+
}
|
|
2934
2651
|
for (const adapter of adapters) {
|
|
2935
2652
|
if (specification instanceof DirectAcpAgentDefinition && adapter.path !== agent.path) {
|
|
2936
2653
|
continue;
|
|
@@ -2959,7 +2676,11 @@ async function discoverAgent(specification, context) {
|
|
|
2959
2676
|
if (context.signal.aborted) {
|
|
2960
2677
|
context.signal.throwIfAborted();
|
|
2961
2678
|
}
|
|
2962
|
-
lastFailure =
|
|
2679
|
+
lastFailure = integrationProbeFailure(
|
|
2680
|
+
specification,
|
|
2681
|
+
installedAgent,
|
|
2682
|
+
error61
|
|
2683
|
+
);
|
|
2963
2684
|
continue;
|
|
2964
2685
|
}
|
|
2965
2686
|
const definition = new LocalAgentDefinition(
|
|
@@ -3008,7 +2729,11 @@ async function discoverAgent(specification, context) {
|
|
|
3008
2729
|
if (context.signal.aborted) {
|
|
3009
2730
|
context.signal.throwIfAborted();
|
|
3010
2731
|
}
|
|
3011
|
-
const failure =
|
|
2732
|
+
const failure = integrationProbeFailure(
|
|
2733
|
+
specification,
|
|
2734
|
+
installedAgent,
|
|
2735
|
+
error61
|
|
2736
|
+
);
|
|
3012
2737
|
if (failure instanceof AuthenticationRequiredAgent) {
|
|
3013
2738
|
return failure;
|
|
3014
2739
|
}
|
|
@@ -3016,7 +2741,7 @@ async function discoverAgent(specification, context) {
|
|
|
3016
2741
|
}
|
|
3017
2742
|
}
|
|
3018
2743
|
}
|
|
3019
|
-
return lastFailure ?? new
|
|
2744
|
+
return lastFailure ?? new MissingAgent(specification);
|
|
3020
2745
|
}
|
|
3021
2746
|
|
|
3022
2747
|
// src/agent-catalog/discover-local-agents.ts
|
|
@@ -3027,11 +2752,7 @@ async function discoverLocalAgentInventory(options) {
|
|
|
3027
2752
|
async (specification) => await discoverAgent(specification, options)
|
|
3028
2753
|
)
|
|
3029
2754
|
);
|
|
3030
|
-
return new LocalAgentInventory(
|
|
3031
|
-
discoveries,
|
|
3032
|
-
options.platform,
|
|
3033
|
-
options.architecture
|
|
3034
|
-
);
|
|
2755
|
+
return new LocalAgentInventory(discoveries);
|
|
3035
2756
|
}
|
|
3036
2757
|
|
|
3037
2758
|
// src/audit/audit-store.ts
|
|
@@ -5047,8 +4768,8 @@ function emoji() {
|
|
|
5047
4768
|
}
|
|
5048
4769
|
var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
|
|
5049
4770
|
var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
|
|
5050
|
-
var mac = (
|
|
5051
|
-
const escapedDelim = escapeRegex(
|
|
4771
|
+
var mac = (delimiter2) => {
|
|
4772
|
+
const escapedDelim = escapeRegex(delimiter2 ?? ":");
|
|
5052
4773
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
5053
4774
|
};
|
|
5054
4775
|
var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
|
|
@@ -8105,7 +7826,7 @@ function bucketFor(state, inst) {
|
|
|
8105
7826
|
return bucket;
|
|
8106
7827
|
}
|
|
8107
7828
|
var handoff;
|
|
8108
|
-
var
|
|
7829
|
+
var open3 = [];
|
|
8109
7830
|
var memo = {
|
|
8110
7831
|
alloc(_inst, payload, empty) {
|
|
8111
7832
|
const bucket = handoff;
|
|
@@ -8114,7 +7835,7 @@ var memo = {
|
|
|
8114
7835
|
handoff = void 0;
|
|
8115
7836
|
const entry = { value: empty, issues: null };
|
|
8116
7837
|
bucket.set(payload.value, entry);
|
|
8117
|
-
|
|
7838
|
+
open3.push(entry);
|
|
8118
7839
|
return empty;
|
|
8119
7840
|
},
|
|
8120
7841
|
guard(inst) {
|
|
@@ -8180,10 +7901,10 @@ var memo = {
|
|
|
8180
7901
|
return payload;
|
|
8181
7902
|
}
|
|
8182
7903
|
handoff = bucket;
|
|
8183
|
-
const depth =
|
|
7904
|
+
const depth = open3.length;
|
|
8184
7905
|
const result = base(payload, ctx);
|
|
8185
7906
|
handoff = void 0;
|
|
8186
|
-
const entry =
|
|
7907
|
+
const entry = open3.length > depth ? open3.pop() : void 0;
|
|
8187
7908
|
if (result instanceof Promise) {
|
|
8188
7909
|
return result.then((r) => {
|
|
8189
7910
|
if (entry)
|
|
@@ -22021,13 +21742,13 @@ var SESSION_ELICITATION_RESPOND_KIND = "session.elicitation.respond";
|
|
|
22021
21742
|
var SESSION_ELICITATION_RESOLVED_KIND = "session.elicitation.resolved";
|
|
22022
21743
|
var SESSION_OPERATION_FAILED_KIND = "session.operation.failed";
|
|
22023
21744
|
var AGENT_CONTENT_KIND = "agent.content";
|
|
22024
|
-
var AGENT_INSTALL_REQUEST_KIND = "agent.install.request";
|
|
22025
|
-
var AGENT_INSTALL_CANCEL_KIND = "agent.install.cancel";
|
|
22026
|
-
var AGENT_INSTALL_STARTED_KIND = "agent.install.started";
|
|
22027
|
-
var AGENT_INSTALL_PROGRESS_KIND = "agent.install.progress";
|
|
22028
|
-
var AGENT_INSTALL_COMPLETED_KIND = "agent.install.completed";
|
|
22029
|
-
var AGENT_INSTALL_FAILED_KIND = "agent.install.failed";
|
|
22030
|
-
var AGENT_INSTALL_CANCELLED_KIND = "agent.install.cancelled";
|
|
21745
|
+
var AGENT_INSTALL_REQUEST_KIND = "agent.integration.install.request";
|
|
21746
|
+
var AGENT_INSTALL_CANCEL_KIND = "agent.integration.install.cancel";
|
|
21747
|
+
var AGENT_INSTALL_STARTED_KIND = "agent.integration.install.started";
|
|
21748
|
+
var AGENT_INSTALL_PROGRESS_KIND = "agent.integration.install.progress";
|
|
21749
|
+
var AGENT_INSTALL_COMPLETED_KIND = "agent.integration.install.completed";
|
|
21750
|
+
var AGENT_INSTALL_FAILED_KIND = "agent.integration.install.failed";
|
|
21751
|
+
var AGENT_INSTALL_CANCELLED_KIND = "agent.integration.install.cancelled";
|
|
22031
21752
|
var IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
22032
21753
|
var DIRECTORY_IDENTIFIER_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
|
|
22033
21754
|
var IDENTIFIER = external_exports.string().min(1).max(128).regex(IDENTIFIER_PATTERN);
|
|
@@ -23569,7 +23290,7 @@ function createDaemonConfig(connection, agents = [], installableAgents = []) {
|
|
|
23569
23290
|
import { randomUUID } from "node:crypto";
|
|
23570
23291
|
import {
|
|
23571
23292
|
mkdir as mkdir3,
|
|
23572
|
-
open as
|
|
23293
|
+
open as open4,
|
|
23573
23294
|
realpath as realpath6,
|
|
23574
23295
|
rename as rename3,
|
|
23575
23296
|
stat as stat5,
|
|
@@ -23790,6 +23511,8 @@ function decodeClaimResponse(value) {
|
|
|
23790
23511
|
}
|
|
23791
23512
|
async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
|
|
23792
23513
|
const agents = localAgents.map((agent) => ({
|
|
23514
|
+
agentPath: agent.agentIdentity.requestedPath,
|
|
23515
|
+
agentVersion: agent.agentVersion,
|
|
23793
23516
|
id: agent.id,
|
|
23794
23517
|
label: agent.label
|
|
23795
23518
|
}));
|
|
@@ -23799,10 +23522,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
23799
23522
|
response = await fetch2(endpoint, {
|
|
23800
23523
|
body: JSON.stringify({
|
|
23801
23524
|
agents,
|
|
23802
|
-
installableAgents
|
|
23803
|
-
id: agent.id,
|
|
23804
|
-
label: agent.label
|
|
23805
|
-
})),
|
|
23525
|
+
installableAgents,
|
|
23806
23526
|
machineName: hostname3(),
|
|
23807
23527
|
pairingCode: options.code,
|
|
23808
23528
|
workspaceName: basename(defaultWorkspace) || "Local workspace"
|
|
@@ -23885,7 +23605,7 @@ async function readSavedConnection(channelId) {
|
|
|
23885
23605
|
`${channelId}.json`
|
|
23886
23606
|
);
|
|
23887
23607
|
let encoded = "";
|
|
23888
|
-
const handle = await
|
|
23608
|
+
const handle = await open4(connectionPath, "r");
|
|
23889
23609
|
try {
|
|
23890
23610
|
const metadata = await handle.stat();
|
|
23891
23611
|
if (!metadata.isFile() || metadata.size > MAX_CONNECTION_FILE_LENGTH) {
|
|
@@ -23922,7 +23642,7 @@ function assertInventoryUsable(inventory) {
|
|
|
23922
23642
|
if (inventory.available.length + inventory.installable.length === 0) {
|
|
23923
23643
|
throw new PairingClientError(
|
|
23924
23644
|
"no_supported_agent",
|
|
23925
|
-
"No supported Agent is
|
|
23645
|
+
"No supported Agent is available for local discovery"
|
|
23926
23646
|
);
|
|
23927
23647
|
}
|
|
23928
23648
|
}
|
|
@@ -24010,12 +23730,12 @@ async function resumeLocalMachine(arguments_, signal = new AbortController().sig
|
|
|
24010
23730
|
// src/run-daemon.ts
|
|
24011
23731
|
import { basename as basename3 } from "node:path";
|
|
24012
23732
|
import { styleText } from "node:util";
|
|
24013
|
-
import { WebSocket as WebSocket2 } from "undici";
|
|
23733
|
+
import { fetch as fetch4, WebSocket as WebSocket2 } from "undici";
|
|
24014
23734
|
|
|
24015
23735
|
// src/acp/session-manager.ts
|
|
24016
23736
|
import { spawn as spawn3 } from "node:child_process";
|
|
24017
23737
|
import {
|
|
24018
|
-
methods as
|
|
23738
|
+
methods as methods6,
|
|
24019
23739
|
ndJsonStream as ndJsonStream2,
|
|
24020
23740
|
PROTOCOL_VERSION as PROTOCOL_VERSION2,
|
|
24021
23741
|
RequestError as RequestError2
|
|
@@ -24529,39 +24249,524 @@ var nativeSessionPageSchema = external_exports.object({
|
|
|
24529
24249
|
nextCursor: external_exports.string().min(1).max(4096).nullish()
|
|
24530
24250
|
}).readonly();
|
|
24531
24251
|
|
|
24532
|
-
// src/acp/session-
|
|
24533
|
-
|
|
24534
|
-
|
|
24535
|
-
|
|
24536
|
-
|
|
24537
|
-
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
24544
|
-
|
|
24545
|
-
|
|
24546
|
-
|
|
24547
|
-
|
|
24548
|
-
|
|
24549
|
-
|
|
24550
|
-
|
|
24551
|
-
|
|
24552
|
-
|
|
24553
|
-
|
|
24554
|
-
|
|
24555
|
-
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
24560
|
-
|
|
24561
|
-
|
|
24562
|
-
|
|
24563
|
-
|
|
24564
|
-
|
|
24252
|
+
// src/acp/session-config/session-config-protocol.ts
|
|
24253
|
+
import { methods as methods5 } from "@agentclientprotocol/sdk";
|
|
24254
|
+
var AGENT_DEFAULT_REASONING_EFFORT = "agent_default";
|
|
24255
|
+
var MAXIMUM_CONFIG_OPTIONS = 100;
|
|
24256
|
+
var SessionConfigProtocolError = class extends Error {
|
|
24257
|
+
code = "invalid_session_configuration_response";
|
|
24258
|
+
constructor(message, options = {}) {
|
|
24259
|
+
super(message, options);
|
|
24260
|
+
this.name = "SessionConfigProtocolError";
|
|
24261
|
+
}
|
|
24262
|
+
};
|
|
24263
|
+
function isRecord6(value) {
|
|
24264
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24265
|
+
}
|
|
24266
|
+
function readString2(value, fallback = "") {
|
|
24267
|
+
return typeof value === "string" ? value : fallback;
|
|
24268
|
+
}
|
|
24269
|
+
function truncate2(value, maximum) {
|
|
24270
|
+
return value.length <= maximum ? value : value.slice(0, maximum);
|
|
24271
|
+
}
|
|
24272
|
+
function readBoolean(value, fallback = false) {
|
|
24273
|
+
return typeof value === "boolean" ? value : fallback;
|
|
24274
|
+
}
|
|
24275
|
+
function normalizeConfigValue(option, groupId = "", groupName = "") {
|
|
24276
|
+
return {
|
|
24277
|
+
description: truncate2(readString2(option["description"]), 500),
|
|
24278
|
+
groupId: truncate2(groupId, 128),
|
|
24279
|
+
groupName: truncate2(groupName, 255),
|
|
24280
|
+
name: truncate2(
|
|
24281
|
+
readString2(option["name"], readString2(option["value"])),
|
|
24282
|
+
255
|
|
24283
|
+
),
|
|
24284
|
+
value: truncate2(readString2(option["value"]), 500)
|
|
24285
|
+
};
|
|
24286
|
+
}
|
|
24287
|
+
function normalizeConfigValues(value) {
|
|
24288
|
+
if (!Array.isArray(value)) {
|
|
24289
|
+
return [];
|
|
24290
|
+
}
|
|
24291
|
+
const normalized = [];
|
|
24292
|
+
for (const entry of value) {
|
|
24293
|
+
if (!isRecord6(entry)) {
|
|
24294
|
+
continue;
|
|
24295
|
+
}
|
|
24296
|
+
const groupedOptions = entry["options"];
|
|
24297
|
+
if (Array.isArray(groupedOptions)) {
|
|
24298
|
+
const groupId = readString2(entry["group"]);
|
|
24299
|
+
const groupName = readString2(entry["name"]);
|
|
24300
|
+
for (const groupedOption of groupedOptions) {
|
|
24301
|
+
if (isRecord6(groupedOption)) {
|
|
24302
|
+
normalized.push(
|
|
24303
|
+
normalizeConfigValue(groupedOption, groupId, groupName)
|
|
24304
|
+
);
|
|
24305
|
+
}
|
|
24306
|
+
}
|
|
24307
|
+
continue;
|
|
24308
|
+
}
|
|
24309
|
+
normalized.push(normalizeConfigValue(entry));
|
|
24310
|
+
}
|
|
24311
|
+
return normalized.filter((entry) => entry.value.length > 0).slice(0, 500);
|
|
24312
|
+
}
|
|
24313
|
+
function normalizeConfigOptions(value, modes) {
|
|
24314
|
+
const normalized = [];
|
|
24315
|
+
if (Array.isArray(value)) {
|
|
24316
|
+
for (const option of value) {
|
|
24317
|
+
if (!isRecord6(option)) {
|
|
24318
|
+
continue;
|
|
24319
|
+
}
|
|
24320
|
+
const id = truncate2(readString2(option["id"]), 128);
|
|
24321
|
+
const name = truncate2(readString2(option["name"], id), 255);
|
|
24322
|
+
if (id.length === 0 || name.length === 0) {
|
|
24323
|
+
continue;
|
|
24324
|
+
}
|
|
24325
|
+
if (option["type"] === "boolean") {
|
|
24326
|
+
normalized.push({
|
|
24327
|
+
booleanValue: readBoolean(option["currentValue"]),
|
|
24328
|
+
category: truncate2(readString2(option["category"]), 128),
|
|
24329
|
+
currentValue: "",
|
|
24330
|
+
description: truncate2(readString2(option["description"]), 500),
|
|
24331
|
+
id,
|
|
24332
|
+
name,
|
|
24333
|
+
type: "boolean",
|
|
24334
|
+
values: []
|
|
24335
|
+
});
|
|
24336
|
+
continue;
|
|
24337
|
+
}
|
|
24338
|
+
if (option["type"] === "select") {
|
|
24339
|
+
const values = normalizeConfigValues(option["options"]);
|
|
24340
|
+
const currentValue = truncate2(readString2(option["currentValue"]), 500);
|
|
24341
|
+
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue)) {
|
|
24342
|
+
normalized.push({
|
|
24343
|
+
booleanValue: false,
|
|
24344
|
+
category: truncate2(readString2(option["category"]), 128),
|
|
24345
|
+
currentValue,
|
|
24346
|
+
description: truncate2(readString2(option["description"]), 500),
|
|
24347
|
+
id,
|
|
24348
|
+
name,
|
|
24349
|
+
type: "select",
|
|
24350
|
+
values
|
|
24351
|
+
});
|
|
24352
|
+
}
|
|
24353
|
+
}
|
|
24354
|
+
}
|
|
24355
|
+
}
|
|
24356
|
+
if (isRecord6(modes)) {
|
|
24357
|
+
const values = [];
|
|
24358
|
+
const availableModes = modes["availableModes"];
|
|
24359
|
+
if (Array.isArray(availableModes)) {
|
|
24360
|
+
for (const mode of availableModes) {
|
|
24361
|
+
if (!isRecord6(mode)) {
|
|
24362
|
+
continue;
|
|
24363
|
+
}
|
|
24364
|
+
const id = truncate2(readString2(mode["id"]), 500);
|
|
24365
|
+
if (id.length === 0) {
|
|
24366
|
+
continue;
|
|
24367
|
+
}
|
|
24368
|
+
values.push({
|
|
24369
|
+
description: truncate2(readString2(mode["description"]), 500),
|
|
24370
|
+
groupId: "",
|
|
24371
|
+
groupName: "",
|
|
24372
|
+
name: truncate2(readString2(mode["name"], id), 255),
|
|
24373
|
+
value: id
|
|
24374
|
+
});
|
|
24375
|
+
}
|
|
24376
|
+
}
|
|
24377
|
+
const currentValue = truncate2(readString2(modes["currentModeId"]), 500);
|
|
24378
|
+
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue) && !normalized.some((entry) => entry.category === "mode")) {
|
|
24379
|
+
normalized.unshift({
|
|
24380
|
+
booleanValue: false,
|
|
24381
|
+
category: "mode",
|
|
24382
|
+
currentValue,
|
|
24383
|
+
description: "Agent session mode",
|
|
24384
|
+
id: "mode",
|
|
24385
|
+
name: "Mode",
|
|
24386
|
+
type: "select",
|
|
24387
|
+
values
|
|
24388
|
+
});
|
|
24389
|
+
}
|
|
24390
|
+
}
|
|
24391
|
+
return normalized.slice(0, 100);
|
|
24392
|
+
}
|
|
24393
|
+
function ensureReasoningEffortOption(current) {
|
|
24394
|
+
if (current.some((option) => option.category === "thought_level")) {
|
|
24395
|
+
return current;
|
|
24396
|
+
}
|
|
24397
|
+
const unavailable = {
|
|
24398
|
+
booleanValue: false,
|
|
24399
|
+
category: "thought_level",
|
|
24400
|
+
currentValue: AGENT_DEFAULT_REASONING_EFFORT,
|
|
24401
|
+
description: "This Agent does not expose adjustable reasoning effort for the selected model.",
|
|
24402
|
+
id: "reasoning_effort",
|
|
24403
|
+
name: "Reasoning effort",
|
|
24404
|
+
type: "select",
|
|
24405
|
+
values: [
|
|
24406
|
+
{
|
|
24407
|
+
description: "Selected by the Agent",
|
|
24408
|
+
groupId: "",
|
|
24409
|
+
groupName: "",
|
|
24410
|
+
name: "Agent default",
|
|
24411
|
+
value: AGENT_DEFAULT_REASONING_EFFORT
|
|
24412
|
+
}
|
|
24413
|
+
]
|
|
24414
|
+
};
|
|
24415
|
+
const modelIndex = current.findIndex((option) => option.category === "model");
|
|
24416
|
+
if (current.length < MAXIMUM_CONFIG_OPTIONS) {
|
|
24417
|
+
if (modelIndex < 0) {
|
|
24418
|
+
return [...current, unavailable];
|
|
24419
|
+
}
|
|
24420
|
+
return [
|
|
24421
|
+
...current.slice(0, modelIndex + 1),
|
|
24422
|
+
unavailable,
|
|
24423
|
+
...current.slice(modelIndex + 1)
|
|
24424
|
+
];
|
|
24425
|
+
}
|
|
24426
|
+
if (modelIndex < 0) {
|
|
24427
|
+
return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 1), unavailable];
|
|
24428
|
+
}
|
|
24429
|
+
if (modelIndex < MAXIMUM_CONFIG_OPTIONS - 1) {
|
|
24430
|
+
return [
|
|
24431
|
+
...current.slice(0, modelIndex + 1),
|
|
24432
|
+
unavailable,
|
|
24433
|
+
...current.slice(modelIndex + 1, MAXIMUM_CONFIG_OPTIONS - 1)
|
|
24434
|
+
];
|
|
24435
|
+
}
|
|
24436
|
+
const model = current[modelIndex];
|
|
24437
|
+
if (model === void 0) {
|
|
24438
|
+
return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 1), unavailable];
|
|
24439
|
+
}
|
|
24440
|
+
return [...current.slice(0, MAXIMUM_CONFIG_OPTIONS - 2), model, unavailable];
|
|
24441
|
+
}
|
|
24442
|
+
function normalizeStandardLifecycle(response) {
|
|
24443
|
+
const lifecycle = isRecord6(response) ? response : {};
|
|
24444
|
+
return ensureReasoningEffortOption(
|
|
24445
|
+
normalizeConfigOptions(lifecycle["configOptions"], lifecycle["modes"])
|
|
24446
|
+
);
|
|
24447
|
+
}
|
|
24448
|
+
function replaceStandardConfigOptions(current, value) {
|
|
24449
|
+
const next = normalizeConfigOptions(value, void 0);
|
|
24450
|
+
const withMode = next.some((option) => option.category === "mode") ? next : [
|
|
24451
|
+
...current.filter((option) => option.category === "mode"),
|
|
24452
|
+
...next
|
|
24453
|
+
].slice(0, 100);
|
|
24454
|
+
return ensureReasoningEffortOption(withMode);
|
|
24455
|
+
}
|
|
24456
|
+
function updateCurrentValue(current, configId, value) {
|
|
24457
|
+
return current.map(
|
|
24458
|
+
(option) => option.id === configId ? { ...option, currentValue: value } : option
|
|
24459
|
+
);
|
|
24460
|
+
}
|
|
24461
|
+
var StandardSessionConfigProtocol = class {
|
|
24462
|
+
configure = async (current, change, nativeSessionId, transport) => {
|
|
24463
|
+
const existing = current.find((option) => option.id === change.configId);
|
|
24464
|
+
if (existing === void 0) {
|
|
24465
|
+
return current;
|
|
24466
|
+
}
|
|
24467
|
+
if (existing.type === "select" && existing.category === "mode") {
|
|
24468
|
+
await transport.request(
|
|
24469
|
+
methods5.agent.session.setMode,
|
|
24470
|
+
{ modeId: change.value, sessionId: nativeSessionId },
|
|
24471
|
+
"ACP agent exited while setting the session mode",
|
|
24472
|
+
change.signal
|
|
24473
|
+
);
|
|
24474
|
+
return updateCurrentValue(current, existing.id, change.value);
|
|
24475
|
+
}
|
|
24476
|
+
const params = existing.type === "boolean" ? {
|
|
24477
|
+
configId: existing.id,
|
|
24478
|
+
sessionId: nativeSessionId,
|
|
24479
|
+
type: "boolean",
|
|
24480
|
+
value: change.booleanValue
|
|
24481
|
+
} : {
|
|
24482
|
+
configId: existing.id,
|
|
24483
|
+
sessionId: nativeSessionId,
|
|
24484
|
+
value: change.value
|
|
24485
|
+
};
|
|
24486
|
+
const response = await transport.request(
|
|
24487
|
+
methods5.agent.session.setConfigOption,
|
|
24488
|
+
params,
|
|
24489
|
+
"ACP agent exited while changing session configuration",
|
|
24490
|
+
change.signal
|
|
24491
|
+
);
|
|
24492
|
+
if (!isRecord6(response) || !Array.isArray(response["configOptions"])) {
|
|
24493
|
+
throw new SessionConfigProtocolError(
|
|
24494
|
+
"The Agent returned an invalid session configuration response"
|
|
24495
|
+
);
|
|
24496
|
+
}
|
|
24497
|
+
return replaceStandardConfigOptions(current, response["configOptions"]);
|
|
24498
|
+
};
|
|
24499
|
+
normalizeLifecycle = (response) => normalizeStandardLifecycle(response);
|
|
24500
|
+
normalizeUpdate = (current, value) => replaceStandardConfigOptions(current, value);
|
|
24501
|
+
};
|
|
24502
|
+
var standardSessionConfigProtocol = new StandardSessionConfigProtocol();
|
|
24503
|
+
|
|
24504
|
+
// src/acp/session-config/grok-build-session-config.ts
|
|
24505
|
+
var LEGACY_MODEL_CONFIG_ID = "grok_build_legacy_model";
|
|
24506
|
+
var LEGACY_REASONING_EFFORT_CONFIG_ID = "grok_build_legacy_reasoning_effort";
|
|
24507
|
+
function legacyOptions(response) {
|
|
24508
|
+
if (!isRecord6(response)) {
|
|
24509
|
+
return [];
|
|
24510
|
+
}
|
|
24511
|
+
const metadata = response["_meta"];
|
|
24512
|
+
if (!isRecord6(metadata)) {
|
|
24513
|
+
return [];
|
|
24514
|
+
}
|
|
24515
|
+
const sessionConfig = metadata["x.ai/sessionConfig"];
|
|
24516
|
+
if (!isRecord6(sessionConfig) || !Array.isArray(sessionConfig["options"])) {
|
|
24517
|
+
return [];
|
|
24518
|
+
}
|
|
24519
|
+
return sessionConfig["options"].slice(0, 500).filter(isRecord6);
|
|
24520
|
+
}
|
|
24521
|
+
function legacyValue(option) {
|
|
24522
|
+
const value = readString2(option["id"]);
|
|
24523
|
+
return {
|
|
24524
|
+
description: readString2(option["description"]).slice(0, 500),
|
|
24525
|
+
groupId: "",
|
|
24526
|
+
groupName: "",
|
|
24527
|
+
name: readString2(option["label"], value).slice(0, 255),
|
|
24528
|
+
value: value.slice(0, 500)
|
|
24529
|
+
};
|
|
24530
|
+
}
|
|
24531
|
+
function modelsRecord(response) {
|
|
24532
|
+
if (!isRecord6(response) || !isRecord6(response["models"])) {
|
|
24533
|
+
return {};
|
|
24534
|
+
}
|
|
24535
|
+
return response["models"];
|
|
24536
|
+
}
|
|
24537
|
+
function legacyModelOptions(response) {
|
|
24538
|
+
const options = legacyOptions(response);
|
|
24539
|
+
const models = modelsRecord(response);
|
|
24540
|
+
const values = [];
|
|
24541
|
+
for (const option of options) {
|
|
24542
|
+
if (option["category"] === "model") {
|
|
24543
|
+
const value = legacyValue(option);
|
|
24544
|
+
if (value.value.length > 0 && !values.some((existing) => existing.value === value.value)) {
|
|
24545
|
+
values.push(value);
|
|
24546
|
+
}
|
|
24547
|
+
}
|
|
24548
|
+
}
|
|
24549
|
+
if (values.length === 0 && Array.isArray(models["availableModels"])) {
|
|
24550
|
+
for (const model of models["availableModels"]) {
|
|
24551
|
+
if (!isRecord6(model)) {
|
|
24552
|
+
continue;
|
|
24553
|
+
}
|
|
24554
|
+
const value = readString2(model["modelId"]).slice(0, 500);
|
|
24555
|
+
if (value.length === 0) {
|
|
24556
|
+
continue;
|
|
24557
|
+
}
|
|
24558
|
+
if (!values.some((existing) => existing.value === value)) {
|
|
24559
|
+
values.push({
|
|
24560
|
+
description: "",
|
|
24561
|
+
groupId: "",
|
|
24562
|
+
groupName: "",
|
|
24563
|
+
name: readString2(model["name"], value).slice(0, 255),
|
|
24564
|
+
value
|
|
24565
|
+
});
|
|
24566
|
+
}
|
|
24567
|
+
}
|
|
24568
|
+
}
|
|
24569
|
+
const selected = options.find(
|
|
24570
|
+
(option) => option["category"] === "model" && option["selected"] === true
|
|
24571
|
+
);
|
|
24572
|
+
const currentValue = readString2(
|
|
24573
|
+
models["currentModelId"],
|
|
24574
|
+
selected === void 0 ? "" : readString2(selected["id"])
|
|
24575
|
+
).slice(0, 500);
|
|
24576
|
+
if (values.length === 0 || !values.some((value) => value.value === currentValue)) {
|
|
24577
|
+
return [];
|
|
24578
|
+
}
|
|
24579
|
+
const result = {
|
|
24580
|
+
booleanValue: false,
|
|
24581
|
+
category: "model",
|
|
24582
|
+
currentValue,
|
|
24583
|
+
description: "Model used by Grok Build",
|
|
24584
|
+
id: LEGACY_MODEL_CONFIG_ID,
|
|
24585
|
+
name: "Model",
|
|
24586
|
+
type: "select",
|
|
24587
|
+
values: values.slice(0, 500)
|
|
24588
|
+
};
|
|
24589
|
+
return [result];
|
|
24590
|
+
}
|
|
24591
|
+
function legacyReasoningEffortOptions(response) {
|
|
24592
|
+
const options = legacyOptions(response);
|
|
24593
|
+
const values = [];
|
|
24594
|
+
for (const option of options) {
|
|
24595
|
+
if (option["category"] !== "mode") {
|
|
24596
|
+
continue;
|
|
24597
|
+
}
|
|
24598
|
+
const value = legacyValue(option);
|
|
24599
|
+
if (value.value.length > 0 && !values.some((existing) => existing.value === value.value)) {
|
|
24600
|
+
values.push(value);
|
|
24601
|
+
}
|
|
24602
|
+
}
|
|
24603
|
+
if (values.length === 0) {
|
|
24604
|
+
return [];
|
|
24605
|
+
}
|
|
24606
|
+
const selected = options.find(
|
|
24607
|
+
(option) => option["category"] === "mode" && option["selected"] === true
|
|
24608
|
+
);
|
|
24609
|
+
if (selected === void 0) {
|
|
24610
|
+
values.unshift({
|
|
24611
|
+
description: "Use the selected model's default reasoning effort",
|
|
24612
|
+
groupId: "",
|
|
24613
|
+
groupName: "",
|
|
24614
|
+
name: "Agent default",
|
|
24615
|
+
value: AGENT_DEFAULT_REASONING_EFFORT
|
|
24616
|
+
});
|
|
24617
|
+
}
|
|
24618
|
+
const currentValue = selected === void 0 ? AGENT_DEFAULT_REASONING_EFFORT : readString2(selected["id"], AGENT_DEFAULT_REASONING_EFFORT);
|
|
24619
|
+
if (!values.some((value) => value.value === currentValue)) {
|
|
24620
|
+
return [];
|
|
24621
|
+
}
|
|
24622
|
+
const result = {
|
|
24623
|
+
booleanValue: false,
|
|
24624
|
+
category: "thought_level",
|
|
24625
|
+
currentValue,
|
|
24626
|
+
description: "Reasoning effort used by Grok Build",
|
|
24627
|
+
id: LEGACY_REASONING_EFFORT_CONFIG_ID,
|
|
24628
|
+
name: "Reasoning effort",
|
|
24629
|
+
type: "select",
|
|
24630
|
+
values: values.slice(0, 500)
|
|
24631
|
+
};
|
|
24632
|
+
return [result];
|
|
24633
|
+
}
|
|
24634
|
+
function normalizeGrokLifecycle(response) {
|
|
24635
|
+
const lifecycle = isRecord6(response) ? response : {};
|
|
24636
|
+
const standard = normalizeConfigOptions(
|
|
24637
|
+
lifecycle["configOptions"],
|
|
24638
|
+
lifecycle["modes"]
|
|
24639
|
+
);
|
|
24640
|
+
const normalized = [...standard];
|
|
24641
|
+
if (!normalized.some((option) => option.category === "model")) {
|
|
24642
|
+
normalized.push(...legacyModelOptions(response));
|
|
24643
|
+
}
|
|
24644
|
+
if (!normalized.some((option) => option.category === "thought_level")) {
|
|
24645
|
+
const efforts = legacyReasoningEffortOptions(response);
|
|
24646
|
+
if (efforts.length > 0) {
|
|
24647
|
+
const modelIndex = normalized.findIndex(
|
|
24648
|
+
(option) => option.category === "model"
|
|
24649
|
+
);
|
|
24650
|
+
normalized.splice(
|
|
24651
|
+
modelIndex < 0 ? normalized.length : modelIndex + 1,
|
|
24652
|
+
0,
|
|
24653
|
+
...efforts
|
|
24654
|
+
);
|
|
24655
|
+
}
|
|
24656
|
+
}
|
|
24657
|
+
return ensureReasoningEffortOption(normalized.slice(0, 100));
|
|
24658
|
+
}
|
|
24659
|
+
function updateCurrentValue2(current, category, value) {
|
|
24660
|
+
return current.map(
|
|
24661
|
+
(option) => option.category === category ? { ...option, currentValue: value } : option
|
|
24662
|
+
);
|
|
24663
|
+
}
|
|
24664
|
+
function validateGrokResponse(response, modelId) {
|
|
24665
|
+
if (!isRecord6(response) || !isRecord6(response["_meta"])) {
|
|
24666
|
+
throw new SessionConfigProtocolError(
|
|
24667
|
+
"Grok Build returned an invalid session configuration response"
|
|
24668
|
+
);
|
|
24669
|
+
}
|
|
24670
|
+
const model = response["_meta"]["model"];
|
|
24671
|
+
const appliedModel = isRecord6(model) ? model["Ok"] : model;
|
|
24672
|
+
if (appliedModel !== modelId) {
|
|
24673
|
+
throw new SessionConfigProtocolError(
|
|
24674
|
+
"Grok Build returned an invalid session configuration response"
|
|
24675
|
+
);
|
|
24676
|
+
}
|
|
24677
|
+
}
|
|
24678
|
+
var GrokBuildSessionConfigProtocol = class {
|
|
24679
|
+
configure = async (current, change, nativeSessionId, transport) => {
|
|
24680
|
+
const existing = current.find((option) => option.id === change.configId);
|
|
24681
|
+
if (existing === void 0 || existing.id !== LEGACY_MODEL_CONFIG_ID && existing.id !== LEGACY_REASONING_EFFORT_CONFIG_ID) {
|
|
24682
|
+
return await standardSessionConfigProtocol.configure(
|
|
24683
|
+
current,
|
|
24684
|
+
change,
|
|
24685
|
+
nativeSessionId,
|
|
24686
|
+
transport
|
|
24687
|
+
);
|
|
24688
|
+
}
|
|
24689
|
+
const model = current.find((option) => option.category === "model");
|
|
24690
|
+
if (model === void 0) {
|
|
24691
|
+
return current;
|
|
24692
|
+
}
|
|
24693
|
+
if (existing.category === "thought_level" && change.value === AGENT_DEFAULT_REASONING_EFFORT) {
|
|
24694
|
+
return current;
|
|
24695
|
+
}
|
|
24696
|
+
const modelId = existing.category === "model" ? change.value : model.currentValue;
|
|
24697
|
+
const params = {
|
|
24698
|
+
modelId,
|
|
24699
|
+
sessionId: nativeSessionId
|
|
24700
|
+
};
|
|
24701
|
+
if (existing.category === "thought_level") {
|
|
24702
|
+
params["_meta"] = {
|
|
24703
|
+
reasoningEffort: change.value
|
|
24704
|
+
};
|
|
24705
|
+
}
|
|
24706
|
+
const response = await transport.request(
|
|
24707
|
+
"session/set_model",
|
|
24708
|
+
params,
|
|
24709
|
+
existing.category === "model" ? "Grok Build exited while setting the session model" : "Grok Build exited while setting reasoning effort",
|
|
24710
|
+
change.signal
|
|
24711
|
+
);
|
|
24712
|
+
validateGrokResponse(response, modelId);
|
|
24713
|
+
const updated = updateCurrentValue2(
|
|
24714
|
+
current,
|
|
24715
|
+
existing.category,
|
|
24716
|
+
change.value
|
|
24717
|
+
);
|
|
24718
|
+
return existing.category === "thought_level" ? updated.map(
|
|
24719
|
+
(option) => option.category === "thought_level" ? {
|
|
24720
|
+
...option,
|
|
24721
|
+
values: option.values.filter(
|
|
24722
|
+
(value) => value.value !== AGENT_DEFAULT_REASONING_EFFORT
|
|
24723
|
+
)
|
|
24724
|
+
} : option
|
|
24725
|
+
) : updated;
|
|
24726
|
+
};
|
|
24727
|
+
normalizeLifecycle = (response) => normalizeGrokLifecycle(response);
|
|
24728
|
+
normalizeUpdate = (current, value) => standardSessionConfigProtocol.normalizeUpdate(current, value);
|
|
24729
|
+
};
|
|
24730
|
+
var grokBuildSessionConfigProtocol = new GrokBuildSessionConfigProtocol();
|
|
24731
|
+
|
|
24732
|
+
// src/acp/session-config/session-config-registry.ts
|
|
24733
|
+
function sessionConfigProtocolForAgent(agentId) {
|
|
24734
|
+
return agentId === "grok-build" ? grokBuildSessionConfigProtocol : standardSessionConfigProtocol;
|
|
24735
|
+
}
|
|
24736
|
+
|
|
24737
|
+
// src/acp/session-history.ts
|
|
24738
|
+
var AcpHistoryReplay = class {
|
|
24739
|
+
#messages = [];
|
|
24740
|
+
#lastMessageId = null;
|
|
24741
|
+
#characters = 0;
|
|
24742
|
+
#imageCharacters = 0;
|
|
24743
|
+
#truncated = false;
|
|
24744
|
+
record = (update) => {
|
|
24745
|
+
if (update.sessionUpdate !== "user_message_chunk" && update.sessionUpdate !== "agent_message_chunk")
|
|
24746
|
+
return;
|
|
24747
|
+
if (update.sessionUpdate === "agent_message_chunk" && isProgressMessage(update))
|
|
24748
|
+
return;
|
|
24749
|
+
const role = update.sessionUpdate === "user_message_chunk" ? "user" : "assistant";
|
|
24750
|
+
const content = update.content;
|
|
24751
|
+
const parsed = parseNativeHistoryText(
|
|
24752
|
+
content.type === "text" ? content.text : content.type === "image" ? `[@image](data:${content.mimeType};base64,${content.data})` : `[${content.type} attachment]`
|
|
24753
|
+
);
|
|
24754
|
+
const text = parsed.text;
|
|
24755
|
+
if (text.length === 0 && parsed.images.length === 0) return;
|
|
24756
|
+
const previous = this.#messages.at(-1);
|
|
24757
|
+
const id = update.messageId ?? null;
|
|
24758
|
+
const continuation = previous?.role === role && id === this.#lastMessageId;
|
|
24759
|
+
const combined = continuation ? `${previous.text}${text}` : text;
|
|
24760
|
+
const allImages = continuation ? [...previous.images ?? [], ...parsed.images] : parsed.images;
|
|
24761
|
+
const images = allImages.slice(0, 8);
|
|
24762
|
+
this.#truncated ||= images.length < allImages.length;
|
|
24763
|
+
if (continuation) {
|
|
24764
|
+
this.#messages.pop();
|
|
24765
|
+
this.#characters -= previous.text.length;
|
|
24766
|
+
this.#imageCharacters -= (previous.images ?? []).reduce(
|
|
24767
|
+
(size, image) => size + image.data.length,
|
|
24768
|
+
0
|
|
24769
|
+
);
|
|
24565
24770
|
}
|
|
24566
24771
|
const bounded = combined.slice(-SESSION_HISTORY_CHARACTER_LIMIT);
|
|
24567
24772
|
this.#truncated ||= bounded.length < combined.length;
|
|
@@ -24633,7 +24838,7 @@ var FoundAcpStoredSession = class extends AcpStoredSessionLookup {
|
|
|
24633
24838
|
var DeletedAcpStoredSession = class extends AcpStoredSessionLookup {
|
|
24634
24839
|
found = false;
|
|
24635
24840
|
};
|
|
24636
|
-
function
|
|
24841
|
+
function readString3(value, field) {
|
|
24637
24842
|
if (typeof value !== "string" || value.length === 0) {
|
|
24638
24843
|
throw new Error(`Stored ACP session has an invalid ${field}`);
|
|
24639
24844
|
}
|
|
@@ -24663,10 +24868,10 @@ function decodeSessionRow(row) {
|
|
|
24663
24868
|
throw new Error("Stored ACP session is not an object");
|
|
24664
24869
|
}
|
|
24665
24870
|
return new AcpStoredSession(
|
|
24666
|
-
|
|
24667
|
-
|
|
24668
|
-
|
|
24669
|
-
|
|
24871
|
+
readString3(Reflect.get(row, "session_id"), "session ID"),
|
|
24872
|
+
readString3(Reflect.get(row, "agent_id"), "agent ID"),
|
|
24873
|
+
readString3(Reflect.get(row, "native_session_id"), "native session ID"),
|
|
24874
|
+
readString3(Reflect.get(row, "cwd"), "working directory"),
|
|
24670
24875
|
readAdditionalDirectories(Reflect.get(row, "additional_directories_json")),
|
|
24671
24876
|
readPrompted(Reflect.get(row, "prompted"))
|
|
24672
24877
|
);
|
|
@@ -24928,168 +25133,37 @@ function createWritableAcpStream(output2) {
|
|
|
24928
25133
|
}
|
|
24929
25134
|
});
|
|
24930
25135
|
}
|
|
24931
|
-
function
|
|
25136
|
+
function truncate3(value, maximumLength) {
|
|
24932
25137
|
return value.length <= maximumLength ? value : `${value.slice(0, Math.max(0, maximumLength - 1))}\u2026`;
|
|
24933
25138
|
}
|
|
24934
|
-
function
|
|
25139
|
+
function isRecord7(value) {
|
|
24935
25140
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24936
25141
|
}
|
|
24937
|
-
function
|
|
25142
|
+
function readString4(value, fallback = "") {
|
|
24938
25143
|
return typeof value === "string" ? value : fallback;
|
|
24939
25144
|
}
|
|
24940
|
-
function readBoolean(value, fallback = false) {
|
|
24941
|
-
return typeof value === "boolean" ? value : fallback;
|
|
24942
|
-
}
|
|
24943
25145
|
function arraysEqual(left, right) {
|
|
24944
25146
|
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
24945
25147
|
}
|
|
24946
|
-
function
|
|
25148
|
+
function normalizeCapabilities(capabilities) {
|
|
25149
|
+
const session = capabilities.sessionCapabilities;
|
|
25150
|
+
const prompt = capabilities.promptCapabilities;
|
|
24947
25151
|
return {
|
|
24948
|
-
|
|
24949
|
-
|
|
24950
|
-
|
|
24951
|
-
|
|
24952
|
-
|
|
24953
|
-
|
|
24954
|
-
|
|
24955
|
-
|
|
25152
|
+
additionalDirectories: session?.additionalDirectories != null,
|
|
25153
|
+
audioPrompt: prompt?.audio === true,
|
|
25154
|
+
closeSession: session?.close != null,
|
|
25155
|
+
deleteSession: session?.delete != null,
|
|
25156
|
+
embeddedContextPrompt: prompt?.embeddedContext === true,
|
|
25157
|
+
imagePrompt: prompt?.image === true,
|
|
25158
|
+
listSessions: session?.list != null,
|
|
25159
|
+
loadSession: capabilities.loadSession === true,
|
|
25160
|
+
resumeSession: session?.resume != null,
|
|
25161
|
+
unstableForkSession: session?.fork != null
|
|
24956
25162
|
};
|
|
24957
25163
|
}
|
|
24958
|
-
function
|
|
24959
|
-
if (
|
|
24960
|
-
return
|
|
24961
|
-
}
|
|
24962
|
-
const normalized = [];
|
|
24963
|
-
for (const entry of value) {
|
|
24964
|
-
if (!isRecord6(entry)) {
|
|
24965
|
-
continue;
|
|
24966
|
-
}
|
|
24967
|
-
const groupedOptions = entry["options"];
|
|
24968
|
-
if (Array.isArray(groupedOptions)) {
|
|
24969
|
-
const groupId = readString3(entry["group"]);
|
|
24970
|
-
const groupName = readString3(entry["name"]);
|
|
24971
|
-
for (const groupedOption of groupedOptions) {
|
|
24972
|
-
if (isRecord6(groupedOption)) {
|
|
24973
|
-
normalized.push(
|
|
24974
|
-
normalizeConfigValue(groupedOption, groupId, groupName)
|
|
24975
|
-
);
|
|
24976
|
-
}
|
|
24977
|
-
}
|
|
24978
|
-
continue;
|
|
24979
|
-
}
|
|
24980
|
-
normalized.push(normalizeConfigValue(entry));
|
|
24981
|
-
}
|
|
24982
|
-
return normalized.filter((entry) => entry.value.length > 0).slice(0, 500);
|
|
24983
|
-
}
|
|
24984
|
-
function normalizeConfigOptions(value, modes) {
|
|
24985
|
-
const normalized = [];
|
|
24986
|
-
if (Array.isArray(value)) {
|
|
24987
|
-
for (const option of value) {
|
|
24988
|
-
if (!isRecord6(option)) {
|
|
24989
|
-
continue;
|
|
24990
|
-
}
|
|
24991
|
-
const id = truncate2(readString3(option["id"]), 128);
|
|
24992
|
-
const name = truncate2(readString3(option["name"], id), 255);
|
|
24993
|
-
if (id.length === 0 || name.length === 0) {
|
|
24994
|
-
continue;
|
|
24995
|
-
}
|
|
24996
|
-
if (option["type"] === "boolean") {
|
|
24997
|
-
normalized.push({
|
|
24998
|
-
booleanValue: readBoolean(option["currentValue"]),
|
|
24999
|
-
category: truncate2(readString3(option["category"]), 128),
|
|
25000
|
-
currentValue: "",
|
|
25001
|
-
description: truncate2(readString3(option["description"]), 500),
|
|
25002
|
-
id,
|
|
25003
|
-
name,
|
|
25004
|
-
type: "boolean",
|
|
25005
|
-
values: []
|
|
25006
|
-
});
|
|
25007
|
-
continue;
|
|
25008
|
-
}
|
|
25009
|
-
if (option["type"] === "select") {
|
|
25010
|
-
const values = normalizeConfigValues(option["options"]);
|
|
25011
|
-
const currentValue = truncate2(readString3(option["currentValue"]), 500);
|
|
25012
|
-
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue)) {
|
|
25013
|
-
normalized.push({
|
|
25014
|
-
booleanValue: false,
|
|
25015
|
-
category: truncate2(readString3(option["category"]), 128),
|
|
25016
|
-
currentValue,
|
|
25017
|
-
description: truncate2(readString3(option["description"]), 500),
|
|
25018
|
-
id,
|
|
25019
|
-
name,
|
|
25020
|
-
type: "select",
|
|
25021
|
-
values
|
|
25022
|
-
});
|
|
25023
|
-
}
|
|
25024
|
-
}
|
|
25025
|
-
}
|
|
25026
|
-
}
|
|
25027
|
-
if (isRecord6(modes)) {
|
|
25028
|
-
const values = [];
|
|
25029
|
-
const availableModes = modes["availableModes"];
|
|
25030
|
-
if (Array.isArray(availableModes)) {
|
|
25031
|
-
for (const mode of availableModes) {
|
|
25032
|
-
if (!isRecord6(mode)) {
|
|
25033
|
-
continue;
|
|
25034
|
-
}
|
|
25035
|
-
const id = truncate2(readString3(mode["id"]), 500);
|
|
25036
|
-
if (id.length === 0) {
|
|
25037
|
-
continue;
|
|
25038
|
-
}
|
|
25039
|
-
values.push({
|
|
25040
|
-
description: truncate2(readString3(mode["description"]), 500),
|
|
25041
|
-
groupId: "",
|
|
25042
|
-
groupName: "",
|
|
25043
|
-
name: truncate2(readString3(mode["name"], id), 255),
|
|
25044
|
-
value: id
|
|
25045
|
-
});
|
|
25046
|
-
}
|
|
25047
|
-
}
|
|
25048
|
-
const currentValue = truncate2(readString3(modes["currentModeId"]), 500);
|
|
25049
|
-
if (currentValue.length > 0 && values.some((entry) => entry.value === currentValue) && !normalized.some((entry) => entry.category === "mode")) {
|
|
25050
|
-
normalized.unshift({
|
|
25051
|
-
booleanValue: false,
|
|
25052
|
-
category: "mode",
|
|
25053
|
-
currentValue,
|
|
25054
|
-
description: "Agent session mode",
|
|
25055
|
-
id: "mode",
|
|
25056
|
-
name: "Mode",
|
|
25057
|
-
type: "select",
|
|
25058
|
-
values
|
|
25059
|
-
});
|
|
25060
|
-
}
|
|
25061
|
-
}
|
|
25062
|
-
return normalized.slice(0, 100);
|
|
25063
|
-
}
|
|
25064
|
-
function replaceConfigOptionsKeepingMode(current, value) {
|
|
25065
|
-
const next = normalizeConfigOptions(value, void 0);
|
|
25066
|
-
if (next.some((option) => option.category === "mode")) {
|
|
25067
|
-
return next;
|
|
25068
|
-
}
|
|
25069
|
-
return [
|
|
25070
|
-
...current.filter((option) => option.category === "mode"),
|
|
25071
|
-
...next
|
|
25072
|
-
].slice(0, 100);
|
|
25073
|
-
}
|
|
25074
|
-
function normalizeCapabilities(capabilities) {
|
|
25075
|
-
const session = capabilities.sessionCapabilities;
|
|
25076
|
-
const prompt = capabilities.promptCapabilities;
|
|
25077
|
-
return {
|
|
25078
|
-
additionalDirectories: session?.additionalDirectories != null,
|
|
25079
|
-
audioPrompt: prompt?.audio === true,
|
|
25080
|
-
closeSession: session?.close != null,
|
|
25081
|
-
deleteSession: session?.delete != null,
|
|
25082
|
-
embeddedContextPrompt: prompt?.embeddedContext === true,
|
|
25083
|
-
imagePrompt: prompt?.image === true,
|
|
25084
|
-
listSessions: session?.list != null,
|
|
25085
|
-
loadSession: capabilities.loadSession === true,
|
|
25086
|
-
resumeSession: session?.resume != null,
|
|
25087
|
-
unstableForkSession: session?.fork != null
|
|
25088
|
-
};
|
|
25089
|
-
}
|
|
25090
|
-
function elicitationFieldType(value) {
|
|
25091
|
-
if (value === "boolean") {
|
|
25092
|
-
return "boolean";
|
|
25164
|
+
function elicitationFieldType(value) {
|
|
25165
|
+
if (value === "boolean") {
|
|
25166
|
+
return "boolean";
|
|
25093
25167
|
}
|
|
25094
25168
|
if (value === "integer") {
|
|
25095
25169
|
return "integer";
|
|
@@ -25107,11 +25181,11 @@ function normalizeElicitationOptions(schema) {
|
|
|
25107
25181
|
const oneOf = schema["oneOf"];
|
|
25108
25182
|
if (Array.isArray(oneOf)) {
|
|
25109
25183
|
for (const option of oneOf) {
|
|
25110
|
-
if (
|
|
25184
|
+
if (isRecord7(option) && typeof option["const"] === "string") {
|
|
25111
25185
|
normalized.push({
|
|
25112
|
-
description:
|
|
25113
|
-
label:
|
|
25114
|
-
value:
|
|
25186
|
+
description: truncate3(readString4(option["description"]), 500),
|
|
25187
|
+
label: truncate3(readString4(option["title"], option["const"]), 255),
|
|
25188
|
+
value: truncate3(option["const"], 500)
|
|
25115
25189
|
});
|
|
25116
25190
|
}
|
|
25117
25191
|
}
|
|
@@ -25127,7 +25201,7 @@ function normalizeElicitationOptions(schema) {
|
|
|
25127
25201
|
return normalized.slice(0, 200);
|
|
25128
25202
|
}
|
|
25129
25203
|
const items = schema["items"];
|
|
25130
|
-
if (!
|
|
25204
|
+
if (!isRecord7(items)) {
|
|
25131
25205
|
return normalized;
|
|
25132
25206
|
}
|
|
25133
25207
|
const anyOf = items["anyOf"];
|
|
@@ -25140,7 +25214,7 @@ function numericString(value) {
|
|
|
25140
25214
|
return typeof value === "number" && Number.isFinite(value) ? value.toString() : "";
|
|
25141
25215
|
}
|
|
25142
25216
|
function normalizeElicitationFields(requestedSchema) {
|
|
25143
|
-
if (!
|
|
25217
|
+
if (!isRecord7(requestedSchema) || !isRecord7(requestedSchema["properties"])) {
|
|
25144
25218
|
return [];
|
|
25145
25219
|
}
|
|
25146
25220
|
const properties = requestedSchema["properties"];
|
|
@@ -25150,7 +25224,7 @@ function normalizeElicitationFields(requestedSchema) {
|
|
|
25150
25224
|
);
|
|
25151
25225
|
const normalized = [];
|
|
25152
25226
|
for (const [name, property] of Object.entries(properties)) {
|
|
25153
|
-
if (!
|
|
25227
|
+
if (!isRecord7(property)) {
|
|
25154
25228
|
continue;
|
|
25155
25229
|
}
|
|
25156
25230
|
const type = elicitationFieldType(property["type"]);
|
|
@@ -25160,9 +25234,9 @@ function normalizeElicitationFields(requestedSchema) {
|
|
|
25160
25234
|
normalized.push({
|
|
25161
25235
|
defaultBooleanValue: typeof defaultValue === "boolean" ? defaultValue : false,
|
|
25162
25236
|
defaultNumberValue: typeof defaultValue === "number" && Number.isFinite(defaultValue) ? defaultValue : 0,
|
|
25163
|
-
defaultStringValue: typeof defaultValue === "string" ?
|
|
25164
|
-
description:
|
|
25165
|
-
format:
|
|
25237
|
+
defaultStringValue: typeof defaultValue === "string" ? truncate3(defaultValue, 1e4) : Array.isArray(defaultValue) ? truncate3(JSON.stringify(defaultValue), 1e4) : "",
|
|
25238
|
+
description: truncate3(readString4(property["description"]), 500),
|
|
25239
|
+
format: truncate3(readString4(property["format"]), 64),
|
|
25166
25240
|
hasDefaultValue: defaultValue !== void 0 && defaultValue !== null,
|
|
25167
25241
|
maximum: numericString(property["maximum"]),
|
|
25168
25242
|
maximumLength: numericString(
|
|
@@ -25172,11 +25246,11 @@ function normalizeElicitationFields(requestedSchema) {
|
|
|
25172
25246
|
minimumLength: numericString(
|
|
25173
25247
|
property["minLength"] ?? property["minItems"]
|
|
25174
25248
|
),
|
|
25175
|
-
name:
|
|
25249
|
+
name: truncate3(name, 128),
|
|
25176
25250
|
options,
|
|
25177
|
-
pattern:
|
|
25251
|
+
pattern: truncate3(readString4(property["pattern"]), 500),
|
|
25178
25252
|
required: required2.has(name),
|
|
25179
|
-
title:
|
|
25253
|
+
title: truncate3(readString4(property["title"], name), 255),
|
|
25180
25254
|
type: normalizedType
|
|
25181
25255
|
});
|
|
25182
25256
|
}
|
|
@@ -25245,7 +25319,7 @@ function validateElicitationContent(encoded, requestedSchema) {
|
|
|
25245
25319
|
"invalid_elicitation_response"
|
|
25246
25320
|
);
|
|
25247
25321
|
}
|
|
25248
|
-
if (!
|
|
25322
|
+
if (!isRecord7(decoded) || !isRecord7(requestedSchema) || !isRecord7(requestedSchema["properties"])) {
|
|
25249
25323
|
throw new AcpExecutionError(
|
|
25250
25324
|
"Elicitation response does not match the requested form",
|
|
25251
25325
|
{},
|
|
@@ -25269,7 +25343,7 @@ function validateElicitationContent(encoded, requestedSchema) {
|
|
|
25269
25343
|
const validated = {};
|
|
25270
25344
|
for (const [name, value] of Object.entries(decoded)) {
|
|
25271
25345
|
const property = properties[name];
|
|
25272
|
-
if (!
|
|
25346
|
+
if (!isRecord7(property)) {
|
|
25273
25347
|
throw new AcpExecutionError(
|
|
25274
25348
|
`Elicitation field ${name} was not requested`,
|
|
25275
25349
|
{},
|
|
@@ -25421,6 +25495,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25421
25495
|
#pendingPermissions = /* @__PURE__ */ new Map();
|
|
25422
25496
|
#preSessionUpdates = [];
|
|
25423
25497
|
#processExit;
|
|
25498
|
+
#sessionConfigProtocol;
|
|
25424
25499
|
#store;
|
|
25425
25500
|
#verifiedAgentVersion;
|
|
25426
25501
|
#preSessionUpdateBytes = 0;
|
|
@@ -25439,6 +25514,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25439
25514
|
unstableForkSession: false
|
|
25440
25515
|
};
|
|
25441
25516
|
#commands = [];
|
|
25517
|
+
#configRevision = 0;
|
|
25442
25518
|
#configOptions = [];
|
|
25443
25519
|
#nativeSessionId = "";
|
|
25444
25520
|
#prompted = false;
|
|
@@ -25456,6 +25532,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25456
25532
|
this.#cwd = cwd;
|
|
25457
25533
|
this.#getObserver = getObserver;
|
|
25458
25534
|
this.#mobiusSessionId = mobiusSessionId;
|
|
25535
|
+
this.#sessionConfigProtocol = sessionConfigProtocolForAgent(agent.id);
|
|
25459
25536
|
this.#store = store;
|
|
25460
25537
|
this.#verifiedAgentVersion = agent.agentVersion;
|
|
25461
25538
|
this.#child = spawn3(agent.adapterPath, [...agent.arguments], {
|
|
@@ -25560,7 +25637,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25560
25637
|
try {
|
|
25561
25638
|
await this.race(
|
|
25562
25639
|
this.#connection.agent.request(
|
|
25563
|
-
|
|
25640
|
+
methods6.agent.session.load,
|
|
25564
25641
|
{
|
|
25565
25642
|
additionalDirectories: [...this.#additionalDirectories],
|
|
25566
25643
|
cwd: this.#cwd,
|
|
@@ -25582,7 +25659,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25582
25659
|
async #initializeAgent(signal) {
|
|
25583
25660
|
const initialized = await this.race(
|
|
25584
25661
|
this.#connection.agent.request(
|
|
25585
|
-
|
|
25662
|
+
methods6.agent.initialize,
|
|
25586
25663
|
{
|
|
25587
25664
|
clientCapabilities: {
|
|
25588
25665
|
elicitation: { form: {}, url: {} },
|
|
@@ -25609,11 +25686,11 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25609
25686
|
}
|
|
25610
25687
|
const capabilities = initialized.agentCapabilities ?? {};
|
|
25611
25688
|
this.#capabilities = normalizeCapabilities(capabilities);
|
|
25612
|
-
this.#agentName =
|
|
25689
|
+
this.#agentName = truncate3(
|
|
25613
25690
|
initialized.agentInfo?.title ?? initialized.agentInfo?.name ?? this.#agentId,
|
|
25614
25691
|
255
|
|
25615
25692
|
);
|
|
25616
|
-
this.#agentVersion =
|
|
25693
|
+
this.#agentVersion = truncate3(
|
|
25617
25694
|
this.#verifiedAgentVersion.length > 0 ? this.#verifiedAgentVersion : initialized.agentInfo?.version ?? "",
|
|
25618
25695
|
128
|
|
25619
25696
|
);
|
|
@@ -25650,7 +25727,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25650
25727
|
);
|
|
25651
25728
|
const forked = await this.race(
|
|
25652
25729
|
this.#connection.agent.request(
|
|
25653
|
-
|
|
25730
|
+
methods6.agent.session.fork,
|
|
25654
25731
|
{
|
|
25655
25732
|
sessionId: nativeSessionIdSchema.parse(origin.nativeSessionId),
|
|
25656
25733
|
cwd: this.#cwd,
|
|
@@ -25683,7 +25760,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25683
25760
|
if (this.#capabilities.resumeSession) {
|
|
25684
25761
|
lifecycleResponse = await this.race(
|
|
25685
25762
|
this.#connection.agent.request(
|
|
25686
|
-
|
|
25763
|
+
methods6.agent.session.resume,
|
|
25687
25764
|
{
|
|
25688
25765
|
additionalDirectories: [...this.#additionalDirectories],
|
|
25689
25766
|
cwd: this.#cwd,
|
|
@@ -25700,7 +25777,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25700
25777
|
try {
|
|
25701
25778
|
lifecycleResponse = await this.race(
|
|
25702
25779
|
this.#connection.agent.request(
|
|
25703
|
-
|
|
25780
|
+
methods6.agent.session.load,
|
|
25704
25781
|
{
|
|
25705
25782
|
additionalDirectories: [...this.#additionalDirectories],
|
|
25706
25783
|
cwd: this.#cwd,
|
|
@@ -25736,7 +25813,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25736
25813
|
}
|
|
25737
25814
|
const created = await this.race(
|
|
25738
25815
|
this.#connection.agent.request(
|
|
25739
|
-
|
|
25816
|
+
methods6.agent.session.new,
|
|
25740
25817
|
{
|
|
25741
25818
|
additionalDirectories: [...this.#additionalDirectories],
|
|
25742
25819
|
cwd: this.#cwd,
|
|
@@ -25750,11 +25827,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25750
25827
|
this.selectNativeSession(created.sessionId);
|
|
25751
25828
|
lifecycleResponse = created;
|
|
25752
25829
|
}
|
|
25753
|
-
|
|
25754
|
-
this.#configOptions = normalizeConfigOptions(
|
|
25755
|
-
lifecycleRecord["configOptions"],
|
|
25756
|
-
lifecycleRecord["modes"]
|
|
25757
|
-
);
|
|
25830
|
+
this.#configOptions = this.#sessionConfigProtocol.normalizeLifecycle(lifecycleResponse);
|
|
25758
25831
|
await this.#updateTail;
|
|
25759
25832
|
signal.throwIfAborted();
|
|
25760
25833
|
if (this.#prompted) {
|
|
@@ -25779,7 +25852,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25779
25852
|
);
|
|
25780
25853
|
const response = await this.race(
|
|
25781
25854
|
this.#connection.agent.request(
|
|
25782
|
-
|
|
25855
|
+
methods6.agent.session.list,
|
|
25783
25856
|
cursor === null ? {} : { cursor },
|
|
25784
25857
|
{ cancellationSignal: signal }
|
|
25785
25858
|
),
|
|
@@ -25804,7 +25877,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25804
25877
|
);
|
|
25805
25878
|
await this.race(
|
|
25806
25879
|
this.#connection.agent.request(
|
|
25807
|
-
|
|
25880
|
+
methods6.agent.session.delete,
|
|
25808
25881
|
{ sessionId: nativeSessionIdSchema.parse(nativeSessionId) },
|
|
25809
25882
|
{ cancellationSignal: signal }
|
|
25810
25883
|
),
|
|
@@ -25825,64 +25898,50 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25825
25898
|
);
|
|
25826
25899
|
}
|
|
25827
25900
|
if (existing.type === "select") {
|
|
25828
|
-
if (
|
|
25901
|
+
if (existing.values.length < 2) {
|
|
25829
25902
|
throw new AcpExecutionError(
|
|
25830
|
-
"The requested ACP configuration
|
|
25903
|
+
"The requested ACP configuration option is unavailable",
|
|
25831
25904
|
{},
|
|
25832
25905
|
"invalid_session_configuration"
|
|
25833
25906
|
);
|
|
25834
25907
|
}
|
|
25835
|
-
if (existing.
|
|
25836
|
-
|
|
25837
|
-
|
|
25838
|
-
|
|
25839
|
-
|
|
25840
|
-
{ cancellationSignal: options.signal }
|
|
25841
|
-
),
|
|
25842
|
-
"ACP agent exited while setting the session mode",
|
|
25843
|
-
options.signal
|
|
25844
|
-
);
|
|
25845
|
-
this.#configOptions = this.#configOptions.map(
|
|
25846
|
-
(option) => option.id === existing.id ? { ...option, currentValue: options.value } : option
|
|
25847
|
-
);
|
|
25848
|
-
} else {
|
|
25849
|
-
const response = await this.race(
|
|
25850
|
-
this.#connection.agent.request(
|
|
25851
|
-
methods5.agent.session.setConfigOption,
|
|
25852
|
-
{
|
|
25853
|
-
configId: existing.id,
|
|
25854
|
-
sessionId: this.#nativeSessionId,
|
|
25855
|
-
value: options.value
|
|
25856
|
-
},
|
|
25857
|
-
{ cancellationSignal: options.signal }
|
|
25858
|
-
),
|
|
25859
|
-
"ACP agent exited while changing session configuration",
|
|
25860
|
-
options.signal
|
|
25861
|
-
);
|
|
25862
|
-
this.#configOptions = replaceConfigOptionsKeepingMode(
|
|
25863
|
-
this.#configOptions,
|
|
25864
|
-
response.configOptions
|
|
25908
|
+
if (!existing.values.some((entry) => entry.value === options.value)) {
|
|
25909
|
+
throw new AcpExecutionError(
|
|
25910
|
+
"The requested ACP configuration value is unavailable",
|
|
25911
|
+
{},
|
|
25912
|
+
"invalid_session_configuration"
|
|
25865
25913
|
);
|
|
25866
25914
|
}
|
|
25867
|
-
}
|
|
25868
|
-
|
|
25869
|
-
|
|
25870
|
-
|
|
25871
|
-
{
|
|
25872
|
-
configId: existing.id,
|
|
25873
|
-
sessionId: this.#nativeSessionId,
|
|
25874
|
-
type: "boolean",
|
|
25875
|
-
value: options.booleanValue
|
|
25876
|
-
},
|
|
25877
|
-
{ cancellationSignal: options.signal }
|
|
25878
|
-
),
|
|
25879
|
-
"ACP agent exited while changing session configuration",
|
|
25880
|
-
options.signal
|
|
25881
|
-
);
|
|
25882
|
-
this.#configOptions = replaceConfigOptionsKeepingMode(
|
|
25915
|
+
}
|
|
25916
|
+
const configRevision = this.#configRevision;
|
|
25917
|
+
try {
|
|
25918
|
+
const configured = await this.#sessionConfigProtocol.configure(
|
|
25883
25919
|
this.#configOptions,
|
|
25884
|
-
|
|
25920
|
+
options,
|
|
25921
|
+
this.#nativeSessionId,
|
|
25922
|
+
{
|
|
25923
|
+
request: async (method, params, failureMessage, signal) => await this.race(
|
|
25924
|
+
this.#connection.agent.request(method, params, {
|
|
25925
|
+
cancellationSignal: signal
|
|
25926
|
+
}),
|
|
25927
|
+
failureMessage,
|
|
25928
|
+
signal
|
|
25929
|
+
)
|
|
25930
|
+
}
|
|
25885
25931
|
);
|
|
25932
|
+
await this.#updateTail;
|
|
25933
|
+
if (this.#configRevision === configRevision) {
|
|
25934
|
+
this.#configOptions = configured;
|
|
25935
|
+
}
|
|
25936
|
+
} catch (error61) {
|
|
25937
|
+
if (error61 instanceof SessionConfigProtocolError) {
|
|
25938
|
+
throw new AcpExecutionError(
|
|
25939
|
+
error61.message,
|
|
25940
|
+
{ cause: error61 },
|
|
25941
|
+
error61.code
|
|
25942
|
+
);
|
|
25943
|
+
}
|
|
25944
|
+
throw error61;
|
|
25886
25945
|
}
|
|
25887
25946
|
return this.#configOptions;
|
|
25888
25947
|
};
|
|
@@ -25966,7 +26025,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
25966
26025
|
try {
|
|
25967
26026
|
const response = await this.race(
|
|
25968
26027
|
this.#connection.agent.request(
|
|
25969
|
-
|
|
26028
|
+
methods6.agent.session.prompt,
|
|
25970
26029
|
{ prompt, sessionId: this.#nativeSessionId },
|
|
25971
26030
|
{ cancellationSignal: options.signal }
|
|
25972
26031
|
),
|
|
@@ -26013,7 +26072,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26013
26072
|
try {
|
|
26014
26073
|
await this.cancelPendingInteractions();
|
|
26015
26074
|
if (this.#turn.running) {
|
|
26016
|
-
await this.#connection.agent.notify(
|
|
26075
|
+
await this.#connection.agent.notify(methods6.agent.session.cancel, {
|
|
26017
26076
|
sessionId: this.#nativeSessionId
|
|
26018
26077
|
});
|
|
26019
26078
|
}
|
|
@@ -26103,8 +26162,8 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26103
26162
|
const interactionId = `permission-${crypto.randomUUID()}`;
|
|
26104
26163
|
const options = request.options.slice(0, 20).map((option) => ({
|
|
26105
26164
|
kind: option.kind,
|
|
26106
|
-
name:
|
|
26107
|
-
optionId:
|
|
26165
|
+
name: truncate3(option.name, 255),
|
|
26166
|
+
optionId: truncate3(option.optionId, 255)
|
|
26108
26167
|
}));
|
|
26109
26168
|
if (options.length === 0) {
|
|
26110
26169
|
throw new AcpExecutionError(
|
|
@@ -26129,9 +26188,9 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26129
26188
|
kind: SESSION_PERMISSION_REQUESTED_KIND,
|
|
26130
26189
|
options,
|
|
26131
26190
|
sessionId: this.#mobiusSessionId,
|
|
26132
|
-
title:
|
|
26133
|
-
toolCallId:
|
|
26134
|
-
toolKind:
|
|
26191
|
+
title: truncate3(request.toolCall.title ?? "Permission required", 500),
|
|
26192
|
+
toolCallId: truncate3(request.toolCall.toolCallId, 255),
|
|
26193
|
+
toolKind: truncate3(request.toolCall.kind ?? "other", 64)
|
|
26135
26194
|
});
|
|
26136
26195
|
return await pending.completion.promise;
|
|
26137
26196
|
} finally {
|
|
@@ -26160,7 +26219,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26160
26219
|
const schemaValue = Reflect.get(request, "requestedSchema");
|
|
26161
26220
|
const requestedSchema = request.mode === "form" ? schemaValue : {};
|
|
26162
26221
|
const elicitationIdValue = Reflect.get(request, "elicitationId");
|
|
26163
|
-
const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ?
|
|
26222
|
+
const elicitationId = request.mode === "url" && typeof elicitationIdValue === "string" ? truncate3(elicitationIdValue, 255) : "";
|
|
26164
26223
|
const pending = new PendingElicitation(
|
|
26165
26224
|
interactionId,
|
|
26166
26225
|
elicitationId,
|
|
@@ -26179,10 +26238,10 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26179
26238
|
fields: normalizeElicitationFields(requestedSchema),
|
|
26180
26239
|
interactionId,
|
|
26181
26240
|
kind: SESSION_ELICITATION_REQUESTED_KIND,
|
|
26182
|
-
message:
|
|
26241
|
+
message: truncate3(request.message, 2e3),
|
|
26183
26242
|
mode: request.mode,
|
|
26184
26243
|
sessionId: this.#mobiusSessionId,
|
|
26185
|
-
url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ?
|
|
26244
|
+
url: request.mode === "url" && typeof Reflect.get(request, "url") === "string" ? truncate3(readString4(Reflect.get(request, "url")), 4096) : ""
|
|
26186
26245
|
});
|
|
26187
26246
|
return await pending.completion.promise;
|
|
26188
26247
|
} finally {
|
|
@@ -26271,7 +26330,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26271
26330
|
content: normalizeContentBlock(update.content),
|
|
26272
26331
|
contentId: `content-${crypto.randomUUID()}`,
|
|
26273
26332
|
kind: AGENT_CONTENT_KIND,
|
|
26274
|
-
messageId:
|
|
26333
|
+
messageId: truncate3(update.messageId ?? "", 255),
|
|
26275
26334
|
sessionId: this.#mobiusSessionId
|
|
26276
26335
|
});
|
|
26277
26336
|
}
|
|
@@ -26309,9 +26368,9 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26309
26368
|
}
|
|
26310
26369
|
if (update.sessionUpdate === "available_commands_update") {
|
|
26311
26370
|
const commands = update.availableCommands.slice(0, 500).map((command) => ({
|
|
26312
|
-
description:
|
|
26313
|
-
inputHint:
|
|
26314
|
-
name:
|
|
26371
|
+
description: truncate3(command.description, 500),
|
|
26372
|
+
inputHint: truncate3(command.input?.hint ?? "", 255),
|
|
26373
|
+
name: truncate3(command.name, 128)
|
|
26315
26374
|
})).filter((command) => command.name.length > 0);
|
|
26316
26375
|
this.#commands = commands;
|
|
26317
26376
|
await this.#getObserver().onCommands({
|
|
@@ -26322,10 +26381,11 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26322
26381
|
return;
|
|
26323
26382
|
}
|
|
26324
26383
|
if (update.sessionUpdate === "config_option_update") {
|
|
26325
|
-
this.#configOptions =
|
|
26384
|
+
this.#configOptions = this.#sessionConfigProtocol.normalizeUpdate(
|
|
26326
26385
|
this.#configOptions,
|
|
26327
26386
|
update.configOptions
|
|
26328
26387
|
);
|
|
26388
|
+
this.#configRevision += 1;
|
|
26329
26389
|
await this.emitConfigUpdate();
|
|
26330
26390
|
return;
|
|
26331
26391
|
}
|
|
@@ -26333,15 +26393,16 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26333
26393
|
this.#configOptions = this.#configOptions.map(
|
|
26334
26394
|
(option) => option.category === "mode" ? { ...option, currentValue: update.currentModeId } : option
|
|
26335
26395
|
);
|
|
26396
|
+
this.#configRevision += 1;
|
|
26336
26397
|
await this.emitConfigUpdate();
|
|
26337
26398
|
return;
|
|
26338
26399
|
}
|
|
26339
26400
|
if (update.sessionUpdate === "session_info_update") {
|
|
26340
26401
|
if (Object.hasOwn(update, "title")) {
|
|
26341
|
-
this.#sessionTitle =
|
|
26402
|
+
this.#sessionTitle = truncate3(update.title ?? "", 500);
|
|
26342
26403
|
}
|
|
26343
26404
|
if (Object.hasOwn(update, "updatedAt")) {
|
|
26344
|
-
this.#sessionUpdatedAt =
|
|
26405
|
+
this.#sessionUpdatedAt = truncate3(update.updatedAt ?? "", 128);
|
|
26345
26406
|
}
|
|
26346
26407
|
await this.#getObserver().onInfo({
|
|
26347
26408
|
kind: SESSION_INFO_UPDATED_KIND,
|
|
@@ -26354,7 +26415,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26354
26415
|
if (update.sessionUpdate === "usage_update") {
|
|
26355
26416
|
await this.#getObserver().onUsage({
|
|
26356
26417
|
costAmount: update.cost?.amount ?? 0,
|
|
26357
|
-
costCurrency:
|
|
26418
|
+
costCurrency: truncate3(update.cost?.currency ?? "", 16),
|
|
26358
26419
|
hasCost: update.cost !== void 0 && update.cost !== null,
|
|
26359
26420
|
kind: SESSION_USAGE_UPDATED_KIND,
|
|
26360
26421
|
sessionId: this.#mobiusSessionId,
|
|
@@ -26369,7 +26430,7 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
26369
26430
|
if (this.#capabilities.closeSession && this.#nativeSessionId.length > 0) {
|
|
26370
26431
|
try {
|
|
26371
26432
|
await this.#connection.agent.request(
|
|
26372
|
-
|
|
26433
|
+
methods6.agent.session.close,
|
|
26373
26434
|
{ sessionId: this.#nativeSessionId },
|
|
26374
26435
|
{
|
|
26375
26436
|
cancellationSignal: AbortSignal.timeout(
|
|
@@ -27001,13 +27062,12 @@ async function publishAgentCatalog(config2, signal) {
|
|
|
27001
27062
|
response = await fetch3(catalogEndpoint(config2.relayUrl), {
|
|
27002
27063
|
body: JSON.stringify({
|
|
27003
27064
|
agents: catalog.agents.map((agent) => ({
|
|
27065
|
+
agentPath: agent.agentIdentity.requestedPath,
|
|
27066
|
+
agentVersion: agent.agentVersion,
|
|
27004
27067
|
id: agent.id,
|
|
27005
27068
|
label: agent.label
|
|
27006
27069
|
})),
|
|
27007
|
-
installableAgents: catalog.installableAgents
|
|
27008
|
-
id: agent.id,
|
|
27009
|
-
label: agent.label
|
|
27010
|
-
}))
|
|
27070
|
+
installableAgents: catalog.installableAgents
|
|
27011
27071
|
}),
|
|
27012
27072
|
dispatcher: environmentProxyDispatcher,
|
|
27013
27073
|
headers: { "content-type": "application/json" },
|
|
@@ -27103,7 +27163,7 @@ var InstallationJob = class {
|
|
|
27103
27163
|
};
|
|
27104
27164
|
function authorizedSpecificationFor(specifications, agentId) {
|
|
27105
27165
|
for (const specification of specifications) {
|
|
27106
|
-
if (specification.id === agentId
|
|
27166
|
+
if (specification.id === agentId) {
|
|
27107
27167
|
return specification;
|
|
27108
27168
|
}
|
|
27109
27169
|
}
|
|
@@ -27115,7 +27175,7 @@ function executionFailure(error61) {
|
|
|
27115
27175
|
}
|
|
27116
27176
|
return new InstallationManagerError(
|
|
27117
27177
|
"installation_failed",
|
|
27118
|
-
"The local Agent installation failed",
|
|
27178
|
+
"The local Agent integration installation failed",
|
|
27119
27179
|
{ cause: error61 }
|
|
27120
27180
|
);
|
|
27121
27181
|
}
|
|
@@ -27186,7 +27246,7 @@ var AgentInstallationManager = class {
|
|
|
27186
27246
|
command.requestId,
|
|
27187
27247
|
command.agentId,
|
|
27188
27248
|
"installation_in_progress",
|
|
27189
|
-
"An installation for this Agent is already running"
|
|
27249
|
+
"An integration installation for this Agent is already running"
|
|
27190
27250
|
);
|
|
27191
27251
|
const job2 = new InstallationJob(command.requestId, command.agentId);
|
|
27192
27252
|
job2.state = busy;
|
|
@@ -27223,7 +27283,7 @@ var AgentInstallationManager = class {
|
|
|
27223
27283
|
job.requestId,
|
|
27224
27284
|
job.agentId
|
|
27225
27285
|
);
|
|
27226
|
-
job.controller.abort(new Error("Agent installation cancelled"));
|
|
27286
|
+
job.controller.abort(new Error("Agent integration installation cancelled"));
|
|
27227
27287
|
return await job.completion.promise;
|
|
27228
27288
|
};
|
|
27229
27289
|
close = async () => {
|
|
@@ -27233,7 +27293,7 @@ var AgentInstallationManager = class {
|
|
|
27233
27293
|
if (job === void 0) {
|
|
27234
27294
|
throw new InstallationManagerError(
|
|
27235
27295
|
"installation_state_invalid",
|
|
27236
|
-
"An active Agent installation is unavailable"
|
|
27296
|
+
"An active Agent integration installation is unavailable"
|
|
27237
27297
|
);
|
|
27238
27298
|
}
|
|
27239
27299
|
job.controller.abort(new Error("Mobius daemon stopped"));
|
|
@@ -27246,919 +27306,108 @@ var AgentInstallationManager = class {
|
|
|
27246
27306
|
await this.#observer.onState(state);
|
|
27247
27307
|
};
|
|
27248
27308
|
#run = async (job, specification, externalSignal) => {
|
|
27249
|
-
const abort = () => job.controller.abort(externalSignal.reason);
|
|
27250
|
-
externalSignal.addEventListener("abort", abort, { once: true });
|
|
27251
|
-
if (externalSignal.aborted) {
|
|
27252
|
-
abort();
|
|
27253
|
-
}
|
|
27254
|
-
const deadline = setTimeout(() => {
|
|
27255
|
-
job.controller.abort(
|
|
27256
|
-
new InstallationManagerError(
|
|
27257
|
-
"installation_timeout",
|
|
27258
|
-
"The local Agent installation exceeded its deadline"
|
|
27259
|
-
)
|
|
27260
|
-
);
|
|
27261
|
-
}, INSTALLATION_DEADLINE_MILLISECONDS);
|
|
27262
|
-
const signal = job.controller.signal;
|
|
27263
|
-
try {
|
|
27264
|
-
signal.throwIfAborted();
|
|
27265
|
-
this.#audit.record(
|
|
27266
|
-
"agent_installation_authorized",
|
|
27267
|
-
job.requestId,
|
|
27268
|
-
specification.id
|
|
27269
|
-
);
|
|
27270
|
-
await this.#executor.execute(
|
|
27271
|
-
specification.id,
|
|
27272
|
-
job.requestId,
|
|
27273
|
-
async (stage) => {
|
|
27274
|
-
signal.throwIfAborted();
|
|
27275
|
-
await this.#transition(
|
|
27276
|
-
job,
|
|
27277
|
-
new RunningInstallation(job.requestId, job.agentId, stage)
|
|
27278
|
-
);
|
|
27279
|
-
this.#audit.record(
|
|
27280
|
-
`agent_installation_${stage}`,
|
|
27281
|
-
job.requestId,
|
|
27282
|
-
job.agentId
|
|
27283
|
-
);
|
|
27284
|
-
},
|
|
27285
|
-
signal
|
|
27286
|
-
);
|
|
27287
|
-
signal.throwIfAborted();
|
|
27288
|
-
const succeeded = new SucceededInstallation(job.requestId, job.agentId);
|
|
27289
|
-
await this.#transition(job, succeeded);
|
|
27290
|
-
this.#audit.record(
|
|
27291
|
-
"agent_installation_completed",
|
|
27292
|
-
job.requestId,
|
|
27293
|
-
job.agentId
|
|
27294
|
-
);
|
|
27295
|
-
job.completion.resolve(succeeded);
|
|
27296
|
-
} catch (error61) {
|
|
27297
|
-
if (signal.aborted) {
|
|
27298
|
-
if (signal.reason instanceof InstallationManagerError && signal.reason.code === "installation_timeout") {
|
|
27299
|
-
const timedOut = new FailedInstallation(
|
|
27300
|
-
job.requestId,
|
|
27301
|
-
job.agentId,
|
|
27302
|
-
signal.reason.code,
|
|
27303
|
-
signal.reason.message
|
|
27304
|
-
);
|
|
27305
|
-
await this.#transition(job, timedOut);
|
|
27306
|
-
this.#audit.record(
|
|
27307
|
-
"agent_installation_failed_installation_timeout",
|
|
27308
|
-
job.requestId,
|
|
27309
|
-
job.agentId
|
|
27310
|
-
);
|
|
27311
|
-
job.completion.resolve(timedOut);
|
|
27312
|
-
return;
|
|
27313
|
-
}
|
|
27314
|
-
const cancelled = new CancelledInstallation(job.requestId, job.agentId);
|
|
27315
|
-
await this.#transition(job, cancelled);
|
|
27316
|
-
this.#audit.record(
|
|
27317
|
-
"agent_installation_cancelled",
|
|
27318
|
-
job.requestId,
|
|
27319
|
-
job.agentId
|
|
27320
|
-
);
|
|
27321
|
-
job.completion.resolve(cancelled);
|
|
27322
|
-
} else {
|
|
27323
|
-
const failure = executionFailure(error61);
|
|
27324
|
-
const failed = new FailedInstallation(
|
|
27325
|
-
job.requestId,
|
|
27326
|
-
job.agentId,
|
|
27327
|
-
failure.code,
|
|
27328
|
-
failure.message
|
|
27329
|
-
);
|
|
27330
|
-
await this.#transition(job, failed);
|
|
27331
|
-
this.#audit.record(
|
|
27332
|
-
`agent_installation_failed_${failure.code}`,
|
|
27333
|
-
job.requestId,
|
|
27334
|
-
job.agentId
|
|
27335
|
-
);
|
|
27336
|
-
job.completion.resolve(failed);
|
|
27337
|
-
}
|
|
27338
|
-
} finally {
|
|
27339
|
-
clearTimeout(deadline);
|
|
27340
|
-
externalSignal.removeEventListener("abort", abort);
|
|
27341
|
-
if (this.#activeAgents.get(job.agentId) === job.requestId) {
|
|
27342
|
-
this.#activeAgents.delete(job.agentId);
|
|
27343
|
-
}
|
|
27344
|
-
}
|
|
27345
|
-
};
|
|
27346
|
-
};
|
|
27347
|
-
|
|
27348
|
-
// src/agent-installation/automatic-adapter-provisioner.ts
|
|
27349
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
27350
|
-
var AUTOMATIC_ADAPTER_FAILURE_CODES = /* @__PURE__ */ new Set([
|
|
27351
|
-
"adapter_not_found",
|
|
27352
|
-
"adapter_probe_failed",
|
|
27353
|
-
"adapter_probe_timeout",
|
|
27354
|
-
"acp_incompatible"
|
|
27355
|
-
]);
|
|
27356
|
-
var InstalledAutomaticAdapter = class {
|
|
27357
|
-
executable;
|
|
27358
|
-
requestId;
|
|
27359
|
-
specification;
|
|
27360
|
-
constructor(specification, requestId, executable) {
|
|
27361
|
-
this.executable = executable;
|
|
27362
|
-
this.requestId = requestId;
|
|
27363
|
-
this.specification = specification;
|
|
27364
|
-
}
|
|
27365
|
-
};
|
|
27366
|
-
function shouldProvisionAdapter(unavailable, options) {
|
|
27367
|
-
return unavailable.specification instanceof BridgedAcpAgentDefinition && AUTOMATIC_ADAPTER_FAILURE_CODES.has(unavailable.code) && options.environment[unavailable.specification.adapterOverrideVariable] === void 0 && unavailable.specification.supportsInstallation(
|
|
27368
|
-
options.platform ?? process.platform,
|
|
27369
|
-
options.architecture ?? process.arch
|
|
27370
|
-
);
|
|
27371
|
-
}
|
|
27372
|
-
function stableFailureCode(error61) {
|
|
27373
|
-
return error61 instanceof ManagedAdapterInstallError ? error61.code : "adapter_install_failed";
|
|
27374
|
-
}
|
|
27375
|
-
function discoveryOptions(options, environment, signal, specifications) {
|
|
27376
|
-
return {
|
|
27377
|
-
...options.architecture === void 0 ? {} : { architecture: options.architecture },
|
|
27378
|
-
defaultWorkspace: options.defaultWorkspace,
|
|
27379
|
-
environment,
|
|
27380
|
-
...options.platform === void 0 ? {} : { platform: options.platform },
|
|
27381
|
-
signal,
|
|
27382
|
-
specifications
|
|
27383
|
-
};
|
|
27384
|
-
}
|
|
27385
|
-
var AutomaticAdapterProvisioner = class {
|
|
27386
|
-
#adapterInstaller;
|
|
27387
|
-
#options;
|
|
27388
|
-
#specifications;
|
|
27389
|
-
constructor(options, adapterInstaller, specifications = supportedLocalAgentSpecifications()) {
|
|
27390
|
-
this.#adapterInstaller = adapterInstaller;
|
|
27391
|
-
this.#options = options;
|
|
27392
|
-
this.#specifications = Object.freeze([...specifications]);
|
|
27393
|
-
}
|
|
27394
|
-
prepare = async (signal) => {
|
|
27395
|
-
signal.throwIfAborted();
|
|
27396
|
-
let inventory = await discoverLocalAgentInventory(
|
|
27397
|
-
discoveryOptions(
|
|
27398
|
-
this.#options,
|
|
27399
|
-
this.#options.environment,
|
|
27400
|
-
signal,
|
|
27401
|
-
this.#specifications
|
|
27402
|
-
)
|
|
27403
|
-
);
|
|
27404
|
-
const candidates = inventory.unavailable.filter(
|
|
27405
|
-
(unavailable) => shouldProvisionAdapter(unavailable, this.#options)
|
|
27406
|
-
);
|
|
27407
|
-
const attempts = [];
|
|
27408
|
-
for (const unavailable of candidates) {
|
|
27409
|
-
signal.throwIfAborted();
|
|
27410
|
-
const specification = unavailable.specification;
|
|
27411
|
-
if (!(specification instanceof BridgedAcpAgentDefinition)) {
|
|
27412
|
-
attempts.push(null);
|
|
27413
|
-
continue;
|
|
27414
|
-
}
|
|
27415
|
-
const verifiedAgent = await findVerifiedAgentExecutable(
|
|
27416
|
-
specification,
|
|
27417
|
-
discoveryOptions(
|
|
27418
|
-
this.#options,
|
|
27419
|
-
this.#options.environment,
|
|
27420
|
-
signal,
|
|
27421
|
-
this.#specifications
|
|
27422
|
-
)
|
|
27423
|
-
);
|
|
27424
|
-
if (verifiedAgent === null) {
|
|
27425
|
-
attempts.push(null);
|
|
27426
|
-
continue;
|
|
27427
|
-
}
|
|
27428
|
-
const requestId = `automatic-adapter-${randomUUID2()}`;
|
|
27429
|
-
this.#options.audit.record(
|
|
27430
|
-
"agent_adapter_auto_install_started",
|
|
27431
|
-
requestId,
|
|
27432
|
-
specification.id,
|
|
27433
|
-
{
|
|
27434
|
-
agentVersion: verifiedAgent.version,
|
|
27435
|
-
adapterVersion: specification.adapterVersion
|
|
27436
|
-
}
|
|
27437
|
-
);
|
|
27438
|
-
process.stdout.write(
|
|
27439
|
-
`Installing the pinned ACP adapter for ${specification.label}.
|
|
27440
|
-
`
|
|
27441
|
-
);
|
|
27442
|
-
try {
|
|
27443
|
-
const executable = await this.#adapterInstaller.install(
|
|
27444
|
-
specification,
|
|
27445
|
-
signal
|
|
27446
|
-
);
|
|
27447
|
-
this.#options.audit.record(
|
|
27448
|
-
"agent_adapter_auto_install_completed",
|
|
27449
|
-
requestId,
|
|
27450
|
-
specification.id,
|
|
27451
|
-
{ adapterVersion: specification.adapterVersion }
|
|
27452
|
-
);
|
|
27453
|
-
attempts.push(
|
|
27454
|
-
new InstalledAutomaticAdapter(specification, requestId, executable)
|
|
27455
|
-
);
|
|
27456
|
-
} catch (error61) {
|
|
27457
|
-
if (signal.aborted) {
|
|
27458
|
-
this.#options.audit.record(
|
|
27459
|
-
"agent_adapter_auto_install_cancelled",
|
|
27460
|
-
requestId,
|
|
27461
|
-
specification.id
|
|
27462
|
-
);
|
|
27463
|
-
signal.throwIfAborted();
|
|
27464
|
-
}
|
|
27465
|
-
this.#options.audit.record(
|
|
27466
|
-
"agent_adapter_auto_install_failed",
|
|
27467
|
-
requestId,
|
|
27468
|
-
specification.id,
|
|
27469
|
-
{ code: stableFailureCode(error61) }
|
|
27470
|
-
);
|
|
27471
|
-
process.stderr.write(
|
|
27472
|
-
`The pinned ACP adapter for ${specification.label} could not be installed automatically; the daemon will continue.
|
|
27473
|
-
`
|
|
27474
|
-
);
|
|
27475
|
-
attempts.push(null);
|
|
27476
|
-
}
|
|
27477
|
-
}
|
|
27478
|
-
signal.throwIfAborted();
|
|
27479
|
-
const installed = attempts.filter(
|
|
27480
|
-
(attempt) => attempt !== null
|
|
27481
|
-
);
|
|
27482
|
-
if (installed.length > 0) {
|
|
27483
|
-
const verificationEnvironment = {
|
|
27484
|
-
...this.#options.environment
|
|
27485
|
-
};
|
|
27486
|
-
for (const attempt of installed) {
|
|
27487
|
-
verificationEnvironment[attempt.specification.adapterOverrideVariable] = attempt.executable.path;
|
|
27488
|
-
}
|
|
27489
|
-
inventory = await discoverLocalAgentInventory(
|
|
27490
|
-
discoveryOptions(
|
|
27491
|
-
this.#options,
|
|
27492
|
-
verificationEnvironment,
|
|
27493
|
-
signal,
|
|
27494
|
-
this.#specifications
|
|
27495
|
-
)
|
|
27496
|
-
);
|
|
27497
|
-
}
|
|
27498
|
-
this.#options.catalog.transition(
|
|
27499
|
-
inventory.readyAgents(),
|
|
27500
|
-
inventory.installable
|
|
27501
|
-
);
|
|
27502
|
-
for (const attempt of installed) {
|
|
27503
|
-
const available = inventory.available.find(
|
|
27504
|
-
(candidate) => candidate instanceof AvailableAgent && candidate.specification.id === attempt.specification.id
|
|
27505
|
-
);
|
|
27506
|
-
if (available === void 0) {
|
|
27507
|
-
const unavailable = inventory.unavailable.find(
|
|
27508
|
-
(candidate) => candidate.specification.id === attempt.specification.id
|
|
27509
|
-
);
|
|
27510
|
-
this.#options.audit.record(
|
|
27511
|
-
"agent_adapter_auto_install_verification_failed",
|
|
27512
|
-
attempt.requestId,
|
|
27513
|
-
attempt.specification.id,
|
|
27514
|
-
{ code: unavailable?.code ?? "agent_verification_failed" }
|
|
27515
|
-
);
|
|
27516
|
-
continue;
|
|
27517
|
-
}
|
|
27518
|
-
this.#options.audit.record(
|
|
27519
|
-
"agent_adapter_auto_install_verified",
|
|
27520
|
-
attempt.requestId,
|
|
27521
|
-
attempt.specification.id,
|
|
27522
|
-
{
|
|
27523
|
-
adapterVersion: available.agent.adapterVersion,
|
|
27524
|
-
agentVersion: available.agent.agentVersion
|
|
27525
|
-
}
|
|
27526
|
-
);
|
|
27527
|
-
process.stdout.write(
|
|
27528
|
-
`${attempt.specification.label} ACP integration is ready.
|
|
27529
|
-
`
|
|
27530
|
-
);
|
|
27531
|
-
}
|
|
27532
|
-
return inventory;
|
|
27533
|
-
};
|
|
27534
|
-
};
|
|
27535
|
-
|
|
27536
|
-
// src/agent-installation/fixed-installation-executor.ts
|
|
27537
|
-
import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
27538
|
-
import { resolve as resolve4 } from "node:path";
|
|
27539
|
-
|
|
27540
|
-
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
27541
|
-
import { mkdir as mkdir5, mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
|
|
27542
|
-
import { join as join17 } from "node:path";
|
|
27543
|
-
|
|
27544
|
-
// src/agent-installation/fixed-agent-install-recipe.ts
|
|
27545
|
-
var FixedAgentInstallRecipe = class {
|
|
27546
|
-
assertSupportedPlatform = () => {
|
|
27547
|
-
if (process.platform !== "darwin" && process.platform !== "linux" || process.arch !== "arm64" && process.arch !== "x64") {
|
|
27548
|
-
throw new InstallationManagerError(
|
|
27549
|
-
"unsupported_install_platform",
|
|
27550
|
-
"This Agent installation recipe does not support the local platform"
|
|
27551
|
-
);
|
|
27552
|
-
}
|
|
27553
|
-
};
|
|
27554
|
-
requireInstalledExecutable = async (path2) => {
|
|
27555
|
-
const executable = await resolveExecutablePath(path2);
|
|
27556
|
-
if (executable === null) {
|
|
27557
|
-
throw new InstallationManagerError(
|
|
27558
|
-
"agent_verification_failed",
|
|
27559
|
-
"The Agent installer did not produce a valid executable"
|
|
27560
|
-
);
|
|
27561
|
-
}
|
|
27562
|
-
return executable;
|
|
27563
|
-
};
|
|
27564
|
-
};
|
|
27565
|
-
|
|
27566
|
-
// src/agent-installation/grok-build-install-recipe.ts
|
|
27567
|
-
import { mkdir as mkdir4, realpath as realpath7, stat as stat6 } from "node:fs/promises";
|
|
27568
|
-
import { delimiter as delimiter2, dirname as dirname5, isAbsolute as isAbsolute7, join as join15, relative as relative4, sep as sep4 } from "node:path";
|
|
27569
|
-
var INSTALL_TIMEOUT_MILLISECONDS2 = 5 * 60 * 1e3;
|
|
27570
|
-
function isContainedPath4(root, candidate) {
|
|
27571
|
-
const difference = relative4(root, candidate);
|
|
27572
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute7(difference);
|
|
27573
|
-
}
|
|
27574
|
-
async function resolveLifecycleScript(packageRoot) {
|
|
27575
|
-
try {
|
|
27576
|
-
const canonicalPackageRoot = await realpath7(packageRoot);
|
|
27577
|
-
const script = await realpath7(
|
|
27578
|
-
join15(canonicalPackageRoot, "bin", "postinstall.js")
|
|
27579
|
-
);
|
|
27580
|
-
const metadata = await stat6(script);
|
|
27581
|
-
if (!metadata.isFile() || !isContainedPath4(canonicalPackageRoot, script)) {
|
|
27582
|
-
throw new Error("Invalid Grok Build lifecycle script");
|
|
27583
|
-
}
|
|
27584
|
-
return script;
|
|
27585
|
-
} catch (error61) {
|
|
27586
|
-
throw new InstallationManagerError(
|
|
27587
|
-
"agent_verification_failed",
|
|
27588
|
-
"The managed Grok Build lifecycle script is invalid",
|
|
27589
|
-
{ cause: error61 }
|
|
27590
|
-
);
|
|
27591
|
-
}
|
|
27592
|
-
}
|
|
27593
|
-
var GrokBuildInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27594
|
-
#npmInstaller;
|
|
27595
|
-
id = "grok-build";
|
|
27596
|
-
label = "Grok Build";
|
|
27597
|
-
releaseChannel = GROK_BUILD_MANAGED_VERSION;
|
|
27598
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27599
|
-
super();
|
|
27600
|
-
this.#npmInstaller = npmInstaller;
|
|
27601
|
-
}
|
|
27602
|
-
install = async (options) => {
|
|
27603
|
-
this.assertSupportedPlatform();
|
|
27604
|
-
const definition = grokBuildManagedPackage(process.platform, process.arch);
|
|
27605
|
-
const versionRoot = join15(
|
|
27606
|
-
options.stateDirectory,
|
|
27607
|
-
"agents",
|
|
27608
|
-
this.id,
|
|
27609
|
-
GROK_BUILD_MANAGED_VERSION
|
|
27610
|
-
);
|
|
27611
|
-
const packageRoot = join15(versionRoot, "package");
|
|
27612
|
-
const managedHome = join15(versionRoot, "home");
|
|
27613
|
-
try {
|
|
27614
|
-
await mkdir4(managedHome, { mode: 448, recursive: true });
|
|
27615
|
-
const canonicalHome = await realpath7(managedHome);
|
|
27616
|
-
await options.report("downloading");
|
|
27617
|
-
await options.report("verifying");
|
|
27618
|
-
await options.report("installing_agent");
|
|
27619
|
-
await this.#npmInstaller.install(
|
|
27620
|
-
packageRoot,
|
|
27621
|
-
definition,
|
|
27622
|
-
options.environment,
|
|
27623
|
-
options.signal
|
|
27624
|
-
);
|
|
27625
|
-
options.audit.record(
|
|
27626
|
-
"agent_npm_package_verified",
|
|
27627
|
-
options.requestId,
|
|
27628
|
-
this.id,
|
|
27629
|
-
{
|
|
27630
|
-
integrity: definition.integrity,
|
|
27631
|
-
package: definition.packageName,
|
|
27632
|
-
version: definition.version
|
|
27633
|
-
}
|
|
27634
|
-
);
|
|
27635
|
-
const script = await resolveLifecycleScript(
|
|
27636
|
-
join15(packageRoot, "node_modules", "@xai-official", "grok")
|
|
27637
|
-
);
|
|
27638
|
-
await runBoundedProcess({
|
|
27639
|
-
arguments: [script],
|
|
27640
|
-
command: process.execPath,
|
|
27641
|
-
cwd: dirname5(script),
|
|
27642
|
-
environment: {
|
|
27643
|
-
GROK_HOME: canonicalHome,
|
|
27644
|
-
GROK_INSTALL_COMPLETIONS: "0",
|
|
27645
|
-
GROK_NPM_REGISTRY: "https://registry.npmjs.org/",
|
|
27646
|
-
HOME: canonicalHome,
|
|
27647
|
-
PATH: `${dirname5(process.execPath)}${delimiter2}/usr/bin${delimiter2}/bin`
|
|
27648
|
-
},
|
|
27649
|
-
outputLimitBytes: 64 * 1024,
|
|
27650
|
-
signal: options.signal,
|
|
27651
|
-
timeoutMilliseconds: INSTALL_TIMEOUT_MILLISECONDS2
|
|
27652
|
-
});
|
|
27653
|
-
options.audit.record(
|
|
27654
|
-
"agent_lifecycle_step_completed",
|
|
27655
|
-
options.requestId,
|
|
27656
|
-
this.id,
|
|
27657
|
-
{
|
|
27658
|
-
lifecycle: "postinstall",
|
|
27659
|
-
package: definition.packageName,
|
|
27660
|
-
version: definition.version
|
|
27661
|
-
}
|
|
27662
|
-
);
|
|
27663
|
-
return await this.requireInstalledExecutable(
|
|
27664
|
-
join15(canonicalHome, "bin", "grok")
|
|
27665
|
-
);
|
|
27666
|
-
} catch (error61) {
|
|
27667
|
-
if (options.signal.aborted) {
|
|
27668
|
-
options.signal.throwIfAborted();
|
|
27669
|
-
}
|
|
27670
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
27671
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
27672
|
-
throw new InstallationManagerError(
|
|
27673
|
-
"agent_verification_failed",
|
|
27674
|
-
"The managed Grok Build packages did not match their pinned artifacts",
|
|
27675
|
-
{ cause: error61 }
|
|
27676
|
-
);
|
|
27677
|
-
}
|
|
27678
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
27679
|
-
throw new InstallationManagerError(
|
|
27680
|
-
"agent_publish_failed",
|
|
27681
|
-
"The managed Grok Build package could not be published",
|
|
27682
|
-
{ cause: error61 }
|
|
27683
|
-
);
|
|
27684
|
-
}
|
|
27685
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
27686
|
-
cause: error61
|
|
27687
|
-
});
|
|
27688
|
-
}
|
|
27689
|
-
if (error61 instanceof InstallationManagerError) {
|
|
27690
|
-
throw error61;
|
|
27691
|
-
}
|
|
27692
|
-
throw new InstallationManagerError(
|
|
27693
|
-
"agent_install_failed",
|
|
27694
|
-
"The fixed Grok Build installation recipe failed",
|
|
27695
|
-
{ cause: error61 }
|
|
27696
|
-
);
|
|
27697
|
-
}
|
|
27698
|
-
};
|
|
27699
|
-
};
|
|
27700
|
-
|
|
27701
|
-
// src/agent-installation/workbuddy-install-recipe.ts
|
|
27702
|
-
import { join as join16 } from "node:path";
|
|
27703
|
-
var WorkBuddyInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27704
|
-
#npmInstaller;
|
|
27705
|
-
id = "workbuddy";
|
|
27706
|
-
label = "WorkBuddy";
|
|
27707
|
-
releaseChannel = WORKBUDDY_MANAGED_VERSION;
|
|
27708
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27709
|
-
super();
|
|
27710
|
-
this.#npmInstaller = npmInstaller;
|
|
27711
|
-
}
|
|
27712
|
-
install = async (options) => {
|
|
27713
|
-
this.assertSupportedPlatform();
|
|
27714
|
-
try {
|
|
27715
|
-
await options.report("downloading");
|
|
27716
|
-
await options.report("verifying");
|
|
27717
|
-
await options.report("installing_agent");
|
|
27718
|
-
const executable = await this.#npmInstaller.install(
|
|
27719
|
-
join16(
|
|
27720
|
-
options.stateDirectory,
|
|
27721
|
-
"agents",
|
|
27722
|
-
this.id,
|
|
27723
|
-
WORKBUDDY_MANAGED_VERSION
|
|
27724
|
-
),
|
|
27725
|
-
WORKBUDDY_MANAGED_PACKAGE,
|
|
27726
|
-
options.environment,
|
|
27727
|
-
options.signal
|
|
27728
|
-
);
|
|
27729
|
-
options.audit.record(
|
|
27730
|
-
"agent_npm_package_verified",
|
|
27731
|
-
options.requestId,
|
|
27732
|
-
this.id,
|
|
27733
|
-
{
|
|
27734
|
-
integrity: WORKBUDDY_MANAGED_PACKAGE.integrity,
|
|
27735
|
-
package: WORKBUDDY_MANAGED_PACKAGE.packageName,
|
|
27736
|
-
version: WORKBUDDY_MANAGED_PACKAGE.version
|
|
27737
|
-
}
|
|
27738
|
-
);
|
|
27739
|
-
return executable;
|
|
27740
|
-
} catch (error61) {
|
|
27741
|
-
if (options.signal.aborted) {
|
|
27742
|
-
options.signal.throwIfAborted();
|
|
27743
|
-
}
|
|
27744
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
27745
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
27746
|
-
throw new InstallationManagerError(
|
|
27747
|
-
"agent_verification_failed",
|
|
27748
|
-
"The managed WorkBuddy package did not match its pinned artifact",
|
|
27749
|
-
{ cause: error61 }
|
|
27750
|
-
);
|
|
27751
|
-
}
|
|
27752
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
27753
|
-
throw new InstallationManagerError(
|
|
27754
|
-
"agent_publish_failed",
|
|
27755
|
-
"The managed WorkBuddy package could not be published",
|
|
27756
|
-
{ cause: error61 }
|
|
27757
|
-
);
|
|
27758
|
-
}
|
|
27759
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
27760
|
-
cause: error61
|
|
27761
|
-
});
|
|
27762
|
-
}
|
|
27763
|
-
if (error61 instanceof InstallationManagerError) {
|
|
27764
|
-
throw error61;
|
|
27765
|
-
}
|
|
27766
|
-
throw new InstallationManagerError(
|
|
27767
|
-
"agent_install_failed",
|
|
27768
|
-
"The fixed WorkBuddy installation recipe failed",
|
|
27769
|
-
{ cause: error61 }
|
|
27770
|
-
);
|
|
27771
|
-
}
|
|
27772
|
-
};
|
|
27773
|
-
};
|
|
27774
|
-
|
|
27775
|
-
// src/agent-installation/fixed-agent-install-recipes.ts
|
|
27776
|
-
var INSTALLER_DOWNLOAD_LIMIT_BYTES = 1024 * 1024;
|
|
27777
|
-
var INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS = 6e4;
|
|
27778
|
-
var AGENT_INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
27779
|
-
var MINIMAL_PATH2 = "/usr/bin:/bin";
|
|
27780
|
-
var CodexInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27781
|
-
id = "codex";
|
|
27782
|
-
label = "Codex";
|
|
27783
|
-
releaseChannel = "latest";
|
|
27784
|
-
install = async (options) => {
|
|
27785
|
-
this.assertSupportedPlatform();
|
|
27786
|
-
const root = join17(options.stateDirectory, "agents", this.id);
|
|
27787
|
-
const temporaryRoot = join17(options.stateDirectory, "temporary");
|
|
27788
|
-
await Promise.all([
|
|
27789
|
-
mkdir5(root, { mode: 448, recursive: true }),
|
|
27790
|
-
mkdir5(temporaryRoot, { mode: 448, recursive: true })
|
|
27791
|
-
]);
|
|
27792
|
-
const temporaryDirectory = await mkdtemp3(
|
|
27793
|
-
join17(temporaryRoot, ".codex-install-")
|
|
27794
|
-
);
|
|
27795
|
-
const installerPath = join17(temporaryDirectory, "install.sh");
|
|
27796
|
-
const installDirectory = join17(root, "bin");
|
|
27797
|
-
const codexHome = join17(root, "home");
|
|
27798
|
-
try {
|
|
27799
|
-
await Promise.all([
|
|
27800
|
-
mkdir5(installDirectory, { mode: 448, recursive: true }),
|
|
27801
|
-
mkdir5(codexHome, { mode: 448, recursive: true })
|
|
27802
|
-
]);
|
|
27803
|
-
await options.report("downloading");
|
|
27804
|
-
const download = await downloadVerifiedFile({
|
|
27805
|
-
allowedHosts: /* @__PURE__ */ new Set(["chatgpt.com", "releases.openai.com"]),
|
|
27806
|
-
destination: installerPath,
|
|
27807
|
-
maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
|
|
27808
|
-
signal: options.signal,
|
|
27809
|
-
timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
|
|
27810
|
-
url: new URL("https://chatgpt.com/codex/install.sh")
|
|
27811
|
-
});
|
|
27812
|
-
options.audit.record(
|
|
27813
|
-
"agent_installer_download_verified",
|
|
27814
|
-
options.requestId,
|
|
27815
|
-
this.id,
|
|
27816
|
-
{
|
|
27817
|
-
bytes: download.bytes.toString(),
|
|
27818
|
-
releaseChannel: this.releaseChannel,
|
|
27819
|
-
sha256: download.sha256
|
|
27820
|
-
}
|
|
27821
|
-
);
|
|
27822
|
-
await options.report("verifying");
|
|
27823
|
-
await options.report("installing_agent");
|
|
27824
|
-
await runBoundedProcess({
|
|
27825
|
-
arguments: [installerPath],
|
|
27826
|
-
command: "/bin/sh",
|
|
27827
|
-
cwd: temporaryDirectory,
|
|
27828
|
-
environment: {
|
|
27829
|
-
CODEX_HOME: codexHome,
|
|
27830
|
-
CODEX_INSTALL_DIR: installDirectory,
|
|
27831
|
-
CODEX_NON_INTERACTIVE: "1",
|
|
27832
|
-
CODEX_RELEASE: this.releaseChannel,
|
|
27833
|
-
HOME: codexHome,
|
|
27834
|
-
PATH: MINIMAL_PATH2
|
|
27835
|
-
},
|
|
27836
|
-
outputLimitBytes: 64 * 1024,
|
|
27837
|
-
signal: options.signal,
|
|
27838
|
-
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
27839
|
-
});
|
|
27840
|
-
return await this.requireInstalledExecutable(
|
|
27841
|
-
join17(installDirectory, "codex")
|
|
27842
|
-
);
|
|
27843
|
-
} catch (error61) {
|
|
27844
|
-
if (options.signal.aborted) {
|
|
27845
|
-
options.signal.throwIfAborted();
|
|
27846
|
-
}
|
|
27847
|
-
if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
|
|
27848
|
-
throw error61;
|
|
27849
|
-
}
|
|
27850
|
-
throw new InstallationManagerError(
|
|
27851
|
-
"agent_install_failed",
|
|
27852
|
-
"The fixed Codex installation recipe failed"
|
|
27853
|
-
);
|
|
27854
|
-
} finally {
|
|
27855
|
-
await rm3(temporaryDirectory, { force: true, recursive: true });
|
|
27856
|
-
}
|
|
27857
|
-
};
|
|
27858
|
-
};
|
|
27859
|
-
var ClaudeCodeInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27860
|
-
id = "claude";
|
|
27861
|
-
label = "Claude Code";
|
|
27862
|
-
releaseChannel = "stable";
|
|
27863
|
-
install = async (options) => {
|
|
27864
|
-
this.assertSupportedPlatform();
|
|
27865
|
-
const root = join17(options.stateDirectory, "agents", this.id);
|
|
27866
|
-
const managedHome = join17(root, "home");
|
|
27867
|
-
const temporaryRoot = join17(options.stateDirectory, "temporary");
|
|
27868
|
-
await Promise.all([
|
|
27869
|
-
mkdir5(managedHome, { mode: 448, recursive: true }),
|
|
27870
|
-
mkdir5(temporaryRoot, { mode: 448, recursive: true })
|
|
27871
|
-
]);
|
|
27872
|
-
const temporaryDirectory = await mkdtemp3(
|
|
27873
|
-
join17(temporaryRoot, ".claude-install-")
|
|
27874
|
-
);
|
|
27875
|
-
const installerPath = join17(temporaryDirectory, "install.sh");
|
|
27876
|
-
try {
|
|
27877
|
-
await options.report("downloading");
|
|
27878
|
-
const download = await downloadVerifiedFile({
|
|
27879
|
-
allowedHosts: /* @__PURE__ */ new Set(["claude.ai"]),
|
|
27880
|
-
destination: installerPath,
|
|
27881
|
-
maximumBytes: INSTALLER_DOWNLOAD_LIMIT_BYTES,
|
|
27882
|
-
signal: options.signal,
|
|
27883
|
-
timeoutMilliseconds: INSTALLER_DOWNLOAD_TIMEOUT_MILLISECONDS,
|
|
27884
|
-
url: new URL("https://claude.ai/install.sh")
|
|
27885
|
-
});
|
|
27886
|
-
options.audit.record(
|
|
27887
|
-
"agent_installer_download_verified",
|
|
27888
|
-
options.requestId,
|
|
27889
|
-
this.id,
|
|
27890
|
-
{
|
|
27891
|
-
bytes: download.bytes.toString(),
|
|
27892
|
-
releaseChannel: this.releaseChannel,
|
|
27893
|
-
sha256: download.sha256
|
|
27894
|
-
}
|
|
27895
|
-
);
|
|
27896
|
-
await options.report("verifying");
|
|
27897
|
-
await options.report("installing_agent");
|
|
27898
|
-
await runBoundedProcess({
|
|
27899
|
-
arguments: [installerPath, "stable"],
|
|
27900
|
-
command: "/bin/bash",
|
|
27901
|
-
cwd: temporaryDirectory,
|
|
27902
|
-
environment: {
|
|
27903
|
-
HOME: managedHome,
|
|
27904
|
-
PATH: MINIMAL_PATH2,
|
|
27905
|
-
SHELL: "/bin/bash"
|
|
27906
|
-
},
|
|
27907
|
-
outputLimitBytes: 64 * 1024,
|
|
27908
|
-
signal: options.signal,
|
|
27909
|
-
timeoutMilliseconds: AGENT_INSTALL_TIMEOUT_MILLISECONDS
|
|
27910
|
-
});
|
|
27911
|
-
return await this.requireInstalledExecutable(
|
|
27912
|
-
join17(managedHome, ".local", "bin", "claude")
|
|
27913
|
-
);
|
|
27914
|
-
} catch (error61) {
|
|
27915
|
-
if (options.signal.aborted) {
|
|
27916
|
-
options.signal.throwIfAborted();
|
|
27917
|
-
}
|
|
27918
|
-
if (error61 instanceof InstallationManagerError || error61 instanceof Error && "code" in error61) {
|
|
27919
|
-
throw error61;
|
|
27920
|
-
}
|
|
27921
|
-
throw new InstallationManagerError(
|
|
27922
|
-
"agent_install_failed",
|
|
27923
|
-
"The fixed Claude Code installation recipe failed"
|
|
27924
|
-
);
|
|
27925
|
-
} finally {
|
|
27926
|
-
await rm3(temporaryDirectory, { force: true, recursive: true });
|
|
27927
|
-
}
|
|
27928
|
-
};
|
|
27929
|
-
};
|
|
27930
|
-
var PiInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
27931
|
-
#npmInstaller;
|
|
27932
|
-
id = "pi";
|
|
27933
|
-
label = "Pi";
|
|
27934
|
-
releaseChannel = PI_AGENT_PACKAGE.version;
|
|
27935
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
27936
|
-
super();
|
|
27937
|
-
this.#npmInstaller = npmInstaller;
|
|
27938
|
-
}
|
|
27939
|
-
install = async (options) => {
|
|
27940
|
-
this.assertSupportedPlatform();
|
|
27941
|
-
try {
|
|
27942
|
-
await options.report("downloading");
|
|
27943
|
-
await options.report("verifying");
|
|
27944
|
-
await options.report("installing_agent");
|
|
27945
|
-
const executable = await this.#npmInstaller.install(
|
|
27946
|
-
join17(
|
|
27947
|
-
options.stateDirectory,
|
|
27948
|
-
"agents",
|
|
27949
|
-
this.id,
|
|
27950
|
-
PI_AGENT_PACKAGE.version
|
|
27951
|
-
),
|
|
27952
|
-
PI_AGENT_PACKAGE,
|
|
27953
|
-
options.environment,
|
|
27954
|
-
options.signal
|
|
27955
|
-
);
|
|
27956
|
-
options.audit.record(
|
|
27957
|
-
"agent_npm_package_verified",
|
|
27958
|
-
options.requestId,
|
|
27959
|
-
this.id,
|
|
27960
|
-
{
|
|
27961
|
-
integrity: PI_AGENT_PACKAGE.integrity,
|
|
27962
|
-
package: PI_AGENT_PACKAGE.packageName,
|
|
27963
|
-
version: PI_AGENT_PACKAGE.version
|
|
27964
|
-
}
|
|
27965
|
-
);
|
|
27966
|
-
return executable;
|
|
27967
|
-
} catch (error61) {
|
|
27968
|
-
if (options.signal.aborted) {
|
|
27969
|
-
options.signal.throwIfAborted();
|
|
27970
|
-
}
|
|
27971
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
27972
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
27973
|
-
throw new InstallationManagerError(
|
|
27974
|
-
"agent_verification_failed",
|
|
27975
|
-
"The managed Pi package did not match its pinned artifact",
|
|
27976
|
-
{ cause: error61 }
|
|
27977
|
-
);
|
|
27978
|
-
}
|
|
27979
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
27980
|
-
throw new InstallationManagerError(
|
|
27981
|
-
"agent_publish_failed",
|
|
27982
|
-
"The managed Pi package could not be published",
|
|
27983
|
-
{ cause: error61 }
|
|
27984
|
-
);
|
|
27985
|
-
}
|
|
27986
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
27987
|
-
cause: error61
|
|
27988
|
-
});
|
|
27989
|
-
}
|
|
27990
|
-
if (error61 instanceof InstallationManagerError) {
|
|
27991
|
-
throw error61;
|
|
27992
|
-
}
|
|
27993
|
-
throw new InstallationManagerError(
|
|
27994
|
-
"agent_install_failed",
|
|
27995
|
-
"The fixed Pi installation recipe failed",
|
|
27996
|
-
{ cause: error61 }
|
|
27997
|
-
);
|
|
27998
|
-
}
|
|
27999
|
-
};
|
|
28000
|
-
};
|
|
28001
|
-
var DeepSeekHarnessInstallRecipe = class extends FixedAgentInstallRecipe {
|
|
28002
|
-
#npmInstaller;
|
|
28003
|
-
id = "deepseek-harness";
|
|
28004
|
-
label = "DeepSeek Harness";
|
|
28005
|
-
releaseChannel = DEEPSEEK_HARNESS_PACKAGE.version;
|
|
28006
|
-
constructor(npmInstaller = new ManagedNpmPackageInstaller()) {
|
|
28007
|
-
super();
|
|
28008
|
-
this.#npmInstaller = npmInstaller;
|
|
28009
|
-
}
|
|
28010
|
-
install = async (options) => {
|
|
28011
|
-
this.assertSupportedPlatform();
|
|
28012
|
-
try {
|
|
28013
|
-
const managedHome = join17(
|
|
28014
|
-
options.stateDirectory,
|
|
28015
|
-
"agents",
|
|
28016
|
-
this.id,
|
|
28017
|
-
"home"
|
|
28018
|
-
);
|
|
28019
|
-
await mkdir5(managedHome, { mode: 448, recursive: true });
|
|
28020
|
-
await options.report("downloading");
|
|
28021
|
-
await options.report("verifying");
|
|
28022
|
-
await options.report("installing_agent");
|
|
28023
|
-
const executable = await this.#npmInstaller.install(
|
|
28024
|
-
join17(
|
|
28025
|
-
options.stateDirectory,
|
|
28026
|
-
"agents",
|
|
28027
|
-
this.id,
|
|
28028
|
-
DEEPSEEK_HARNESS_PACKAGE.version
|
|
28029
|
-
),
|
|
28030
|
-
DEEPSEEK_HARNESS_PACKAGE,
|
|
28031
|
-
options.environment,
|
|
28032
|
-
options.signal
|
|
28033
|
-
);
|
|
28034
|
-
options.audit.record(
|
|
28035
|
-
"agent_npm_package_verified",
|
|
28036
|
-
options.requestId,
|
|
28037
|
-
this.id,
|
|
28038
|
-
{
|
|
28039
|
-
integrity: DEEPSEEK_HARNESS_PACKAGE.integrity,
|
|
28040
|
-
package: DEEPSEEK_HARNESS_PACKAGE.packageName,
|
|
28041
|
-
version: DEEPSEEK_HARNESS_PACKAGE.version
|
|
28042
|
-
}
|
|
28043
|
-
);
|
|
28044
|
-
return executable;
|
|
28045
|
-
} catch (error61) {
|
|
28046
|
-
if (options.signal.aborted) {
|
|
28047
|
-
options.signal.throwIfAborted();
|
|
28048
|
-
}
|
|
28049
|
-
if (error61 instanceof ManagedNpmPackageError) {
|
|
28050
|
-
if (error61.code === "managed_package_verification_failed") {
|
|
28051
|
-
throw new InstallationManagerError(
|
|
28052
|
-
"agent_verification_failed",
|
|
28053
|
-
"The managed DeepSeek Harness package did not match its pinned artifact",
|
|
28054
|
-
{ cause: error61 }
|
|
28055
|
-
);
|
|
28056
|
-
}
|
|
28057
|
-
if (error61.code === "managed_package_publish_failed") {
|
|
28058
|
-
throw new InstallationManagerError(
|
|
28059
|
-
"agent_publish_failed",
|
|
28060
|
-
"The managed DeepSeek Harness package could not be published",
|
|
28061
|
-
{ cause: error61 }
|
|
28062
|
-
);
|
|
28063
|
-
}
|
|
28064
|
-
throw new InstallationManagerError(error61.code, error61.message, {
|
|
28065
|
-
cause: error61
|
|
28066
|
-
});
|
|
28067
|
-
}
|
|
28068
|
-
if (error61 instanceof InstallationManagerError) {
|
|
28069
|
-
throw error61;
|
|
28070
|
-
}
|
|
28071
|
-
throw new InstallationManagerError(
|
|
28072
|
-
"agent_install_failed",
|
|
28073
|
-
"The fixed DeepSeek Harness installation recipe failed",
|
|
28074
|
-
{ cause: error61 }
|
|
28075
|
-
);
|
|
27309
|
+
const abort = () => job.controller.abort(externalSignal.reason);
|
|
27310
|
+
externalSignal.addEventListener("abort", abort, { once: true });
|
|
27311
|
+
if (externalSignal.aborted) {
|
|
27312
|
+
abort();
|
|
28076
27313
|
}
|
|
28077
|
-
|
|
28078
|
-
|
|
28079
|
-
|
|
28080
|
-
|
|
28081
|
-
|
|
28082
|
-
|
|
28083
|
-
|
|
28084
|
-
|
|
28085
|
-
|
|
28086
|
-
this.#archiveInstaller = archiveInstaller;
|
|
28087
|
-
}
|
|
28088
|
-
install = async (options) => {
|
|
28089
|
-
this.assertSupportedPlatform();
|
|
28090
|
-
const definition = openCodeManagedArchive(process.platform, process.arch);
|
|
27314
|
+
const deadline = setTimeout(() => {
|
|
27315
|
+
job.controller.abort(
|
|
27316
|
+
new InstallationManagerError(
|
|
27317
|
+
"installation_timeout",
|
|
27318
|
+
"The local Agent integration installation exceeded its deadline"
|
|
27319
|
+
)
|
|
27320
|
+
);
|
|
27321
|
+
}, INSTALLATION_DEADLINE_MILLISECONDS);
|
|
27322
|
+
const signal = job.controller.signal;
|
|
28091
27323
|
try {
|
|
28092
|
-
|
|
28093
|
-
|
|
28094
|
-
|
|
28095
|
-
|
|
28096
|
-
|
|
28097
|
-
options.stateDirectory,
|
|
28098
|
-
"agents",
|
|
28099
|
-
this.id,
|
|
28100
|
-
OPENCODE_MANAGED_VERSION
|
|
28101
|
-
),
|
|
28102
|
-
definition,
|
|
28103
|
-
options.signal
|
|
27324
|
+
signal.throwIfAborted();
|
|
27325
|
+
this.#audit.record(
|
|
27326
|
+
"agent_installation_authorized",
|
|
27327
|
+
job.requestId,
|
|
27328
|
+
specification.id
|
|
28104
27329
|
);
|
|
28105
|
-
|
|
28106
|
-
|
|
28107
|
-
|
|
28108
|
-
|
|
28109
|
-
|
|
28110
|
-
|
|
28111
|
-
|
|
28112
|
-
|
|
27330
|
+
await this.#executor.execute(
|
|
27331
|
+
specification.id,
|
|
27332
|
+
job.requestId,
|
|
27333
|
+
async (stage) => {
|
|
27334
|
+
signal.throwIfAborted();
|
|
27335
|
+
await this.#transition(
|
|
27336
|
+
job,
|
|
27337
|
+
new RunningInstallation(job.requestId, job.agentId, stage)
|
|
27338
|
+
);
|
|
27339
|
+
this.#audit.record(
|
|
27340
|
+
`agent_installation_${stage}`,
|
|
27341
|
+
job.requestId,
|
|
27342
|
+
job.agentId
|
|
27343
|
+
);
|
|
27344
|
+
},
|
|
27345
|
+
signal
|
|
27346
|
+
);
|
|
27347
|
+
signal.throwIfAborted();
|
|
27348
|
+
const succeeded = new SucceededInstallation(job.requestId, job.agentId);
|
|
27349
|
+
await this.#transition(job, succeeded);
|
|
27350
|
+
this.#audit.record(
|
|
27351
|
+
"agent_installation_completed",
|
|
27352
|
+
job.requestId,
|
|
27353
|
+
job.agentId
|
|
28113
27354
|
);
|
|
28114
|
-
|
|
27355
|
+
job.completion.resolve(succeeded);
|
|
28115
27356
|
} catch (error61) {
|
|
28116
|
-
if (
|
|
28117
|
-
|
|
28118
|
-
|
|
28119
|
-
|
|
28120
|
-
|
|
28121
|
-
|
|
28122
|
-
|
|
28123
|
-
"The managed OpenCode archive did not match its pinned artifact",
|
|
28124
|
-
{ cause: error61 }
|
|
27357
|
+
if (signal.aborted) {
|
|
27358
|
+
if (signal.reason instanceof InstallationManagerError && signal.reason.code === "installation_timeout") {
|
|
27359
|
+
const timedOut = new FailedInstallation(
|
|
27360
|
+
job.requestId,
|
|
27361
|
+
job.agentId,
|
|
27362
|
+
signal.reason.code,
|
|
27363
|
+
signal.reason.message
|
|
28125
27364
|
);
|
|
28126
|
-
|
|
28127
|
-
|
|
28128
|
-
|
|
28129
|
-
|
|
28130
|
-
|
|
28131
|
-
{ cause: error61 }
|
|
27365
|
+
await this.#transition(job, timedOut);
|
|
27366
|
+
this.#audit.record(
|
|
27367
|
+
"agent_installation_failed_installation_timeout",
|
|
27368
|
+
job.requestId,
|
|
27369
|
+
job.agentId
|
|
28132
27370
|
);
|
|
27371
|
+
job.completion.resolve(timedOut);
|
|
27372
|
+
return;
|
|
28133
27373
|
}
|
|
28134
|
-
|
|
28135
|
-
|
|
28136
|
-
|
|
27374
|
+
const cancelled = new CancelledInstallation(job.requestId, job.agentId);
|
|
27375
|
+
await this.#transition(job, cancelled);
|
|
27376
|
+
this.#audit.record(
|
|
27377
|
+
"agent_installation_cancelled",
|
|
27378
|
+
job.requestId,
|
|
27379
|
+
job.agentId
|
|
27380
|
+
);
|
|
27381
|
+
job.completion.resolve(cancelled);
|
|
27382
|
+
} else {
|
|
27383
|
+
const failure = executionFailure(error61);
|
|
27384
|
+
const failed = new FailedInstallation(
|
|
27385
|
+
job.requestId,
|
|
27386
|
+
job.agentId,
|
|
27387
|
+
failure.code,
|
|
27388
|
+
failure.message
|
|
27389
|
+
);
|
|
27390
|
+
await this.#transition(job, failed);
|
|
27391
|
+
this.#audit.record(
|
|
27392
|
+
`agent_installation_failed_${failure.code}`,
|
|
27393
|
+
job.requestId,
|
|
27394
|
+
job.agentId
|
|
27395
|
+
);
|
|
27396
|
+
job.completion.resolve(failed);
|
|
28137
27397
|
}
|
|
28138
|
-
|
|
28139
|
-
|
|
27398
|
+
} finally {
|
|
27399
|
+
clearTimeout(deadline);
|
|
27400
|
+
externalSignal.removeEventListener("abort", abort);
|
|
27401
|
+
if (this.#activeAgents.get(job.agentId) === job.requestId) {
|
|
27402
|
+
this.#activeAgents.delete(job.agentId);
|
|
28140
27403
|
}
|
|
28141
|
-
throw new InstallationManagerError(
|
|
28142
|
-
"agent_install_failed",
|
|
28143
|
-
"The fixed OpenCode installation recipe failed",
|
|
28144
|
-
{ cause: error61 }
|
|
28145
|
-
);
|
|
28146
27404
|
}
|
|
28147
27405
|
};
|
|
28148
27406
|
};
|
|
28149
|
-
function fixedAgentInstallRecipes() {
|
|
28150
|
-
return Object.freeze([
|
|
28151
|
-
new CodexInstallRecipe(),
|
|
28152
|
-
new ClaudeCodeInstallRecipe(),
|
|
28153
|
-
new PiInstallRecipe(),
|
|
28154
|
-
new DeepSeekHarnessInstallRecipe(),
|
|
28155
|
-
new OpenCodeInstallRecipe(),
|
|
28156
|
-
new GrokBuildInstallRecipe(),
|
|
28157
|
-
new WorkBuddyInstallRecipe()
|
|
28158
|
-
]);
|
|
28159
|
-
}
|
|
28160
27407
|
|
|
28161
27408
|
// src/agent-installation/fixed-installation-executor.ts
|
|
27409
|
+
import { realpathSync as realpathSync2, statSync as statSync2 } from "node:fs";
|
|
27410
|
+
import { resolve as resolve4 } from "node:path";
|
|
28162
27411
|
function findSpecification(specifications, agentId) {
|
|
28163
27412
|
for (const specification of specifications) {
|
|
28164
27413
|
if (specification.id === agentId) {
|
|
@@ -28170,17 +27419,6 @@ function findSpecification(specifications, agentId) {
|
|
|
28170
27419
|
"The requested Agent is not supported"
|
|
28171
27420
|
);
|
|
28172
27421
|
}
|
|
28173
|
-
function findRecipe(recipes, agentId) {
|
|
28174
|
-
for (const recipe of recipes) {
|
|
28175
|
-
if (recipe.id === agentId) {
|
|
28176
|
-
return recipe;
|
|
28177
|
-
}
|
|
28178
|
-
}
|
|
28179
|
-
throw new InstallationManagerError(
|
|
28180
|
-
"agent_not_installable",
|
|
28181
|
-
"The requested Agent does not have an approved installation recipe"
|
|
28182
|
-
);
|
|
28183
|
-
}
|
|
28184
27422
|
function resolveDefaultWorkspace2(path2) {
|
|
28185
27423
|
try {
|
|
28186
27424
|
const directory = realpathSync2(resolve4(path2));
|
|
@@ -28196,7 +27434,7 @@ function resolveDefaultWorkspace2(path2) {
|
|
|
28196
27434
|
);
|
|
28197
27435
|
}
|
|
28198
27436
|
}
|
|
28199
|
-
function
|
|
27437
|
+
function resolveIntegrationStateDirectory(path2) {
|
|
28200
27438
|
try {
|
|
28201
27439
|
const directory = realpathSync2(resolve4(path2));
|
|
28202
27440
|
const metadata = statSync2(directory);
|
|
@@ -28207,7 +27445,7 @@ function resolveUserInstallationDirectory(path2) {
|
|
|
28207
27445
|
} catch (error61) {
|
|
28208
27446
|
throw new InstallationManagerError(
|
|
28209
27447
|
"unsafe_installation_root",
|
|
28210
|
-
"The local
|
|
27448
|
+
"The local integration state directory is unavailable or unsafe",
|
|
28211
27449
|
{ cause: error61 }
|
|
28212
27450
|
);
|
|
28213
27451
|
}
|
|
@@ -28216,20 +27454,17 @@ function translateExecutionError(error61) {
|
|
|
28216
27454
|
if (error61 instanceof InstallationManagerError) {
|
|
28217
27455
|
return error61;
|
|
28218
27456
|
}
|
|
28219
|
-
if (error61 instanceof ManagedAdapterInstallError
|
|
27457
|
+
if (error61 instanceof ManagedAdapterInstallError) {
|
|
28220
27458
|
return new InstallationManagerError(error61.code, error61.message, {
|
|
28221
27459
|
cause: error61
|
|
28222
27460
|
});
|
|
28223
27461
|
}
|
|
28224
27462
|
return new InstallationManagerError(
|
|
28225
27463
|
"installation_failed",
|
|
28226
|
-
"The
|
|
27464
|
+
"The local Agent integration installation failed",
|
|
28227
27465
|
{ cause: error61 }
|
|
28228
27466
|
);
|
|
28229
27467
|
}
|
|
28230
|
-
function requiresAgentReplacement(code) {
|
|
28231
|
-
return code === "agent_not_found" || code === "agent_probe_failed" || code === "agent_probe_timeout";
|
|
28232
|
-
}
|
|
28233
27468
|
function requiresAdapterReplacement(code) {
|
|
28234
27469
|
return code === "adapter_not_found" || code === "adapter_probe_failed" || code === "adapter_probe_timeout" || code === "acp_incompatible";
|
|
28235
27470
|
}
|
|
@@ -28240,12 +27475,10 @@ var FixedInstallationExecutor = class {
|
|
|
28240
27475
|
#catalog;
|
|
28241
27476
|
#environment;
|
|
28242
27477
|
#publishCatalog;
|
|
28243
|
-
#recipes;
|
|
28244
27478
|
#specifications;
|
|
28245
|
-
|
|
28246
|
-
constructor(options, specifications = supportedLocalAgentSpecifications(), recipes = fixedAgentInstallRecipes(), adapterInstaller) {
|
|
27479
|
+
constructor(options, specifications = supportedLocalAgentSpecifications(), adapterInstaller) {
|
|
28247
27480
|
const defaultWorkspace = resolveDefaultWorkspace2(options.defaultWorkspace);
|
|
28248
|
-
const stateDirectory =
|
|
27481
|
+
const stateDirectory = resolveIntegrationStateDirectory(
|
|
28249
27482
|
options.stateDirectory
|
|
28250
27483
|
);
|
|
28251
27484
|
this.#defaultWorkspace = defaultWorkspace;
|
|
@@ -28253,9 +27486,7 @@ var FixedInstallationExecutor = class {
|
|
|
28253
27486
|
this.#catalog = options.catalog;
|
|
28254
27487
|
this.#environment = Object.freeze({ ...options.environment });
|
|
28255
27488
|
this.#publishCatalog = options.publishCatalog;
|
|
28256
|
-
this.#recipes = Object.freeze([...recipes]);
|
|
28257
27489
|
this.#specifications = Object.freeze([...specifications]);
|
|
28258
|
-
this.#stateDirectory = stateDirectory;
|
|
28259
27490
|
this.#adapterInstaller = adapterInstaller ?? new ManagedAdapterInstaller({
|
|
28260
27491
|
environment: this.#environment,
|
|
28261
27492
|
stateDirectory
|
|
@@ -28264,35 +27495,59 @@ var FixedInstallationExecutor = class {
|
|
|
28264
27495
|
execute = async (agentId, requestId, report, signal) => {
|
|
28265
27496
|
try {
|
|
28266
27497
|
const specification = findSpecification(this.#specifications, agentId);
|
|
28267
|
-
const
|
|
28268
|
-
this.#audit.record(
|
|
28269
|
-
"agent_installation_recipe_resolved",
|
|
28270
|
-
requestId,
|
|
28271
|
-
agentId,
|
|
28272
|
-
{
|
|
28273
|
-
adapterVersion: specification.adapterVersion,
|
|
28274
|
-
releaseChannel: recipe.releaseChannel
|
|
28275
|
-
}
|
|
28276
|
-
);
|
|
28277
|
-
const discoveryOptions2 = {
|
|
27498
|
+
const discoveryOptions = {
|
|
28278
27499
|
defaultWorkspace: this.#defaultWorkspace,
|
|
28279
27500
|
environment: this.#environment,
|
|
28280
27501
|
signal
|
|
28281
27502
|
};
|
|
28282
|
-
|
|
28283
|
-
|
|
28284
|
-
|
|
28285
|
-
|
|
28286
|
-
|
|
28287
|
-
|
|
28288
|
-
|
|
28289
|
-
|
|
28290
|
-
|
|
28291
|
-
|
|
28292
|
-
|
|
28293
|
-
|
|
27503
|
+
const initialInventory = await discoverLocalAgentInventory({
|
|
27504
|
+
...discoveryOptions,
|
|
27505
|
+
specifications: this.#specifications
|
|
27506
|
+
});
|
|
27507
|
+
const previous = this.#catalog.read();
|
|
27508
|
+
this.#catalog.transition(
|
|
27509
|
+
initialInventory.readyAgents(),
|
|
27510
|
+
initialInventory.installable
|
|
27511
|
+
);
|
|
27512
|
+
try {
|
|
27513
|
+
await this.#publishCatalog(signal);
|
|
27514
|
+
} catch (error61) {
|
|
27515
|
+
this.#catalog.transition(previous.agents, previous.installableAgents);
|
|
27516
|
+
throw error61;
|
|
27517
|
+
}
|
|
27518
|
+
const alreadyReady = initialInventory.available.find(
|
|
27519
|
+
(candidate2) => candidate2.specification.id === agentId
|
|
27520
|
+
);
|
|
27521
|
+
if (alreadyReady instanceof AvailableAgent) {
|
|
27522
|
+
return;
|
|
27523
|
+
}
|
|
27524
|
+
const candidate = initialInventory.installable.find(
|
|
27525
|
+
(agent2) => agent2.id === agentId
|
|
27526
|
+
);
|
|
27527
|
+
if (candidate instanceof MissingAgentDefinition) {
|
|
27528
|
+
throw new InstallationManagerError(
|
|
27529
|
+
"agent_not_installed",
|
|
27530
|
+
`Install ${specification.label} on this machine, then try installing the integration again.`
|
|
27531
|
+
);
|
|
27532
|
+
}
|
|
27533
|
+
if (!(candidate instanceof AgentIntegrationDefinition)) {
|
|
27534
|
+
throw new InstallationManagerError(
|
|
27535
|
+
"agent_verification_failed",
|
|
27536
|
+
"The local Agent discovery result is unavailable"
|
|
27537
|
+
);
|
|
28294
27538
|
}
|
|
28295
|
-
|
|
27539
|
+
const verifiedAgent = await findVerifiedAgentExecutable(
|
|
27540
|
+
specification,
|
|
27541
|
+
discoveryOptions
|
|
27542
|
+
);
|
|
27543
|
+
if (verifiedAgent === null) {
|
|
27544
|
+
throw new InstallationManagerError(
|
|
27545
|
+
"agent_not_installed",
|
|
27546
|
+
`Install ${specification.label} on this machine, then try installing the integration again.`
|
|
27547
|
+
);
|
|
27548
|
+
}
|
|
27549
|
+
const agent = verifiedAgent.executable;
|
|
27550
|
+
let adapter = specification instanceof DirectAcpAgentDefinition ? agent : await resolveAdapterExecutable(specification, discoveryOptions);
|
|
28296
27551
|
let installedAdapter = false;
|
|
28297
27552
|
if (adapter === null) {
|
|
28298
27553
|
if (!(specification instanceof BridgedAcpAgentDefinition)) {
|
|
@@ -28301,6 +27556,12 @@ var FixedInstallationExecutor = class {
|
|
|
28301
27556
|
"The direct Agent executable is unavailable"
|
|
28302
27557
|
);
|
|
28303
27558
|
}
|
|
27559
|
+
if (this.#environment[specification.adapterOverrideVariable] !== void 0) {
|
|
27560
|
+
throw new InstallationManagerError(
|
|
27561
|
+
"adapter_not_found",
|
|
27562
|
+
"The configured ACP adapter is unavailable"
|
|
27563
|
+
);
|
|
27564
|
+
}
|
|
28304
27565
|
await report("installing_adapter");
|
|
28305
27566
|
adapter = await this.#adapterInstaller.install(specification, signal);
|
|
28306
27567
|
installedAdapter = true;
|
|
@@ -28311,8 +27572,8 @@ var FixedInstallationExecutor = class {
|
|
|
28311
27572
|
while (true) {
|
|
28312
27573
|
await report("checking_acp");
|
|
28313
27574
|
const environment = { ...this.#environment };
|
|
28314
|
-
environment[specification.agentOverrideVariable] = agent.
|
|
28315
|
-
environment[specification.adapterOverrideVariable] = adapter.
|
|
27575
|
+
environment[specification.agentOverrideVariable] = agent.identity.requestedPath;
|
|
27576
|
+
environment[specification.adapterOverrideVariable] = adapter.identity.requestedPath;
|
|
28316
27577
|
const inventory = await discoverLocalAgentInventory({
|
|
28317
27578
|
defaultWorkspace: this.#defaultWorkspace,
|
|
28318
27579
|
environment,
|
|
@@ -28320,7 +27581,7 @@ var FixedInstallationExecutor = class {
|
|
|
28320
27581
|
specifications: this.#specifications
|
|
28321
27582
|
});
|
|
28322
27583
|
const verified = inventory.available.find(
|
|
28323
|
-
(
|
|
27584
|
+
(candidate2) => candidate2.specification.id === agentId
|
|
28324
27585
|
);
|
|
28325
27586
|
if (verified instanceof AvailableAgent) {
|
|
28326
27587
|
this.#audit.record(
|
|
@@ -28332,7 +27593,7 @@ var FixedInstallationExecutor = class {
|
|
|
28332
27593
|
agentVersion: verified.agent.agentVersion
|
|
28333
27594
|
}
|
|
28334
27595
|
);
|
|
28335
|
-
const
|
|
27596
|
+
const previousCatalog = this.#catalog.read();
|
|
28336
27597
|
this.#catalog.transition(
|
|
28337
27598
|
inventory.readyAgents(),
|
|
28338
27599
|
inventory.installable
|
|
@@ -28341,15 +27602,15 @@ var FixedInstallationExecutor = class {
|
|
|
28341
27602
|
await this.#publishCatalog(signal);
|
|
28342
27603
|
} catch (error61) {
|
|
28343
27604
|
this.#catalog.transition(
|
|
28344
|
-
|
|
28345
|
-
|
|
27605
|
+
previousCatalog.agents,
|
|
27606
|
+
previousCatalog.installableAgents
|
|
28346
27607
|
);
|
|
28347
27608
|
throw error61;
|
|
28348
27609
|
}
|
|
28349
27610
|
return;
|
|
28350
27611
|
}
|
|
28351
27612
|
const unavailable = inventory.unavailable.find(
|
|
28352
|
-
(
|
|
27613
|
+
(candidate2) => candidate2.specification.id === agentId
|
|
28353
27614
|
);
|
|
28354
27615
|
if (unavailable === void 0) {
|
|
28355
27616
|
throw new InstallationManagerError(
|
|
@@ -28357,7 +27618,7 @@ var FixedInstallationExecutor = class {
|
|
|
28357
27618
|
"The complete Agent ACP path did not pass verification"
|
|
28358
27619
|
);
|
|
28359
27620
|
}
|
|
28360
|
-
if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && requiresAdapterReplacement(unavailable.code)) {
|
|
27621
|
+
if (!installedAdapter && specification instanceof BridgedAcpAgentDefinition && this.#environment[specification.adapterOverrideVariable] === void 0 && requiresAdapterReplacement(unavailable.code)) {
|
|
28361
27622
|
await report("installing_adapter");
|
|
28362
27623
|
adapter = await this.#adapterInstaller.install(specification, signal);
|
|
28363
27624
|
installedAdapter = true;
|
|
@@ -28366,21 +27627,6 @@ var FixedInstallationExecutor = class {
|
|
|
28366
27627
|
});
|
|
28367
27628
|
continue;
|
|
28368
27629
|
}
|
|
28369
|
-
if (!installedAgent && (requiresAgentReplacement(unavailable.code) || unavailable.code === "acp_incompatible")) {
|
|
28370
|
-
agent = await recipe.install({
|
|
28371
|
-
audit: this.#audit,
|
|
28372
|
-
environment: this.#environment,
|
|
28373
|
-
report,
|
|
28374
|
-
requestId,
|
|
28375
|
-
signal,
|
|
28376
|
-
stateDirectory: this.#stateDirectory
|
|
28377
|
-
});
|
|
28378
|
-
installedAgent = true;
|
|
28379
|
-
if (specification instanceof DirectAcpAgentDefinition) {
|
|
28380
|
-
adapter = agent;
|
|
28381
|
-
}
|
|
28382
|
-
continue;
|
|
28383
|
-
}
|
|
28384
27630
|
throw new InstallationManagerError(
|
|
28385
27631
|
unavailable.code,
|
|
28386
27632
|
unavailable.message
|
|
@@ -28405,15 +27651,15 @@ var LocalAuthorizationError = class extends Error {
|
|
|
28405
27651
|
};
|
|
28406
27652
|
|
|
28407
27653
|
// src/authorization/workspace-directory.ts
|
|
28408
|
-
import { readdir, realpath as
|
|
27654
|
+
import { readdir, realpath as realpath7, stat as stat6 } from "node:fs/promises";
|
|
28409
27655
|
import { homedir as homedir2 } from "node:os";
|
|
28410
27656
|
import {
|
|
28411
27657
|
basename as basename2,
|
|
28412
|
-
dirname as
|
|
28413
|
-
isAbsolute as
|
|
28414
|
-
join as
|
|
27658
|
+
dirname as dirname5,
|
|
27659
|
+
isAbsolute as isAbsolute7,
|
|
27660
|
+
join as join15,
|
|
28415
27661
|
normalize as normalize2,
|
|
28416
|
-
relative as
|
|
27662
|
+
relative as relative4
|
|
28417
27663
|
} from "node:path";
|
|
28418
27664
|
var WorkspaceDirectoryListing = class {
|
|
28419
27665
|
directoryId;
|
|
@@ -28463,20 +27709,20 @@ var WorkspaceDirectoryService = class {
|
|
|
28463
27709
|
if (id === "home") return homedir2();
|
|
28464
27710
|
if (id.startsWith("path-")) {
|
|
28465
27711
|
const path2 = decodePath(id, "path-");
|
|
28466
|
-
if (
|
|
27712
|
+
if (isAbsolute7(path2)) return path2;
|
|
28467
27713
|
}
|
|
28468
27714
|
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28469
27715
|
};
|
|
28470
27716
|
resolvePath = async (requested, signal) => {
|
|
28471
27717
|
signal.throwIfAborted();
|
|
28472
|
-
if (!
|
|
27718
|
+
if (!isAbsolute7(requested) || requested.includes("\0") || normalize2(requested) !== requested)
|
|
28473
27719
|
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
28474
27720
|
try {
|
|
28475
|
-
const target = await
|
|
27721
|
+
const target = await realpath7(requested);
|
|
28476
27722
|
signal.throwIfAborted();
|
|
28477
|
-
const metadata = await
|
|
27723
|
+
const metadata = await stat6(target);
|
|
28478
27724
|
signal.throwIfAborted();
|
|
28479
|
-
if (!
|
|
27725
|
+
if (!isAbsolute7(target) || normalize2(target) !== target || !metadata.isDirectory())
|
|
28480
27726
|
throw new LocalAuthorizationError(
|
|
28481
27727
|
"The selected location is not a directory"
|
|
28482
27728
|
);
|
|
@@ -28491,8 +27737,8 @@ var WorkspaceDirectoryService = class {
|
|
|
28491
27737
|
}
|
|
28492
27738
|
};
|
|
28493
27739
|
label = (path2) => {
|
|
28494
|
-
const suffix =
|
|
28495
|
-
return suffix === "" ? "~" : !
|
|
27740
|
+
const suffix = relative4(homedir2(), path2);
|
|
27741
|
+
return suffix === "" ? "~" : !isAbsolute7(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
28496
27742
|
};
|
|
28497
27743
|
identify = async (bindingId, requestedPath, signal) => {
|
|
28498
27744
|
this.authorizeMachine(bindingId);
|
|
@@ -28520,7 +27766,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28520
27766
|
continue;
|
|
28521
27767
|
}
|
|
28522
27768
|
try {
|
|
28523
|
-
const path2 = await this.resolvePath(
|
|
27769
|
+
const path2 = await this.resolvePath(join15(target, child.name), signal);
|
|
28524
27770
|
entries.push({ directoryId: encodePath(path2), name: child.name });
|
|
28525
27771
|
} catch (cause) {
|
|
28526
27772
|
signal.throwIfAborted();
|
|
@@ -28528,7 +27774,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28528
27774
|
}
|
|
28529
27775
|
}
|
|
28530
27776
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
28531
|
-
const parent =
|
|
27777
|
+
const parent = dirname5(target);
|
|
28532
27778
|
return new WorkspaceDirectoryListing(
|
|
28533
27779
|
id,
|
|
28534
27780
|
this.label(target),
|
|
@@ -28552,7 +27798,7 @@ var WorkspaceDirectoryService = class {
|
|
|
28552
27798
|
};
|
|
28553
27799
|
|
|
28554
27800
|
// src/native-sessions/service.ts
|
|
28555
|
-
import { randomUUID as
|
|
27801
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
28556
27802
|
|
|
28557
27803
|
// src/native-sessions/codex-history.ts
|
|
28558
27804
|
import { spawn as spawn4 } from "node:child_process";
|
|
@@ -28866,7 +28112,7 @@ var NativeSessionService = class {
|
|
|
28866
28112
|
for (const info of page.sessions) {
|
|
28867
28113
|
const authorized = await this.authorizeEntry(command, options, info);
|
|
28868
28114
|
if (authorized === null) continue;
|
|
28869
|
-
const entryId =
|
|
28115
|
+
const entryId = randomUUID2();
|
|
28870
28116
|
if (this.#entries.size >= 5e3) this.#entries.clear();
|
|
28871
28117
|
this.#entries.set(entryId, {
|
|
28872
28118
|
scope: entryScope,
|
|
@@ -28891,7 +28137,7 @@ var NativeSessionService = class {
|
|
|
28891
28137
|
{},
|
|
28892
28138
|
"invalid_native_session_response"
|
|
28893
28139
|
);
|
|
28894
|
-
nextCursor =
|
|
28140
|
+
nextCursor = randomUUID2();
|
|
28895
28141
|
if (this.#cursors.size >= 500) this.#cursors.clear();
|
|
28896
28142
|
this.#cursors.set(nextCursor, {
|
|
28897
28143
|
scope: cursorScope,
|
|
@@ -29211,7 +28457,7 @@ function connectRelay(url2, signal) {
|
|
|
29211
28457
|
}
|
|
29212
28458
|
|
|
29213
28459
|
// src/relay-connection/liveness.ts
|
|
29214
|
-
import { randomUUID as
|
|
28460
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
29215
28461
|
var HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 1e4;
|
|
29216
28462
|
var HEARTBEAT_INTERVAL_MILLISECONDS = 2e4;
|
|
29217
28463
|
var RelayLivenessState = class {
|
|
@@ -29302,7 +28548,7 @@ var RelayConnectionLiveness = class {
|
|
|
29302
28548
|
}
|
|
29303
28549
|
throw new Error("Heartbeat was scheduled in an invalid state");
|
|
29304
28550
|
}
|
|
29305
|
-
const heartbeatId =
|
|
28551
|
+
const heartbeatId = randomUUID3();
|
|
29306
28552
|
this.#state = new AwaitingHeartbeatAckState(
|
|
29307
28553
|
heartbeatId,
|
|
29308
28554
|
this.#timer.schedule(
|
|
@@ -29321,7 +28567,7 @@ var RelayConnectionLiveness = class {
|
|
|
29321
28567
|
|
|
29322
28568
|
// src/relay-connection/session-event-outbox.ts
|
|
29323
28569
|
import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
29324
|
-
import { dirname as
|
|
28570
|
+
import { dirname as dirname6 } from "node:path";
|
|
29325
28571
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
29326
28572
|
function readPendingEnvelope(row) {
|
|
29327
28573
|
if (typeof row !== "object" || row === null || Array.isArray(row)) {
|
|
@@ -29336,7 +28582,7 @@ function readPendingEnvelope(row) {
|
|
|
29336
28582
|
var SessionEventOutbox = class {
|
|
29337
28583
|
#database;
|
|
29338
28584
|
constructor(path2) {
|
|
29339
|
-
mkdirSync3(
|
|
28585
|
+
mkdirSync3(dirname6(path2), { recursive: true });
|
|
29340
28586
|
this.#database = new DatabaseSync3(path2);
|
|
29341
28587
|
this.#database.exec(`
|
|
29342
28588
|
CREATE TABLE IF NOT EXISTS relay_session_event_outbox (
|
|
@@ -29490,6 +28736,7 @@ var systemDaemonTimer = new SystemDaemonTimer();
|
|
|
29490
28736
|
// src/run-daemon.ts
|
|
29491
28737
|
var RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
|
|
29492
28738
|
var RELAY_CONNECTION_REFRESH_MILLISECONDS = 20 * 60 * 1e3;
|
|
28739
|
+
var ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS = 2e4;
|
|
29493
28740
|
var RelayConnectionRefreshState = class {
|
|
29494
28741
|
};
|
|
29495
28742
|
var ScheduledRelayConnectionRefreshState = class extends RelayConnectionRefreshState {
|
|
@@ -29687,7 +28934,7 @@ var DaemonInstallationObserver = class {
|
|
|
29687
28934
|
);
|
|
29688
28935
|
return Promise.resolve();
|
|
29689
28936
|
}
|
|
29690
|
-
throw new Error("Unsupported Agent installation state");
|
|
28937
|
+
throw new Error("Unsupported Agent integration installation state");
|
|
29691
28938
|
};
|
|
29692
28939
|
};
|
|
29693
28940
|
var ResolvedSessionDirectories = class {
|
|
@@ -29701,16 +28948,20 @@ var ResolvedSessionDirectories = class {
|
|
|
29701
28948
|
}
|
|
29702
28949
|
};
|
|
29703
28950
|
var ActiveDaemonTurn = class {
|
|
28951
|
+
attemptId;
|
|
29704
28952
|
command;
|
|
29705
|
-
#
|
|
28953
|
+
#controller;
|
|
28954
|
+
#finished = Promise.withResolvers();
|
|
29706
28955
|
#cancellationRequested = false;
|
|
29707
|
-
constructor(command,
|
|
28956
|
+
constructor(command, attemptId) {
|
|
28957
|
+
this.attemptId = attemptId;
|
|
29708
28958
|
this.command = command;
|
|
29709
|
-
this.#
|
|
28959
|
+
this.#controller = new AbortController();
|
|
29710
28960
|
}
|
|
29711
|
-
|
|
29712
|
-
this.#
|
|
28961
|
+
abortDaemon = () => {
|
|
28962
|
+
this.#controller.abort();
|
|
29713
28963
|
};
|
|
28964
|
+
finish = () => this.#finished.resolve();
|
|
29714
28965
|
matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
|
|
29715
28966
|
requestCancellation = () => {
|
|
29716
28967
|
if (this.#cancellationRequested) {
|
|
@@ -29720,25 +28971,118 @@ var ActiveDaemonTurn = class {
|
|
|
29720
28971
|
return true;
|
|
29721
28972
|
};
|
|
29722
28973
|
get signal() {
|
|
29723
|
-
return this.#
|
|
28974
|
+
return this.#controller.signal;
|
|
28975
|
+
}
|
|
28976
|
+
get completion() {
|
|
28977
|
+
return this.#finished.promise;
|
|
28978
|
+
}
|
|
28979
|
+
};
|
|
28980
|
+
var ActiveTurnReconciliationError = class extends Error {
|
|
28981
|
+
code = "active_turn_reconciliation_failed";
|
|
28982
|
+
constructor(message, options = {}) {
|
|
28983
|
+
super(message, options);
|
|
28984
|
+
this.name = "ActiveTurnReconciliationError";
|
|
29724
28985
|
}
|
|
29725
28986
|
};
|
|
28987
|
+
function activeTurnReconciliationEndpoint(config2, turn) {
|
|
28988
|
+
const endpoint = new URL(config2.relayUrl);
|
|
28989
|
+
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
28990
|
+
if (!endpoint.pathname.endsWith("/daemon")) {
|
|
28991
|
+
throw new ActiveTurnReconciliationError("The Relay URL is invalid");
|
|
28992
|
+
}
|
|
28993
|
+
endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
|
|
28994
|
+
endpoint.searchParams.delete("liveness");
|
|
28995
|
+
return endpoint;
|
|
28996
|
+
}
|
|
28997
|
+
async function reconcileActiveTurn(config2, turn, signal) {
|
|
28998
|
+
signal.throwIfAborted();
|
|
28999
|
+
const timeoutSignal = AbortSignal.timeout(
|
|
29000
|
+
ACTIVE_TURN_RECONCILIATION_TIMEOUT_MILLISECONDS
|
|
29001
|
+
);
|
|
29002
|
+
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
29003
|
+
let response;
|
|
29004
|
+
try {
|
|
29005
|
+
response = await fetch4(activeTurnReconciliationEndpoint(config2, turn), {
|
|
29006
|
+
body: JSON.stringify({ outcome: { kind: "running" } }),
|
|
29007
|
+
dispatcher: environmentProxyDispatcher,
|
|
29008
|
+
headers: { "content-type": "application/json" },
|
|
29009
|
+
method: "POST",
|
|
29010
|
+
signal: requestSignal
|
|
29011
|
+
});
|
|
29012
|
+
} catch (error61) {
|
|
29013
|
+
if (signal.aborted) {
|
|
29014
|
+
signal.throwIfAborted();
|
|
29015
|
+
}
|
|
29016
|
+
throw new ActiveTurnReconciliationError(
|
|
29017
|
+
timeoutSignal.aborted ? "The active Agent turn reconciliation timed out" : "The active Agent turn could not be reconciled",
|
|
29018
|
+
{ cause: error61 }
|
|
29019
|
+
);
|
|
29020
|
+
}
|
|
29021
|
+
await response.body?.cancel();
|
|
29022
|
+
if (!response.ok) {
|
|
29023
|
+
throw new ActiveTurnReconciliationError(
|
|
29024
|
+
"The Relay rejected the active Agent turn reconciliation"
|
|
29025
|
+
);
|
|
29026
|
+
}
|
|
29027
|
+
}
|
|
29028
|
+
async function reconcileActiveTurns(config2, turns, signal) {
|
|
29029
|
+
await Promise.all(
|
|
29030
|
+
turns.map(async (turn) => await reconcileActiveTurn(config2, turn, signal))
|
|
29031
|
+
);
|
|
29032
|
+
}
|
|
29726
29033
|
function send(socket, message) {
|
|
29727
29034
|
if (socket.readyState !== WebSocket2.OPEN) {
|
|
29728
29035
|
throw new Error("Relay connection is not open");
|
|
29729
29036
|
}
|
|
29730
29037
|
socket.send(message);
|
|
29731
29038
|
}
|
|
29732
|
-
|
|
29733
|
-
|
|
29734
|
-
|
|
29735
|
-
|
|
29039
|
+
var DaemonSessionEventConnectionState = class {
|
|
29040
|
+
};
|
|
29041
|
+
var DisconnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
|
|
29042
|
+
disconnect = () => this;
|
|
29043
|
+
send = () => void 0;
|
|
29044
|
+
};
|
|
29045
|
+
var ConnectedDaemonSessionEventState = class extends DaemonSessionEventConnectionState {
|
|
29046
|
+
#socket;
|
|
29047
|
+
constructor(socket) {
|
|
29048
|
+
super();
|
|
29049
|
+
this.#socket = socket;
|
|
29736
29050
|
}
|
|
29737
|
-
|
|
29738
|
-
|
|
29739
|
-
|
|
29740
|
-
|
|
29741
|
-
|
|
29051
|
+
disconnect = (socket) => socket === this.#socket ? new DisconnectedDaemonSessionEventState() : this;
|
|
29052
|
+
send = (message) => {
|
|
29053
|
+
if (this.#socket.readyState === WebSocket2.OPEN) {
|
|
29054
|
+
try {
|
|
29055
|
+
this.#socket.send(message);
|
|
29056
|
+
} catch {
|
|
29057
|
+
}
|
|
29058
|
+
}
|
|
29059
|
+
};
|
|
29060
|
+
};
|
|
29061
|
+
var DaemonSessionEventPublisher = class {
|
|
29062
|
+
#outbox;
|
|
29063
|
+
#connection = new DisconnectedDaemonSessionEventState();
|
|
29064
|
+
constructor(outbox) {
|
|
29065
|
+
this.#outbox = outbox;
|
|
29066
|
+
}
|
|
29067
|
+
connect = (socket) => {
|
|
29068
|
+
const connection = new ConnectedDaemonSessionEventState(socket);
|
|
29069
|
+
this.#connection = connection;
|
|
29070
|
+
for (const pending of this.#outbox.pending()) {
|
|
29071
|
+
connection.send(pending);
|
|
29072
|
+
}
|
|
29073
|
+
};
|
|
29074
|
+
disconnect = (socket) => {
|
|
29075
|
+
this.#connection = this.#connection.disconnect(socket);
|
|
29076
|
+
};
|
|
29077
|
+
recordAttempt = (sessionId, payload, attemptId) => {
|
|
29078
|
+
this.#connection.send(this.#outbox.enqueue(sessionId, payload, attemptId));
|
|
29079
|
+
};
|
|
29080
|
+
recordRuntime = (sessionId, payload) => {
|
|
29081
|
+
this.#connection.send(this.#outbox.enqueue(sessionId, payload));
|
|
29082
|
+
};
|
|
29083
|
+
};
|
|
29084
|
+
function reportFailure(publisher, command, code, message, attemptId) {
|
|
29085
|
+
publisher.recordAttempt(
|
|
29742
29086
|
command.sessionId,
|
|
29743
29087
|
encodeSessionFailedEvent({
|
|
29744
29088
|
code,
|
|
@@ -29834,7 +29178,7 @@ async function executeWorkspaceList(socket, command, directories, audit, signal)
|
|
|
29834
29178
|
reportOperationFailure(socket, command.requestId, "", error61);
|
|
29835
29179
|
}
|
|
29836
29180
|
}
|
|
29837
|
-
async function executeSessionPrepare(
|
|
29181
|
+
async function executeSessionPrepare(publisher, socket, command, config2, directories, audit, sessions, signal) {
|
|
29838
29182
|
try {
|
|
29839
29183
|
const resolved = await resolveSessionDirectories(
|
|
29840
29184
|
directories,
|
|
@@ -29861,9 +29205,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
|
|
|
29861
29205
|
event: "session_prepared",
|
|
29862
29206
|
sessionId: command.sessionId
|
|
29863
29207
|
});
|
|
29864
|
-
|
|
29865
|
-
outbox,
|
|
29866
|
-
socket,
|
|
29208
|
+
publisher.recordRuntime(
|
|
29867
29209
|
command.sessionId,
|
|
29868
29210
|
encodeSessionReadyEvent({
|
|
29869
29211
|
additionalDirectories: resolved.additionalDirectoryEntries,
|
|
@@ -29894,7 +29236,7 @@ async function executeSessionPrepare(outbox, socket, command, config2, directori
|
|
|
29894
29236
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
29895
29237
|
}
|
|
29896
29238
|
}
|
|
29897
|
-
async function executeSessionConfigure(
|
|
29239
|
+
async function executeSessionConfigure(publisher, socket, command, config2, directories, audit, sessions, signal) {
|
|
29898
29240
|
try {
|
|
29899
29241
|
const resolved = await resolveSessionDirectories(
|
|
29900
29242
|
directories,
|
|
@@ -29920,9 +29262,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
|
|
|
29920
29262
|
event: "session_configured",
|
|
29921
29263
|
sessionId: command.sessionId
|
|
29922
29264
|
});
|
|
29923
|
-
|
|
29924
|
-
outbox,
|
|
29925
|
-
socket,
|
|
29265
|
+
publisher.recordRuntime(
|
|
29926
29266
|
command.sessionId,
|
|
29927
29267
|
encodeSessionConfigUpdatedEvent({
|
|
29928
29268
|
configOptions,
|
|
@@ -29935,7 +29275,7 @@ async function executeSessionConfigure(outbox, socket, command, config2, directo
|
|
|
29935
29275
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
29936
29276
|
}
|
|
29937
29277
|
}
|
|
29938
|
-
async function executePrompt(outbox,
|
|
29278
|
+
async function executePrompt(outbox, publisher, command, config2, directories, audit, sessions, attemptId, signal) {
|
|
29939
29279
|
try {
|
|
29940
29280
|
const resolved = await resolveSessionDirectories(
|
|
29941
29281
|
directories,
|
|
@@ -29951,9 +29291,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29951
29291
|
sessionId: command.sessionId
|
|
29952
29292
|
});
|
|
29953
29293
|
outbox.transitionExecution(command.commandId, "running");
|
|
29954
|
-
|
|
29955
|
-
outbox,
|
|
29956
|
-
socket,
|
|
29294
|
+
publisher.recordAttempt(
|
|
29957
29295
|
command.sessionId,
|
|
29958
29296
|
encodeSessionStartedEvent({
|
|
29959
29297
|
commandId: command.commandId,
|
|
@@ -29970,9 +29308,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29970
29308
|
cwd: resolved.cwd,
|
|
29971
29309
|
images: command.images,
|
|
29972
29310
|
onActivity: (activity) => {
|
|
29973
|
-
|
|
29974
|
-
outbox,
|
|
29975
|
-
socket,
|
|
29311
|
+
publisher.recordAttempt(
|
|
29976
29312
|
command.sessionId,
|
|
29977
29313
|
encodeAgentActivityEvent({
|
|
29978
29314
|
activityId: activity.activityId,
|
|
@@ -29996,9 +29332,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
29996
29332
|
return Promise.resolve();
|
|
29997
29333
|
},
|
|
29998
29334
|
onText: (text) => {
|
|
29999
|
-
|
|
30000
|
-
outbox,
|
|
30001
|
-
socket,
|
|
29335
|
+
publisher.recordAttempt(
|
|
30002
29336
|
command.sessionId,
|
|
30003
29337
|
encodeAgentMessageDeltaEvent({
|
|
30004
29338
|
commandId: command.commandId,
|
|
@@ -30015,9 +29349,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
30015
29349
|
sessionId: command.sessionId,
|
|
30016
29350
|
signal
|
|
30017
29351
|
});
|
|
30018
|
-
|
|
30019
|
-
outbox,
|
|
30020
|
-
socket,
|
|
29352
|
+
publisher.recordAttempt(
|
|
30021
29353
|
command.sessionId,
|
|
30022
29354
|
encodeSessionCompletedEvent({
|
|
30023
29355
|
commandId: command.commandId,
|
|
@@ -30044,8 +29376,7 @@ async function executePrompt(outbox, socket, command, config2, directories, audi
|
|
|
30044
29376
|
});
|
|
30045
29377
|
const code = operationErrorCode(error61);
|
|
30046
29378
|
reportFailure(
|
|
30047
|
-
|
|
30048
|
-
socket,
|
|
29379
|
+
publisher,
|
|
30049
29380
|
command,
|
|
30050
29381
|
code === "session_operation_failed" ? "agent_execution_failed" : code,
|
|
30051
29382
|
code === "session_operation_failed" ? "The local agent could not complete the request" : operationErrorMessage(error61),
|
|
@@ -30091,29 +29422,15 @@ async function publishAgentCatalogUntilAvailable(config2, signal, timer) {
|
|
|
30091
29422
|
}
|
|
30092
29423
|
}
|
|
30093
29424
|
}
|
|
30094
|
-
async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, onConnected, signal, timer) {
|
|
29425
|
+
async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, publisher, activeTurns, activeAttemptIds, onConnected, signal, timer) {
|
|
30095
29426
|
const relayUrl = new URL(config2.relayUrl);
|
|
30096
29427
|
relayUrl.searchParams.set("liveness", "1");
|
|
30097
29428
|
const socket = await connectRelay(relayUrl, signal);
|
|
29429
|
+
const reconnectingTurns = [...activeTurns.values()];
|
|
30098
29430
|
onConnected();
|
|
30099
|
-
const activeTurns = /* @__PURE__ */ new Map();
|
|
30100
|
-
const activeAttemptIds = /* @__PURE__ */ new Map();
|
|
30101
29431
|
const connectionController = new AbortController();
|
|
30102
29432
|
const nativeRequests = /* @__PURE__ */ new Map();
|
|
30103
|
-
const record2 = (sessionId, payload) => {
|
|
30104
|
-
recordSessionEvent(
|
|
30105
|
-
outbox,
|
|
30106
|
-
socket,
|
|
30107
|
-
sessionId,
|
|
30108
|
-
payload,
|
|
30109
|
-
activeAttemptIds.get(sessionId) ?? null
|
|
30110
|
-
);
|
|
30111
|
-
};
|
|
30112
|
-
sessions.setObserver(new DaemonAcpObserver(record2));
|
|
30113
29433
|
installationObserver.connect(socket);
|
|
30114
|
-
for (const pending of outbox.pending()) {
|
|
30115
|
-
send(socket, pending);
|
|
30116
|
-
}
|
|
30117
29434
|
try {
|
|
30118
29435
|
await new Promise((resolve5, reject) => {
|
|
30119
29436
|
let finished = false;
|
|
@@ -30125,11 +29442,8 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30125
29442
|
socket.removeEventListener("error", handleError);
|
|
30126
29443
|
socket.removeEventListener("message", handleMessage);
|
|
30127
29444
|
installationObserver.disconnect(socket);
|
|
29445
|
+
publisher.disconnect(socket);
|
|
30128
29446
|
connectionController.abort();
|
|
30129
|
-
for (const turn of activeTurns.values()) {
|
|
30130
|
-
turn.abortConnection();
|
|
30131
|
-
}
|
|
30132
|
-
activeTurns.clear();
|
|
30133
29447
|
};
|
|
30134
29448
|
const resolveConnection = () => {
|
|
30135
29449
|
if (finished) {
|
|
@@ -30348,7 +29662,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30348
29662
|
if (kind === SESSION_PREPARE_KIND) {
|
|
30349
29663
|
const command2 = decodeSessionPrepareCommand(encoded);
|
|
30350
29664
|
void executeSessionPrepare(
|
|
30351
|
-
|
|
29665
|
+
publisher,
|
|
30352
29666
|
socket,
|
|
30353
29667
|
command2,
|
|
30354
29668
|
config2,
|
|
@@ -30362,7 +29676,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30362
29676
|
if (kind === SESSION_CONFIGURE_KIND) {
|
|
30363
29677
|
const command2 = decodeSessionConfigureCommand(encoded);
|
|
30364
29678
|
void executeSessionConfigure(
|
|
30365
|
-
|
|
29679
|
+
publisher,
|
|
30366
29680
|
socket,
|
|
30367
29681
|
command2,
|
|
30368
29682
|
config2,
|
|
@@ -30412,7 +29726,10 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30412
29726
|
if (kind === AGENT_INSTALL_REQUEST_KIND) {
|
|
30413
29727
|
const command2 = decodeAgentInstallRequestCommand(encoded);
|
|
30414
29728
|
void installations.request(command2, signal).catch((error61) => {
|
|
30415
|
-
console.error(
|
|
29729
|
+
console.error(
|
|
29730
|
+
"Mobius Agent integration installation failed",
|
|
29731
|
+
error61
|
|
29732
|
+
);
|
|
30416
29733
|
});
|
|
30417
29734
|
return;
|
|
30418
29735
|
}
|
|
@@ -30438,12 +29755,12 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30438
29755
|
if (receipt.kind === "duplicate") {
|
|
30439
29756
|
return;
|
|
30440
29757
|
}
|
|
30441
|
-
const turn = new ActiveDaemonTurn(command,
|
|
29758
|
+
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
30442
29759
|
activeTurns.set(command.commandId, turn);
|
|
30443
29760
|
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
30444
29761
|
void executePrompt(
|
|
30445
29762
|
outbox,
|
|
30446
|
-
|
|
29763
|
+
publisher,
|
|
30447
29764
|
command,
|
|
30448
29765
|
config2,
|
|
30449
29766
|
directories,
|
|
@@ -30458,6 +29775,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30458
29775
|
if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
|
|
30459
29776
|
activeAttemptIds.delete(command.sessionId);
|
|
30460
29777
|
}
|
|
29778
|
+
turn.finish();
|
|
30461
29779
|
connectionRefresh.afterTurnFinished();
|
|
30462
29780
|
});
|
|
30463
29781
|
} catch (error61) {
|
|
@@ -30469,6 +29787,28 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30469
29787
|
socket.addEventListener("close", handleClose);
|
|
30470
29788
|
socket.addEventListener("error", handleError);
|
|
30471
29789
|
socket.addEventListener("message", handleMessage);
|
|
29790
|
+
void reconcileActiveTurns(
|
|
29791
|
+
config2,
|
|
29792
|
+
reconnectingTurns,
|
|
29793
|
+
connectionController.signal
|
|
29794
|
+
).then(
|
|
29795
|
+
() => {
|
|
29796
|
+
if (finished) {
|
|
29797
|
+
return;
|
|
29798
|
+
}
|
|
29799
|
+
publisher.connect(socket);
|
|
29800
|
+
void Promise.all(
|
|
29801
|
+
reconnectingTurns.map((turn) => turn.completion)
|
|
29802
|
+
).then(connectionRefresh.afterTurnFinished);
|
|
29803
|
+
},
|
|
29804
|
+
() => {
|
|
29805
|
+
if (finished) {
|
|
29806
|
+
return;
|
|
29807
|
+
}
|
|
29808
|
+
socket.close(1011, "Active Agent turn reconciliation failed");
|
|
29809
|
+
rejectConnection();
|
|
29810
|
+
}
|
|
29811
|
+
);
|
|
30472
29812
|
if (signal.aborted) {
|
|
30473
29813
|
stop();
|
|
30474
29814
|
}
|
|
@@ -30492,23 +29832,21 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
30492
29832
|
publishCatalog: async (installationSignal) => await publishAgentCatalog(config2, installationSignal),
|
|
30493
29833
|
stateDirectory
|
|
30494
29834
|
});
|
|
30495
|
-
await new AutomaticAdapterProvisioner(
|
|
30496
|
-
{
|
|
30497
|
-
defaultWorkspace: config2.defaultWorkspace,
|
|
30498
|
-
audit: installationAudit,
|
|
30499
|
-
catalog: config2.catalog,
|
|
30500
|
-
environment: process.env
|
|
30501
|
-
},
|
|
30502
|
-
new ManagedAdapterInstaller({
|
|
30503
|
-
environment: process.env,
|
|
30504
|
-
stateDirectory
|
|
30505
|
-
}),
|
|
30506
|
-
specifications
|
|
30507
|
-
).prepare(signal);
|
|
30508
29835
|
const sessionStore = new SqliteAcpSessionStore(config2.auditDatabasePath);
|
|
30509
29836
|
const outbox = new SessionEventOutbox(config2.auditDatabasePath);
|
|
29837
|
+
const publisher = new DaemonSessionEventPublisher(outbox);
|
|
29838
|
+
const activeTurns = /* @__PURE__ */ new Map();
|
|
29839
|
+
const activeAttemptIds = /* @__PURE__ */ new Map();
|
|
29840
|
+
const recordSessionEvent = (sessionId, payload) => {
|
|
29841
|
+
const attemptId = activeAttemptIds.get(sessionId);
|
|
29842
|
+
if (attemptId === void 0) {
|
|
29843
|
+
publisher.recordRuntime(sessionId, payload);
|
|
29844
|
+
return;
|
|
29845
|
+
}
|
|
29846
|
+
publisher.recordAttempt(sessionId, payload, attemptId);
|
|
29847
|
+
};
|
|
30510
29848
|
const sessions = new AcpSessionManager(
|
|
30511
|
-
new
|
|
29849
|
+
new DaemonAcpObserver(recordSessionEvent),
|
|
30512
29850
|
sessionStore
|
|
30513
29851
|
);
|
|
30514
29852
|
const directories = new WorkspaceDirectoryService(
|
|
@@ -30564,6 +29902,9 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
30564
29902
|
installationObserver,
|
|
30565
29903
|
nativeSessions,
|
|
30566
29904
|
outbox,
|
|
29905
|
+
publisher,
|
|
29906
|
+
activeTurns,
|
|
29907
|
+
activeAttemptIds,
|
|
30567
29908
|
announceConnection,
|
|
30568
29909
|
signal,
|
|
30569
29910
|
timer
|
|
@@ -30581,6 +29922,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
30581
29922
|
await waitForRelayRetry(signal, timer);
|
|
30582
29923
|
}
|
|
30583
29924
|
} finally {
|
|
29925
|
+
const turns = [...activeTurns.values()];
|
|
29926
|
+
for (const turn of turns) {
|
|
29927
|
+
turn.abortDaemon();
|
|
29928
|
+
}
|
|
29929
|
+
await Promise.all(turns.map((turn) => turn.completion));
|
|
30584
29930
|
try {
|
|
30585
29931
|
await catalogPublication;
|
|
30586
29932
|
} finally {
|
|
@@ -30615,7 +29961,7 @@ Usage:
|
|
|
30615
29961
|
Commands:
|
|
30616
29962
|
pair Pair this machine and start its local daemon
|
|
30617
29963
|
start Start the local daemon for a saved channel
|
|
30618
|
-
agents Show
|
|
29964
|
+
agents Show detected, missing, and integration-ready Agents
|
|
30619
29965
|
|
|
30620
29966
|
Pairing grants this browser access to the machine with your user account's permissions.
|
|
30621
29967
|
New conversations default to ~/.mobius/workspace; choose other directories in the browser.
|
|
@@ -30631,7 +29977,7 @@ async function main() {
|
|
|
30631
29977
|
if (arguments_.length > 1 || arguments_.length === 1 && arguments_[0] !== "--json") {
|
|
30632
29978
|
throw new Error("Usage: mobius agents [--json]");
|
|
30633
29979
|
}
|
|
30634
|
-
await
|
|
29980
|
+
await mkdir4(loadDefaultWorkspace(), { recursive: true, mode: 448 });
|
|
30635
29981
|
const inventory = await discoverLocalAgentInventory({
|
|
30636
29982
|
defaultWorkspace: loadDefaultWorkspace(),
|
|
30637
29983
|
environment: process.env,
|